如何用亲爱的嵌套参数解析属性?
How can I parse an attribute with nested arguments with 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 上讨论一个人们更有可能找到的名字。
我正在尝试用 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 上讨论一个人们更有可能找到的名字。