80 lines
2.3 KiB
Rust
80 lines
2.3 KiB
Rust
//! 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()
|
|
);
|
|
}
|