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