如何使用 darling 解析带有嵌套参数的属性?

问题描述

我正在尝试使用 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());
}

,

有一种方法可以使用 darling::util::Override。我从来没有为这个特定的实用程序起过一个好名字,所以我将添加这个确切的片段作为示例,并且有兴趣就人们更可能找到的名称进行关于 GH 的讨论。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...