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
: Yieldsfalse
and thentrue
.- Numeric types: Yields all possible values of the type from the minimum to the maximum one.
Option
: YieldsNone
and thenSome(item)
for each possible value ofT
.Result
: YieldsOk(item)
for each possible value ofT
and thenErr(error)
for each possible value ofE
.char
: Yields all possible Unicode scalar values, i.e. all code points ranging fromU+0000
toU+10FFFF
, excluding the surrogate code points (U+D800
toU+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 implementEnumerable
. ()
: 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 toenumerator()
should not affect each other. - have a
ENUMERABLE_SIZE_OPTION
constant that matches the number of elements returned byenumerator()
. - use the default version of
ENUMERABLE_SIZE
, or provide a custom one that matchesENUMERABLE_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§
Sourceconst ENUMERABLE_SIZE_OPTION: Option<usize>
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§
Sourceconst ENUMERABLE_SIZE: usize = _
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§
Sourcetype Enumerator: Iterator<Item = Self>
type Enumerator: Iterator<Item = Self>
The type of the iterator that will be returned by the enumerator
method.
Required Methods§
Sourcefn enumerator() -> Self::Enumerator
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
.
impl Enumerable for bool
This is an implementation of the Enumerable
trait for bool
.
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
This method returns an iterator over all possible values of bool
.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Copied<Iter<'static, bool>>
Source§impl Enumerable for char
This is an implementation of the Enumerable
trait for char
.
impl Enumerable for char
This is an implementation of the Enumerable
trait for char
.
Source§fn enumerator() -> Self::Enumerator
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}'));
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Chain<RangeInclusive<char>, RangeInclusive<char>>
Source§impl Enumerable for i8
impl Enumerable for i8
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<i8>
Source§impl Enumerable for i16
impl Enumerable for i16
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<i16>
Source§impl Enumerable for i32
impl Enumerable for i32
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<i32>
Source§impl Enumerable for i64
impl Enumerable for i64
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<i64>
Source§impl Enumerable for i128
impl Enumerable for i128
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<i128>
Source§impl Enumerable for isize
impl Enumerable for isize
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<isize>
Source§impl Enumerable for u8
impl Enumerable for u8
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<u8>
Source§impl Enumerable for u16
impl Enumerable for u16
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<u16>
Source§impl Enumerable for u32
impl Enumerable for u32
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<u32>
Source§impl Enumerable for u64
impl Enumerable for u64
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<u64>
Source§impl Enumerable for u128
impl Enumerable for u128
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<u128>
Source§impl Enumerable for ()
This is an implementation of the Enumerable
trait for ()
.
impl Enumerable for ()
This is an implementation of the Enumerable
trait for ()
.
Source§fn enumerator() -> Self::Enumerator
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);
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Once<()>
Source§impl Enumerable for usize
impl Enumerable for usize
Source§fn enumerator() -> Self::Enumerator
fn enumerator() -> Self::Enumerator
Returns an iterator over all possible values of this type.
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = RangeInclusive<usize>
Source§impl<A> Enumerable for (A,)where
A: Enumerable,
impl<A> Enumerable for (A,)where
A: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize> = A::ENUMERABLE_SIZE_OPTION
type Enumerator = Tuple1Enumerator<A>
fn enumerator() -> Self::Enumerator
Source§impl<A, B> Enumerable for (A, B)where
A: Enumerable,
B: Enumerable,
impl<A, B> Enumerable for (A, B)where
A: Enumerable,
B: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple2Enumerator<A, B>
fn enumerator() -> Self::Enumerator
Source§impl<A, B, C> Enumerable for (A, B, C)
impl<A, B, C> Enumerable for (A, B, C)
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple3Enumerator<A, B, C>
fn enumerator() -> Self::Enumerator
Source§impl<A, B, C, D> Enumerable for (A, B, C, D)
impl<A, B, C, D> Enumerable for (A, B, C, D)
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple4Enumerator<A, B, C, D>
fn enumerator() -> Self::Enumerator
Source§impl<A, B, C, D, E> Enumerable for (A, B, C, D, E)
impl<A, B, C, D, E> Enumerable for (A, B, C, D, E)
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple5Enumerator<A, B, C, D, E>
fn enumerator() -> Self::Enumerator
Source§impl<A, B, C, D, E, F> Enumerable for (A, B, C, D, E, F)
impl<A, B, C, D, E, F> Enumerable for (A, B, C, D, E, F)
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple6Enumerator<A, B, C, D, E, F>
fn enumerator() -> Self::Enumerator
Source§impl<A, B, C, D, E, F, G> Enumerable for (A, B, C, D, E, F, G)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
impl<A, B, C, D, E, F, G> Enumerable for (A, B, C, D, E, F, G)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple7Enumerator<A, B, C, D, E, F, G>
fn enumerator() -> Self::Enumerator
Source§impl<A, B, C, D, E, F, G, H> Enumerable for (A, B, C, D, E, F, G, H)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
impl<A, B, C, D, E, F, G, H> Enumerable for (A, B, C, D, E, F, G, H)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple8Enumerator<A, B, C, D, E, F, G, H>
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
impl<A, B, C, D, E, F, G, H, I> Enumerable for (A, B, C, D, E, F, G, H, I)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple9Enumerator<A, B, C, D, E, F, G, H, I>
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
impl<A, B, C, D, E, F, G, H, I, J> Enumerable for (A, B, C, D, E, F, G, H, I, J)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple10Enumerator<A, B, C, D, E, F, G, H, I, J>
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple11Enumerator<A, B, C, D, E, F, G, H, I, J, K>
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
L: Enumerable,
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
L: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple12Enumerator<A, B, C, D, E, F, G, H, I, J, K, L>
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
L: Enumerable,
M: Enumerable,
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
L: Enumerable,
M: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple13Enumerator<A, B, C, D, E, F, G, H, I, J, K, L, M>
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
L: Enumerable,
M: Enumerable,
N: Enumerable,
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
L: Enumerable,
M: Enumerable,
N: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple14Enumerator<A, B, C, D, E, F, G, H, I, J, K, L, M, N>
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
L: Enumerable,
M: Enumerable,
N: Enumerable,
O: Enumerable,
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
L: Enumerable,
M: Enumerable,
N: Enumerable,
O: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple15Enumerator<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
L: Enumerable,
M: Enumerable,
N: Enumerable,
O: Enumerable,
P: Enumerable,
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)where
A: Enumerable,
B: Enumerable,
C: Enumerable,
D: Enumerable,
E: Enumerable,
F: Enumerable,
G: Enumerable,
H: Enumerable,
I: Enumerable,
J: Enumerable,
K: Enumerable,
L: Enumerable,
M: Enumerable,
N: Enumerable,
O: Enumerable,
P: Enumerable,
const ENUMERABLE_SIZE_OPTION: Option<usize>
type Enumerator = Tuple16Enumerator<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>
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
.
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
fn enumerator() -> Self::Enumerator
This method returns an iterator over all possible values of Option<T>
.
const ENUMERABLE_SIZE_OPTION: Option<usize>
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.
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
fn enumerator() -> Self::Enumerator
This method returns an iterator over all possible values of Result<T, E>
.