1 //! Example showing potentially-nested meta item parsing with `darling::util::Override`.
2 //!
3 //! Based on https://stackoverflow.com/q/68046070/86381 by https://github.com/peterjoel
4
5 // The use of fields in debug print commands does not count as "used",
6 // which causes the fields to trigger an unwanted dead code warning.
7 #![allow(dead_code)]
8
9 use std::borrow::Cow;
10
11 use darling::{util::Override, FromDeriveInput, FromMeta};
12 use syn::{Ident, Path};
13
14 #[derive(Debug, FromDeriveInput)]
15 #[darling(attributes(myderive))]
16 struct MyDeriveInput {
17 ident: Ident,
18 /// We can infer the right "table" behavior for this derive, but we want the caller to be
19 /// explicit that they're expecting the inference behavior to avoid cluttering some hypothetical
20 /// database. Therefore this field is required, but can take word form or key-value form.
21 ///
22 /// To make this field optional, we could add `#[darling(default)]`, or we could
23 /// wrap it in `Option` if the presence or absence of the word makes a difference.
24 table: Override<Table>,
25 }
26
27 impl MyDeriveInput {
table(&self) -> Cow<'_, Table>28 fn table(&self) -> Cow<'_, Table> {
29 match &self.table {
30 Override::Explicit(value) => Cow::Borrowed(value),
31 Override::Inherit => Cow::Owned(Table {
32 name: self.ident.to_string(),
33 value: None,
34 }),
35 }
36 }
37 }
38
39 #[derive(Debug, Clone, FromMeta)]
40 struct Table {
41 name: String,
42 value: Option<Path>,
43 }
44
from_str(s: &str) -> darling::Result<MyDeriveInput>45 fn from_str(s: &str) -> darling::Result<MyDeriveInput> {
46 FromDeriveInput::from_derive_input(&syn::parse_str(s)?)
47 }
48
main()49 fn main() {
50 let missing = from_str(
51 r#"
52 #[derive(MyTrait)]
53 struct Foo(u64);
54 "#,
55 )
56 .unwrap_err();
57
58 let short_form = from_str(
59 r#"
60 #[derive(MyTrait)]
61 #[myderive(table)]
62 struct Foo(u64);
63 "#,
64 )
65 .unwrap();
66
67 let long_form = from_str(
68 r#"
69 #[derive(MyTrait)]
70 #[myderive(table(name = "Custom"))]
71 struct Foo(u64);
72 "#,
73 )
74 .unwrap();
75
76 println!("Error when missing: {}", missing);
77 println!("Short form: {:?}", short_form.table());
78 println!("Long form: {:?}", long_form.table());
79 }
80