1 //! This example demonstrates:
2 //!
3 //! - The behavior of a derived `FromMeta` implementation for heterogeneous enums
4 //!   (i.e. enums that include a mix of unit, newtype and struct variants).
5 //! - Using `#[darling(word)]` to specify a unit variant to use when a receiver field
6 //!   is specified without a value (i.e. a unit variant to use for deriving the
7 //!   `FromMeta::from_word` method).
8 //! - Using `#[darling(default)]` on a receiver field to fall back to `Default::default()`
9 //!   for the enum's value when the receiver field is not specified by the caller.
10 
11 use darling::{Error, FromDeriveInput, FromMeta};
12 use syn::parse_quote;
13 
14 /// A playback volume.
15 #[derive(Debug, FromMeta, PartialEq, Eq)]
16 enum Volume {
17     Normal,
18     #[darling(word)]
19     Low,
20     High,
21     #[darling(rename = "dB")]
22     Decibels(u8),
23 }
24 
25 impl Default for Volume {
default() -> Self26     fn default() -> Self {
27         Volume::Normal
28     }
29 }
30 
31 #[derive(Debug, FromDeriveInput)]
32 #[darling(attributes(play))]
33 struct PlayReceiver {
34     #[darling(default)]
35     volume: Volume,
36 }
37 
main()38 fn main() {
39     // `Default::default()` is used when `volume` is not specified.
40     let missing_volume = PlayReceiver::from_derive_input(&parse_quote! {
41         #[play]
42         struct Player;
43     })
44     .unwrap();
45     assert_eq!(Volume::Normal, missing_volume.volume);
46 
47     // `#[darling(word)]` unit variant is used when `volume` is specified as a word with no value.
48     let empty_volume = PlayReceiver::from_derive_input(&parse_quote! {
49         #[play(volume)]
50         struct Player;
51     })
52     .unwrap();
53     assert_eq!(Volume::Low, empty_volume.volume);
54 
55     // Specified `volume` value is used when provided.
56     let unit_variant_volume = PlayReceiver::from_derive_input(&parse_quote! {
57         #[play(volume(high))]
58         struct Player;
59     })
60     .unwrap();
61     assert_eq!(Volume::High, unit_variant_volume.volume);
62     let newtype_volume = PlayReceiver::from_derive_input(&parse_quote! {
63         #[play(volume(dB = 100))]
64         struct Player;
65     })
66     .unwrap();
67     assert_eq!(Volume::Decibels(100), newtype_volume.volume);
68 
69     // Multiple `volume` values result in an error.
70     let err = PlayReceiver::from_derive_input(&parse_quote! {
71         #[play(volume(low, dB = 20))]
72         struct Player;
73     })
74     .unwrap_err();
75     assert_eq!(
76         err.to_string(),
77         Error::too_many_items(1).at("volume").to_string()
78     );
79 }
80