Как найти правильный тип возвращаемого значения для syn::parse?
У меня есть TokenStream
это происходит из определения функции Rust. Я хочу разобрать это с syn::parse
(а также .unrwap()
). Однако я не знаю, каким должен быть тип возвращаемого значения:
let ast: ??? = syn::parse(token_stream_from_function_definition).unwrap();
Какой тип должен ast
быть?
2 ответа
syn::parse
функция пытается разобрать TokenStream
во все, что вы ожидаете. Как сказано в документации:
Разобрать токены исходного кода в выбранном узле синтаксического дерева.
Он принимает параметр типа, который вы обычно предоставляете, используя вывод типа. Например, если вы ожидали проанализировать объявление функции:
let fn_decl: syn::FnDecl = syn::parse(token_stream).unwrap();
Это бы запаниковало, если бы он не мог разобрать fn
декларация.
Если вы точно не знаете, чего ожидать, вы можете сделать более общий подход, сопоставить набор возможностей и затем проверить, что вы найдете. Для групп синтаксиса предусмотрены некоторые перечисления, которые могут появляться в одних и тех же местах. Например, если вы анализируете код в контексте, где вы ожидаете найти объявление функции или некоторые другие объявления на том же уровне, вам, вероятно, нужно проанализировать Item
а затем сопоставьте все возможные типы элементов:
use syn::Item;
let item: Item = syn::parse(token_stream).unwrap();
match item {
Item::Fn(fn_decl) => {}
Item::Mod(mod_item) => {}
Item::Struct(struct_item) => {}
Item::Enum(enum_item) => {}
_ => {}
}
Обратите внимание, что syn::Item
имеет 18 вариантов для соответствия, и syn::Expr
имеет 40! Определенно стоит сузить возможности и выбрать тип для анализа, наиболее подходящий для ваших нужд. Вы могли бы также рассмотреть определение своего собственного типа, представляющего различные синтаксические конструкции, которые вы ожидаете найти, и затем реализацию syn::Parse
черта вручную.
Если вы ищетеsyn
тип, связанный с некоторым типом, который вы анализируете, полезным местом может быть исходный файл элемента .
На широком уровне:
- для элементов в глобальной области видимости, т. е. fn, один из Item
- для элементов в структуре impl один из ImplItem
- для элементов в свойстве один из TraitItem
- для аргумента функции один из FnArg
и т. д...
т.е. для функции используйтеItemFn
:
let stream = quote!(fn foo(&self)->i32{0});
let a:syn::ItemFn = syn::parse2(stream).unwrap();