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