如何为用属性本身注释的结构体的字段提供属性?

csh*_*rad 1 rust

我想实现proc_macro_attribute这样一个:

#[component]
struct Div {
    #[prop]
    color: String,
    clicked: bool
}
Run Code Online (Sandbox Code Playgroud)

其中两个属性的 impl 是:

#[proc_macro_attribute]
pub fn component(_attribute: TokenStream, input: TokenStream) -> TokenStream {
    modify_struct_and_generate_props_struct(input)
}

// Just as a placeholder attribute for the component attribute to work on.
#[proc_macro_attribute]
pub fn prop(_attribute: TokenStream, input: TokenStream) -> TokenStream {
    input
}
Run Code Online (Sandbox Code Playgroud)

我可以使用自定义派生来完成此操作,但这不是我想要在这里实现的目标,因为任何带有注释的结构都#[component]将被修改以包含其他字段。sub#[prop]属性用于创建仅由 prop 字段组成的新结构。

不proc_macro_attribute支持在其上下文中使用的其他子属性,我尝试实现一个单独的属性来缓解这种情况。这会导致编译器出错:

#[component]
struct Div {
    #[prop]
    color: String,
    clicked: bool
}
Run Code Online (Sandbox Code Playgroud)

添加此功能与#![feature(proc_macro)].

我已经在GitHub上定义了问题。你可以查一下它,看看我正在努力实现什么目标。

难道就没有其他可能的出路吗?

如果这不是它本来的样子,我还向 Rust 提出了一个问题。

csh*_*rad 5

proc_macro_attribute 不支持其他子属性...

事实上确实如此。

唯一的事情是,编译器不希望最终扩展结构上有任何编译器未知的属性。我正在宏内扩展结构#[component],但保留属性不变#[prop]。这导致编译器搜索该宏的含义并出错。

因此,为了使其发挥作用,请务必在使用该属性后将其从字段中删除。任何残留都会导致编译器出错。

#[proc_macro_attribute]
pub fn component(_attribute: TokenStream, input: TokenStream) -> TokenStream {
    let item: syn::Item = syn::parse(input).unwrap();
    let props_struct = generate_props_struct(&item);
    let modified_struct = modify_struct_and_remove_props_attribute(&item);
    quote! {
        #props_struct

        #modified_struct
    }
} 
Run Code Online (Sandbox Code Playgroud)

此外,该结构不需要单独定义任何占位符属性。proc_macro_attribute字段上的每个属性都位于结构上放置的上下文中。

我已经用评论更新了github 存储库,以了解如何完成它。