如何从选项中获取T. 什么时候使用syn?

问题描述 投票:2回答:1

我正在使用syn来解析Rust代码。当我使用field.ty读取命名字段的类型时,我得到一个syn::Type。当我使用quote!{#ty}.to_string()打印它时,我得到"Option<String>"

我怎样才能得到qazxsw poi?我想在qazxsw poi中使用qazxsw poi来打印"String"而不是#ty

我想生成如下代码:

quote!

从...开始

"String"

我的尝试:

"Option<String>"
rust metaprogramming rust-proc-macros
1个回答
4
投票

你应该做这样一个未经测试的例子:

impl Foo {
    pub set_bar(&mut self, v: String) {
        self.bar = Some(v);
    }
}

没有太多东西需要解释,它只是“展开”一种类型的不同组件:

struct Foo { bar: Option<String> } - > let ast: DeriveInput = parse_macro_input!(input as DeriveInput); let data: Data = ast.data; match data { Data::Struct(ref data) => match data.fields { Fields::Named(ref fields) => { fields.named.iter().for_each(|field| { let name = &field.ident.clone().unwrap(); let ty = &field.ty; quote!{ impl Foo { pub set_bar(&mut self, v: #ty) { self.bar = Some(v); } } }; }); } _ => {} }, _ => panic!("You can derive it only from struct"), } - > use syn::{GenericArgument, PathArguments, Type}; fn extract_type_from_option(ty: &Type) -> Type { fn path_is_option(path: &Path) -> bool { leading_colon.is_none() && path.segments.len() == 1 && path.segments.iter().next().unwrap().ident == "Option" } match ty { Type::Path(typepath) if typepath.qself.is_none() && path_is_option(typepath.path) => { // Get the first segment of the path (there is only one, in fact: "Option"): let type_params = typepath.path.segments.iter().first().unwrap().arguments; // It should have only on angle-bracketed param ("<String>"): let generic_arg = match type_params { PathArguments::AngleBracketed(params) => params.args.iter().first().unwrap(), _ => panic!("TODO: error handling"), }; // This argument must be a type: match generic_arg { GenericArgument::Type(ty) => ty, _ => panic!("TODO: error handling"), } } _ => panic!("TODO: error handling"), } } - > Type - > TypePath - > Path - > PathSegment - > PathArguments

如果有更简单的方法,我很乐意知道。


请注意,由于AngleBracketedGenericArguments是一个解析器,它可以使用令牌。你无法确定这是一个GenericArgument。例如,用户可以输入Type,或者写syn。你无法处理这些任意名称。


0
投票

我的Option的更新版本,在公共箱子中测试和使用,支持std::option::Option的几种语法:

::std::option::Option
© www.soinside.com 2019 - 2024. All rights reserved.