Trait Enumerable

Source
pub trait Enumerable: Copy {
    type Enumerator: Iterator<Item = Self>;

    const ENUMERABLE_SIZE_OPTION: Option<usize>;
    const ENUMERABLE_SIZE: usize = _;

    // Required method
    fn enumerator() -> Self::Enumerator;
}
Expand description

Enumerable is a trait for types that can have their possible values enumerated.

§Overview

To enumerate all possible values of a Enumerable type, call the enumerator method, which returns an iterator of type Self::Enumerator.

It’s also possible to get the number of possible values of a Enumerable type constantly by accessing the ENUMERABLE_SIZE constant. If the number of possible values exceeds usize::MAX, the constant will panic at compile time. To avoid this, use ENUMERABLE_SIZE_OPTION instead. It’s Some(ENUMERABLE_SIZE) if it does not exceed usize::MAX, None otherwise.

§Built-in Implementations

The following types have built-in implementations of the Enumerable trait:

  • bool: Yields false and then true.
  • Numeric types: Yields all possible values of the type from the minimum to the maximum one.
  • Option: Yields None and then Some(item) for each possible value of T.
  • Result: Yields Ok(item) for each possible value of T and then Err(error) for each possible value of E.
  • char: Yields all possible Unicode scalar values, i.e. all code points ranging from U+0000 to U+10FFFF, excluding the surrogate code points (U+D800 to U+DFFF), from the lowest to the highest one.
  • Tuples: Yields all possible values of the tuple with 1 to 16 elements, in a lexicographic ordering (as core::cmp::Ord does), provided that all elements implement Enumerable.
  • (): Yields the unit value ().

§Derivable

This trait can be derived using #[derive(Enumerable)] on structs and enums, if

  • they have no fields, or
  • all of their fields implement Enumerable.

If the type has generic parameters, they must also meet the following requirements:

  • there are only type parameters, i.e. no lifetime or const parameters, and
  • all type parameters implement Copy.

See “Guarantees and Limitations” below for more information.

§Customizing the Generated Enumerator

In most cases, #[derive(Enumerable)] will generate a new enumerator type named <Type>Enumerator in the same module, with the same visibility and generic parameters as the type to be derived <Type>. It’s possible to customize the name of the generated type by using

  • #[enumerator = "DesiredEnumeratorName"], or
  • #[enumerator(DesiredEnumeratorName)],

they are equivalent.

#[derive(Enumerable)] will NOT generate an enumerator type when the type to be derived is

  • an enum with zero variants,
  • an enum with no fields, or
  • a struct with no fields,

in these cases, the custom enumerator name will be ignored.

§Guarantees and Requirements

It is guaranteed that:

  • The derived implementations will enumerate over all possible variants of an enum in the order they are declared. Variants with fields of uninhabited types (e.g. empty enums) will be skipped.
  • The derived implementations will yield all possible values of a struct (or a variant with some fields of an enum) in a lexicographic ordering based on the top-to-bottom declaration order of the fields, as built-in implementations for tuples do.

It is NOT guaranteed that:

  • The derived and the built-in implementations will return a specific type of Iterator as enumerators.

    Do NOT rely on the specific type of the enumerator provided by an Enumerable type, unless you are using #[enumerator(...)] and knowing that #[derive(Enumerable)] will generate an enumerator type, use <T as Enumerable>::Enumerator instead in all other cases.

It is REQUIRED that if you are implementing Enumerable for a type manually, your enumerator should:

  • have a idempotent enumerator() method, i.e. calling it multiple times should return iterators that yield the same values in the same order. Multiple calls to enumerator() should not affect each other.
  • have a ENUMERABLE_SIZE_OPTION constant that matches the number of elements returned by enumerator().
  • use the default version of ENUMERABLE_SIZE, or provide a custom one that matches ENUMERABLE_SIZE_OPTION.

Failed to meet the requirements will result in unexpected behavior when interacting with the derived implementations.

§Example

use enumerable::Enumerable;

#[derive(Copy, Clone, Eq, PartialEq, Debug, Enumerable)]
enum SomeEnum { A, B, C }

let mut enumerated = SomeEnum::enumerator().collect::<Vec<_>>();
assert_eq!(enumerated, vec![SomeEnum::A, SomeEnum::B, SomeEnum::C]);

let mut enumerated = Option::<SomeEnum>::enumerator().collect::<Vec<_>>();
assert_eq!(enumerated, vec![None, Some(SomeEnum::A), Some(SomeEnum::B), Some(SomeEnum::C)]);

Required Associated Constants§

Source

const ENUMERABLE_SIZE_OPTION: Option<usize>

The number of elements in this enumerable wrapped in Option::Some if it does not exceed usize::MAX, None otherwise.

If a usize without any wrapper is preferred, use ENUMERABLE_SIZE instead.

§Example
use enumerable::Enumerable;
assert_eq!(u8::ENUMERABLE_SIZE_OPTION, Some(256usize));
assert_eq!(<(usize, usize)>::ENUMERABLE_SIZE_OPTION, None);

Provided Associated Constants§

Source

const ENUMERABLE_SIZE: usize = _

The number of elements in this enumerable. If the number exceeds the usize::MAX, accessing this constant fails at compile time.

It’s generally unnecessary to provide this constant manually, as a default value is provided using ENUMERABLE_SIZE_OPTION.

§Example
use enumerable::Enumerable;
let array = [0; u8::ENUMERABLE_SIZE];

This fails to compile:

