Derive Macro Exhaust

Source
#[derive(Exhaust)]
Expand description

Derive macro generating an impl of the trait Exhaust.

§Applicability

This macro may be applied to structs and enums, but not unions. All fields must have types which themselves implement Exhaust.

If your type has invariants enforced through private fields, then do not use this derive macro, as that would make it possible to obtain instances with any values whatsoever. There is not currently any way to add constraints.

§Generated code

The macro generates the following items:

  • An implementation of Exhaust for your type.

  • A “factory” struct type for <Self as Exhaust>::Factory.

    It has no public fields. It implements Clone and fmt::Debug. It is unnameable except through the associated type, <Self as Exhaust>::Factory.

  • An iterator struct type for <Self as Exhaust>::Iter.

    It has no public fields. It implements Iterator, FusedIterator, Clone, and fmt::Debug, but not DoubleEndedIterator or ExactSizeIterator. It does not currently override any of the optional iterator methods such as Iterator::size_hint(). It is unnameable except through the associated type, <Self as Exhaust>::Iter.

The fmt::Debug implementations currently print only a placeholder with no details. This may be changed in future versions.

All of the generated types have names like Exhaust<your type name><some suffix>. Unfortunately, it is possible for these names to conflict with your code’s names; but conflicts will not occur as long as you avoid using any items named ExhaustFoo* from within a type named Foo. Items which are merely in the same module do not interfere, because only the code generated by the derive(Exhaust) macro is affected.

§Example

use exhaust::Exhaust;

#[derive(PartialEq, Debug, Exhaust)]
struct Foo {
    a: bool,
    b: Bar,
}

#[derive(PartialEq, Debug, Exhaust)]
enum Bar {
    One,
    Two(bool),
}

assert_eq!(
    Foo::exhaust().collect::<Vec<Foo>>(),
    vec![
        Foo { a: false, b: Bar::One },
        Foo { a: false, b: Bar::Two(false) },
        Foo { a: false, b: Bar::Two(true) },
        Foo { a: true, b: Bar::One },
        Foo { a: true, b: Bar::Two(false) },
        Foo { a: true, b: Bar::Two(true) },
    ],
);