//! This example demonstrates: //! //! - The behavior of a derived `FromMeta` implementation for heterogeneous enums //! (i.e. enums that include a mix of unit, newtype and struct variants). //! - Using `#[darling(word)]` to specify a unit variant to use when a receiver field //! is specified without a value (i.e. a unit variant to use for deriving the //! `FromMeta::from_word` method). //! - Using `#[darling(default)]` on a receiver field to fall back to `Default::default()` //! for the enum's value when the receiver field is not specified by the caller. use darling::{Error, FromDeriveInput, FromMeta}; use syn::parse_quote; /// A playback volume. #[derive(Debug, FromMeta, PartialEq, Eq)] enum Volume { Normal, #[darling(word)] Low, High, #[darling(rename = "dB")] Decibels(u8), } impl Default for Volume { fn default() -> Self { Volume::Normal } } #[derive(Debug, FromDeriveInput)] #[darling(attributes(play))] struct PlayReceiver { #[darling(default)] volume: Volume, } fn main() { // `Default::default()` is used when `volume` is not specified. let missing_volume = PlayReceiver::from_derive_input(&parse_quote! { #[play] struct Player; }) .unwrap(); assert_eq!(Volume::Normal, missing_volume.volume); // `#[darling(word)]` unit variant is used when `volume` is specified as a word with no value. let empty_volume = PlayReceiver::from_derive_input(&parse_quote! { #[play(volume)] struct Player; }) .unwrap(); assert_eq!(Volume::Low, empty_volume.volume); // Specified `volume` value is used when provided. let unit_variant_volume = PlayReceiver::from_derive_input(&parse_quote! { #[play(volume(high))] struct Player; }) .unwrap(); assert_eq!(Volume::High, unit_variant_volume.volume); let newtype_volume = PlayReceiver::from_derive_input(&parse_quote! { #[play(volume(dB = 100))] struct Player; }) .unwrap(); assert_eq!(Volume::Decibels(100), newtype_volume.volume); // Multiple `volume` values result in an error. let err = PlayReceiver::from_derive_input(&parse_quote! { #[play(volume(low, dB = 20))] struct Player; }) .unwrap_err(); assert_eq!( err.to_string(), Error::too_many_items(1).at("volume").to_string() ); }