rust - 如何使用亲爱的解析带有嵌套参数的属性?

标签 rust rust-proc-macros

我正在尝试使用 darling 解析一个属性,我想支持以下用法:

// att not specified
#[derive(MyTrait)]
struct Foo(u64);

// att specified without an argument
#[derive(MyTrait)]
#[myderive(att)]
struct Foo(u64);

// att specified with an argument
#[derive(MyTrait)]
#[myderive(att(value = "String"))]
struct Foo(u64);
这些是我的类型:
#[derive(FromDeriveInput)]
#[darling(attributes(myderive))]
struct MyDeriveInput {
    #[darling(default)]
    att: Option<MyAttr>,
}

#[derive(FromMeta, Default)]
struct MyAttr {
    #[darling(default)]
    value: Option<Path>,
}
还有一个测试:
#[test]
fn test() {
    let derive_input = syn::parse_str(
        r#"
        #[derive(MyTrait)]
        #[myderive(att)]
        struct Foo(u64);
    "#,
    )
    .unwrap();

    let parsed: MyDeriveInput = FromDeriveInput::from_derive_input(&derive_input).unwrap();
    assert!(parsed.att.is_some());
}
我收到此错误:
thread 'test' panicked at 'called `Result::unwrap()` on an `Err` value:
Error { kind: UnexpectedFormat("word"), locations: ["att"], span: Some(Span) }'
如果我指定 att,我会得到同样的错误,无论是否value被指定。
这可能吗?如果是这样,亲爱的希望将其解析为什么结构?

最佳答案

对于作为结构体的属性值,派生的语法并不完全以这种方式工作。
如果你想指定有一个 att但默认情况下,您应该将其设置为 att() .
这是一个固定的完整代码和测试单元:

extern crate proc_macro;
extern crate syn;

use {
    darling::*,
    std::path::*,
};

#[derive(FromMeta)]
struct MyAttr {
    #[darling(default)]
    value: Option<String>, // I dunno what was your "Path" so I've put String
}

#[derive(FromDeriveInput, Default)]
#[darling(attributes(myderive))]
struct MyTrait {
    #[darling(default)]
    att: Option<MyAttr>,
}


#[test]
fn test() {

    // with specified MyAttr:
    let derive_input = syn::parse_str(
        r#"
        #[derive(MyTrait)]
        #[myderive(att(value = "test"))]
        struct Foo(u64);
    "#,
    )
    .unwrap();
    let parsed: MyTrait = FromDeriveInput::from_derive_input(&derive_input).unwrap();
    assert!(parsed.att.is_some());

    // with default MyAttr:
    let derive_input = syn::parse_str(
        r#"
        #[derive(MyTrait)]
        #[myderive(att())]
        struct Foo(u64);
    "#,
    )
    .unwrap();
    let parsed: MyTrait = FromDeriveInput::from_derive_input(&derive_input).unwrap();
    assert!(parsed.att.is_some());

    // with no MyAttr:
    let derive_input = syn::parse_str(
        r#"
        #[derive(MyTrait)]
        #[myderive()]
        struct Foo(u64);
    "#,
    )
    .unwrap();
    let parsed: MyTrait = FromDeriveInput::from_derive_input(&derive_input).unwrap();
    assert!(parsed.att.is_none());


    // with no myderive
    let derive_input = syn::parse_str(
        r#"
        #[derive(MyTrait)]
        struct Foo(u64);
    "#,
    )
    .unwrap();
    let parsed: MyTrait = FromDeriveInput::from_derive_input(&derive_input).unwrap();
    assert!(parsed.att.is_none());
}

关于rust - 如何使用亲爱的解析带有嵌套参数的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68046070/

相关文章:

rust - 在过程宏中,如何检查字符串是否是有效的变量名而不是关键字?

rust - 如何删除使用 cargo install 安装的二进制文件?

rust - 我应该如何减少 Rust 类型签名的重复?

Rust 异步和 AsRef<P : Path> not being Send

rust - 转换类型里面的报价!给出特征错误

rust - 将枚举变体用作函数的这种奇怪语法是什么?

testing - 对 crate 内的模块运行测试

generics - 如何限制运算符实现的右侧参数的类型?

debugging - 如何查看导致我的编译错误的扩展宏代码?

rust - 如何找到 syn::parse 的正确返回类型?