Crate variter[][src]

A trait and declarative macro for iterating through enum variants.

The Problem

If an enum type in Rust contains zero or more variants that have no fields, it would be valid to iterate through each of these variants. Unfortunately, there is not an easy way to achieve this.

// A suboptimal solution...
enum Status {
    Complete,
    Error,
}

impl Status {
    // not a robust solution, requires tweaking whenever a variant is added or removed
    // this computation is also invalidated if any of the variants receive fields
    fn get_variants() -> &'static [Self] { &[Status::Complete, Status::Error] }
}

The Solution

variter provides a trait VarIter that gives you the opportunity to define an associated constant that returns &'static [Self]. This trait alone won't help much on its own, but the macro derive_var_iter! can wrap your enum declarations and implement VarIter for you. As cases are added or removed, the implementation is automatically updated.

use variter::{derive_var_iter, VarIter};
derive_var_iter! {
    #[derive(Debug, PartialEq, Eq)]
    enum Status {
        Complete,
        Error,
    }
}
assert_eq!(Status::ALL_VARIANTS.len(), 2);
assert!(Status::ALL_VARIANTS.contains(&Status::Error));
assert!(Status::ALL_VARIANTS.contains(&Status::Complete));

What about a #[derive] macro?

#[derive] macros are great, but many IDEs and editors don't support autocompletion capabilities for traits derived in this way, except for the builtin traits, and possibly serde traits. On the other hand, many IDEs and editors can expand declarative macros in place and offer autocompletion and other hints.

Manual Implementations

It is not recommended to implement VarIter manually for the following reasons:

  • Manual implementations need to be updated as variants are added or removed.
  • Implementing VarIter on incorrect types is a logical error. Invalid types include:
    • structs
    • enums where any variant contains a field, such as Case1(i32) or Case2 { x: usize }
    • enums marked with the #[non_exhaustive] attribute
  • Using derive_var_iter! results in a compile-time error if appiled to the above types (albeit with an unhelpful error message!) except for #[non_exhaustive] enums!

Additionally...

This crate exports an additional macro foreign_derive_var_iter! for implementing VarIter on foreign types. The crate also implements VarIter on stable, field-less enums from core and std through the foreign_impls feature flag.

Macros

derive_var_iter

Automatically derive VarIter for your field-less enums. Multiple enum declarations can be included inside the macro.

foreign_derive_var_iter

Automatically derive VarIter for foreign field-less enums. Be sure to include all variants and that the enum is not marked with #[non_exhaustive].

Traits

VarIter

A trait for field-less enums that gives access to each of its variants.