#![cfg(test)] #![allow(unused)] use default_variant::default; #[default(Foo(true))] enum MyTuple1 { Foo(bool), Bar, Baz(usize), } #[default(Bar((), 'a'))] enum MyTuple2 { Foo, Bar((), char), } /// Notice that `TuplesWithBounds` is generic over `A` and `B`. /// /// We are able to conditionally derive a `Default` implementation /// using a variant that depends on `A` and `B` using a `where`-clause /// in the attribute, which will have the same effect as adding the /// bounds in an `impl`-block. #[default( Baz(Default::default(), Default::default()) where A: Default, B: Default )] enum MyGenericTuple1 { Foo(A), Bar(B), Baz(A, B), } /// We are able to derive a `Default` implementation for a generic /// enum and not require any bounds over its type parameters as long /// as the provided variant does not depend on any generic parameters. #[default(Empty)] enum MyGenericTuple2 { Empty, One(A), } #[test] fn tuple_1_variant_defaults() { assert!(matches!(MyTuple1::default(), MyTuple1::Foo(true))); } #[test] fn tuple_2_variant_defaults() { assert!(matches!(MyTuple2::default(), MyTuple2::Bar((), 'a'))); } #[test] fn generic_tuple_1_variant_with_bounds_in_default() { assert!(matches!( MyGenericTuple1::::default(), MyGenericTuple1::Baz(false, 0) )); assert!(matches!( MyGenericTuple1::::default(), MyGenericTuple1::Baz(false, (0, 0)) )); } #[test] fn generic_tuple_2_variant_without_bounds_default() { struct HasNoDefault; assert!(matches!( MyGenericTuple2::::default(), MyGenericTuple2::Empty )); assert!(matches!( MyGenericTuple2::, ()>>::default(), MyGenericTuple2::Empty )); }