#![cfg(test)] use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use default_variant::default; static FIZZBUZZ_STATE: AtomicUsize = AtomicUsize::new(0); #[derive(PartialEq, Debug)] #[default(fizzbuzz())] pub enum FizzBuzz { Fizz, Buzz, FizzBuzz, N(usize), } impl FizzBuzz { fn which(n: usize) -> Self { match (n % 3 == 0, n % 5 == 0) { (true, true) => Self::FizzBuzz, (true, false) => Self::Fizz, (false, true) => Self::Buzz, (false, false) => Self::N(n), } } fn fizzbuzz() -> Self { let n = FIZZBUZZ_STATE.fetch_add(1, Ordering::Acquire); Self::which(n) } } #[test] fn fizz_buzz_states_via_default() { for i in 0..100 { let expected = FizzBuzz::which(i); let actual = FizzBuzz::default(); assert_eq!(actual, expected) } } static COUNT: AtomicUsize = AtomicUsize::new(0); #[default(toggle_global_parity())] #[derive(PartialEq, Debug)] enum Parity { Even(usize), Odd(usize), } impl Parity { fn toggle_global_parity() -> Self { let n = COUNT.fetch_add(1, Ordering::Acquire); (if n % 2 == 0 { Self::Even } else { Self::Odd })(n) } } #[test] fn parity_default_changes_state() { assert_eq!(COUNT.load(Ordering::Relaxed), 0); for i in 0..100 { let parity_of = if i % 2 == 0 { Parity::Even } else { Parity::Odd }; assert_eq!(Parity::default(), parity_of(i)); } } static RIDICULOUS: AtomicBool = AtomicBool::new(true); #[derive(PartialEq, Debug)] #[default(ridiculous())] enum Ridiculous { Yep(bool), Nah(bool), } impl Ridiculous { fn ridiculous() -> Self { let b = RIDICULOUS.load(Ordering::Acquire); RIDICULOUS.store(!b, Ordering::Release); (if b { Self::Yep } else { Self::Nah })(b) } } #[test] fn assert_ridiculous_default_states() { assert_eq!(RIDICULOUS.load(Ordering::Relaxed), true); for i in 0..10 { let even = i % 2 == 0; let can_we = if even { Ridiculous::Yep } else { Ridiculous::Nah }; assert_eq!(Ridiculous::default(), can_we(even)); } }