# `#[derive(QuickCheck)]` Automatically implements `quickcheck::Arbitrary` for any data structure. Rules: - For `struct`s (or, generally, when you have _all_ of a collection of types), we simply call `quickcheck::Arbitrary::arbitrary` on each. - For `enum`s (or, generally, when you have _one_ of a collection of types), we weight all variants equally. - All type parameters (``) must implement `quickcheck::Arbitrary`. If not, the struct will still work outside `quickcheck`, but you can't property-test it. - Caveat: We might in the future check if you actually use that type parameter, but for now, we don't (e.g. `PhantomData` still requires ``). ## Structs ```rust // vvvvvvvvvv #[derive(Clone, Debug, QuickCheck)] struct StructWithABunchOfEdgeCases { a: A, b: B, t1: T, t2: T, t3: T, } ``` automatically writes the following: ```rust impl< A: ::quickcheck::Arbitrary, B: ::quickcheck::Arbitrary, T: ::quickcheck::Arbitrary, const N: usize, // recognizes this is not a type > ::quickcheck::Arbitrary for StructWithABunchOfEdgeCases { #[inline] fn arbitrary(g: &mut ::quickcheck::Gen) -> Self { a: ::arbitrary(g), b: ::arbitrary(g), t1: ::arbitrary(g), t2: ::arbitrary(g), t3: ::arbitrary(g), } } ``` ## Enums ```rust #[derive(Clone, Debug, QuickCheck)] enum Enum { First(A, B, C), Second(A, B, C), Third(A, B, C), } ``` becomes ```rust impl< A: ::quickcheck::Arbitrary, B: ::quickcheck::Arbitrary, C: ::quickcheck::Arbitrary, > ::quickcheck::Arbitrary for Enum { #[inline] fn arbitrary(g: &mut ::quickcheck::Gen) -> Self { g.choose:: Self>(&[ (move |g| Self::First( ::arbitrary(g), ::arbitrary(g), ::arbitrary(g), )) as fn(&mut ::quickcheck::Gen) -> Self, (move |g| Self::Second( ::arbitrary(g), ::arbitrary(g), ::arbitrary(g), )) as fn(&mut ::quickcheck::Gen) -> Self, (move |g| Self::Third( ::arbitrary(g), ::arbitrary(g), ::arbitrary(g), )) as fn(&mut ::quickcheck::Gen) -> Self, ]).unwrap()(g) } } ``` All credit for the incredible `quickcheck` library goes to its authors, not me! :)