簡體   English   中英

Rust proc_macro_derive:如何檢查字段是否屬於基本類型,例如 boolean?

[英]Rust proc_macro_derive: How do I check if a field is of a primitive type, like boolean?

我正在嘗試過濾掉結構中所有bool類型的字段。 但是syn::Type枚舉似乎沒有案例,或者我錯誤地閱讀了定義:

pub enum Type {
    Array(TypeArray),
    BareFn(TypeBareFn),
    Group(TypeGroup),
    ImplTrait(TypeImplTrait),
    Infer(TypeInfer),
    Macro(TypeMacro),
    Never(TypeNever),
    Paren(TypeParen),
    Path(TypePath),
    Ptr(TypePtr),
    Reference(TypeReference),
    Slice(TypeSlice),
    TraitObject(TypeTraitObject),
    Tuple(TypeTuple),
    Verbatim(TokenStream),
    // some variants omitted
}

我查看了syn::Types源,以檢查省略了哪些變體,但這並沒有讓我更進一步。 這是我到目前為止所擁有的:

#[proc_macro_derive(Creator)]
pub fn derive_creator(_item: TokenStream) -> TokenStream {
    let item = parse_macro_input!(_item as syn::DeriveInput);
    let item_ident = item.ident;

    let fields = if let syn::Data::Struct(syn::DataStruct {
        fields: syn::Fields::Named(syn::FieldsNamed { ref named, .. }),
        ..
    }) = item.data
    {
        named
    } else {
        panic!("You can derive Creator only on a struct!")
    };

    let bool_fields = fields.iter().filter(|field| 
        match field.ty {
            // case when field type is bool => true
            _ => false
        }
    );
    unimplemented!()
}

我走錯路了嗎? 或者這根本不可能? 還是我錯過了什么?

我覺得可能有一種更清潔的方式(無需克隆和分配字符串),但過去我做過類似的事情:

match field.ty {
    Type::Path(type_path) if type_path.clone().into_token_stream().to_string() == "bool" => {
        true
    }
    _ => false
}

您也許可以定義一次bool類型,然后比較它是否相等:

let bool_ty = Type::Path(TypePath {
    qself: None,
    path: Path::from(Ident::new("bool", Span::call_site())),
});

if field.ty == bool_ty {
    // it's a bool
}

但我不確定跨度的差異是否會影響平等。 Span似乎沒有實現PartialEq ,所以我猜這沒問題。*


*歡迎編輯澄清這一點。

另一種方式:

    let bool_fields = fields.iter().filter(|field| {
        if let Type::Path(tp) = &field.ty {
            let segments = &tp.path.segments;
            // Check len to avoid "bool::SomeOtherType".
            if segments.len() == 1 {
                return segments[0].ident == "bool";
            }
        }
        false
    });

記住:

值得指出的是,這會按名稱檢查是否相等。 類型別名、單字段元組或 core::primitive::bool 將不匹配,盡管它們在類型解析后都是 bool。 – 用戶2722968

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM