enum-iterator
Derive-based tools to iterate over every value of a Rust type
Repository Health
Technical Analysis
enum-iterator provides tools to enumerate all values of a Rust type. By deriving the Sequence trait, a type gains a well-defined ordering of its inhabitants, and the crate’s free functions let you iterate over all of them, count them, and step forward or backward between adjacent values.
It works not only for simple field-less enums but also for enums with data and structs, computing the Cartesian product of each field’s own value space. This makes it useful for exhaustive testing, building menus or option lists, and any situation where you need the complete, ordered set of a type’s possible values.
What You Get
- A #[derive(Sequence)] macro that defines the ordered value space of a type
- all() and reverse_all() iterators over every value, forward or backward
- cardinality(), first(), and last() to count and bound the value space
- next() and previous() to step between adjacent values
Common Use Cases
- Exhaustively iterating over enum variants for menus, matching, or dispatch
- Property-style testing across every possible value of a small type
- Computing the total number of inhabitants of a composite type
Under The Hood
Architecture - The project is a Cargo workspace with two crates: enum-iterator (the facade, ~1,081-line lib.rs) and enum-iterator-derive (a proc-macro). The heart is the Sequence trait, which defines a type’s cardinality plus next/previous operations that walk a total order over the type’s inhabitants. The derive expands a type into this ordering by treating a struct or enum-with-data as the Cartesian product of its fields’ own Sequence orderings, so composite types enumerate correctly. Free functions (all, reverse_all, first, last, cardinality, next, previous) are thin wrappers over the trait.
Tech Stack - Pure Rust tracking stable, no_std-compatible core. The derive crate builds on the usual proc-macro tooling (syn/quote). No heavy runtime dependencies in the facade crate.
Code Quality - A single well-documented lib.rs with runnable doc examples and blanket implementations for standard types, backed by the derive crate. The design leans on the type system to guarantee the ordering is total and finite.
API Design - The public API is small and intuitive: derive Sequence, then call turbofish’d free functions like all::<Day>() or cardinality::<Foo>(). Naming mirrors familiar iterator/ordering vocabulary, and the composite-type behavior follows naturally, giving a gentle learning curve.