2

我正在尝试添加一个将常量字段添加到结构的过程宏。

例子:

#[add_const]
struct MyStruct {
    id: u32,
    name: String
}

// Expands to:
struct MyStruct {
    id: u32,
    name: String
}
impl MyStruct {
    const FIELDS: [&'static str; 2] = ["id", "name"];
    const TYPES: [syn::Type; 2] = [/*Types of the fields*/];
}

我的程序宏代码如下:

#[proc_macro_attribute]
pub fn add_const(_attrs: TokenStream, input: TokenStream) -> TokenStream {
    let item_struct = parse_macro_input!(input as ItemStruct);
    let struct_name = &item_struct.ident;
    let fields: Vec<(String, syn::Type)>;
    if let syn::Fields::Named(ref _fields) = item_struct.fields {
        let _fields = &_fields.named;
        fields = _fields.iter().map(|field| {
            if let Some(ident) = &field.ident {
                let field_name: String = ident.to_string();
                let field_type = &field.ty;
                let entry = (field_name, field_type.to_owned());
                entry
            } else {
                panic!("Only named fields are supported.")
            }
        }).collect();
    } else {
        panic!("The row struct has no fields.");
    }

    let mut field_names: Vec<String> = Vec::new();
    let mut field_types: Vec<syn::Type> = Vec::new();
    
    fields.iter().for_each(|field| {
        let (_name, _type) = field;
        field_names.push(_name.to_owned());
        field_types.push(_type.to_owned());
    });

    TokenStream::from(
        quote!(
            #item_struct
            
            impl #struct_name {
                const FIELDS: [&'static str; #field_len] = [#(#field_names),*];
                const TYPES: [syn::Type; #field_len] = [#(#field_types),*];
            }
        )
    )
}

这会引发以下错误:

error[E0423]: expected value, found builtin type `i32`
 --> tests/table_row.rs:7:13
  |
7 |         id: i32,
  |             ^^^ not a value

error[E0423]: expected value, found struct `String`
   --> tests/table_row.rs:8:15
    |
8   |         name: String,
    |               ^^^^^^ help: use struct literal syntax instead: `String { vec: val }`
    |
   ::: /Users/jonaseveraert/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/string.rs:292:1
    |
292 | pub struct String {
    | ----------------- `String` defined here

我已经能够确定问题所在;

/*CODE*/
impl #struct_name {
    const FIELDS: [&'static str; #field_len] = [#(#field_names),*];
    // const TYPES: [syn::Type; #field_len] = [#(#field_types),*]; // Commenting out this line makes the errors disappear
}
/*MORE CODE*/

我怎样才能解决这个问题?即如何添加第二个常量而不出现错误,为什么会出现这些错误?

提前谢谢你,乔纳斯

4

0 回答 0