use enumerable::Enumerable;
let array = [0; <(usize, usize)>::ENUMERABLE_SIZE];

Required Associated Types§

Source

type Enumerator: Iterator<Item = Self>

The type of the iterator that will be returned by the enumerator method.

Required Methods§

Source

fn enumerator() -> Self::Enumerator

Return an iterator over all possible values of the implementing type.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl Enumerable for bool

This is an implementation of the Enumerable trait for bool.

Source§

fn enumerator() -> Self::Enumerator

This method returns an iterator over all possible values of bool.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Copied<Iter<'static, bool>>

Source§

impl Enumerable for char

This is an implementation of the Enumerable trait for char.

Source§

fn enumerator() -> Self::Enumerator

This method returns an iterator over all possible values of char, which is U+0000 to U+10FFFF, excluding the surrogate code points.

§Example
use enumerable::Enumerable;

assert_eq!(char::enumerator().skip(0x41).next(), Some('\u{41}'));
Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Chain<RangeInclusive<char>, RangeInclusive<char>>

Source§

impl Enumerable for i8

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<i8>

Source§

impl Enumerable for i16

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<i16>

Source§

impl Enumerable for i32

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<i32>

Source§

impl Enumerable for i64

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<i64>

Source§

impl Enumerable for i128

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<i128>

Source§

impl Enumerable for isize

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<isize>

Source§

impl Enumerable for u8

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<u8>

Source§

impl Enumerable for u16

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<u16>

Source§

impl Enumerable for u32

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<u32>

Source§

impl Enumerable for u64

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<u64>

Source§

impl Enumerable for u128

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<u128>

Source§

impl Enumerable for ()

This is an implementation of the Enumerable trait for ().

Source§

fn enumerator() -> Self::Enumerator

This method returns an iterator over all possible values of ().

§Example
let mut iter = <() as enumerable::Enumerable>::enumerator();
assert_eq!(iter.next(), Some(()));
assert_eq!(iter.next(), None);
Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Once<()>

Source§

impl Enumerable for usize

Source§

fn enumerator() -> Self::Enumerator

Returns an iterator over all possible values of this type.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = RangeInclusive<usize>

Source§

impl<A> Enumerable for (A,)
where A: Enumerable,

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize> = A::ENUMERABLE_SIZE_OPTION

Source§

type Enumerator = Tuple1Enumerator<A>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B> Enumerable for (A, B)
where A: Enumerable, B: Enumerable,

Source§

impl<A, B, C> Enumerable for (A, B, C)
where A: Enumerable, B: Enumerable, C: Enumerable,

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple3Enumerator<A, B, C>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D> Enumerable for (A, B, C, D)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple4Enumerator<A, B, C, D>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E> Enumerable for (A, B, C, D, E)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple5Enumerator<A, B, C, D, E>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E, F> Enumerable for (A, B, C, D, E, F)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple6Enumerator<A, B, C, D, E, F>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E, F, G> Enumerable for (A, B, C, D, E, F, G)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple7Enumerator<A, B, C, D, E, F, G>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E, F, G, H> Enumerable for (A, B, C, D, E, F, G, H)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple8Enumerator<A, B, C, D, E, F, G, H>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E, F, G, H, I> Enumerable for (A, B, C, D, E, F, G, H, I)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple9Enumerator<A, B, C, D, E, F, G, H, I>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E, F, G, H, I, J> Enumerable for (A, B, C, D, E, F, G, H, I, J)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple10Enumerator<A, B, C, D, E, F, G, H, I, J>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E, F, G, H, I, J, K> Enumerable for (A, B, C, D, E, F, G, H, I, J, K)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple11Enumerator<A, B, C, D, E, F, G, H, I, J, K>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E, F, G, H, I, J, K, L> Enumerable for (A, B, C, D, E, F, G, H, I, J, K, L)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple12Enumerator<A, B, C, D, E, F, G, H, I, J, K, L>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E, F, G, H, I, J, K, L, M> Enumerable for (A, B, C, D, E, F, G, H, I, J, K, L, M)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple13Enumerator<A, B, C, D, E, F, G, H, I, J, K, L, M>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E, F, G, H, I, J, K, L, M, N> Enumerable for (A, B, C, D, E, F, G, H, I, J, K, L, M, N)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple14Enumerator<A, B, C, D, E, F, G, H, I, J, K, L, M, N>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> Enumerable for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple15Enumerator<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P> Enumerable for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Tuple16Enumerator<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>

Source§

fn enumerator() -> Self::Enumerator

Source§

impl<T> Enumerable for Option<T>
where T: Enumerable,

This is an implementation of the Enumerable trait for Option<T> where T is Enumerable.

Source§

fn enumerator() -> Self::Enumerator

This method returns an iterator over all possible values of Option<T>.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = OptionEnumerator<T>

Source§

impl<T, E> Enumerable for Result<T, E>
where T: Enumerable, E: Enumerable,

Implementation of the Enumerable trait for Result<T, E>, with core::iter::Chain and core::iter::Map.

Source§

fn enumerator() -> Self::Enumerator

This method returns an iterator over all possible values of Result<T, E>.

Source§

const ENUMERABLE_SIZE_OPTION: Option<usize>

Source§

type Enumerator = Chain<Map<<T as Enumerable>::Enumerator, fn(T) -> Result<T, E>>, Map<<E as Enumerable>::Enumerator, fn(E) -> Result<T, E>>>

Implementors§