Trait enum_iterator::Sequence
source · pub trait Sequence: Sized {
const CARDINALITY: usize;
// Required methods
fn next(&self) -> Option<Self>;
fn previous(&self) -> Option<Self>;
fn first() -> Option<Self>;
fn last() -> Option<Self>;
}
Expand description
Trait to iterate over the values of a type.
The crate root defines useful functions to work with types implementing Sequence
.
Derivation
Sequence
can be derived for enum
and struct
types. Specifically, it can be derived
for:
- Enumerations whose variants meet one of the following criteria:
- The variant does not have fields.
- The variant has fields meeting all these conditions:
- Every field has a type that implements
Sequence
. - Every field but the last one has a type that implements
Clone
.
- Every field has a type that implements
- Enumerations without variants.
- Structures whose fields meet all these conditions:
- Every field has a type that implements
Sequence
. - Every field but the last one has a type that implements
Clone
.
- Every field has a type that implements
- Unit structures (i.e. without fields).
The cardinality (number of values) of the type must not exceed usize::MAX
.
Laws
T: Sequence
implies the following assertions:
T::first().and_then(|x| x.previous()).is_none()
T::last().and_then(|x| x.next()).is_none()
T::first().is_none()
⇔T::last().is_none()
std::iter::successors(T::first(), T::next)
must eventually yieldT::last()
.
Examples
C-like enumeration
use enum_iterator::{all, cardinality, Sequence};
#[derive(Clone, Copy, Debug, PartialEq, Sequence)]
enum Direction { North, South, West, East }
assert_eq!(cardinality::<Direction>(), 4);
assert_eq!(all::<Direction>().collect::<Vec<_>>(), [
Direction::North,
Direction::South,
Direction::West,
Direction::East,
]);
Enumeration with data
use enum_iterator::{all, cardinality, Sequence};
#[derive(Clone, Copy, Debug, PartialEq, Sequence)]
enum Direction { North, South, West, East }
#[derive(Clone, Copy, Debug, PartialEq, Sequence)]
enum Greeting {
Hi,
Bye,
}
#[derive(Clone, Copy, Debug, PartialEq, Sequence)]
enum Action {
Move(Direction),
Jump,
Talk { greeting: Greeting, loud: bool },
}
assert_eq!(cardinality::<Action>(), 4 + 1 + 2 * 2);
assert_eq!(all::<Action>().collect::<Vec<_>>(), [
Action::Move(Direction::North),
Action::Move(Direction::South),
Action::Move(Direction::West),
Action::Move(Direction::East),
Action::Jump,
Action::Talk { greeting: Greeting::Hi, loud: false },
Action::Talk { greeting: Greeting::Hi, loud: true },
Action::Talk { greeting: Greeting::Bye, loud: false },
Action::Talk { greeting: Greeting::Bye, loud: true },
]);
Structure
use enum_iterator::{all, cardinality, Sequence};
#[derive(Clone, Copy, Debug, PartialEq, Sequence)]
enum Side {
Left,
Right,
}
#[derive(Clone, Copy, Debug, PartialEq, Sequence)]
enum LimbKind {
Arm,
Leg,
}
#[derive(Debug, PartialEq, Sequence)]
struct Limb {
kind: LimbKind,
side: Side,
}
assert_eq!(cardinality::<Limb>(), 4);
assert_eq!(all::<Limb>().collect::<Vec<_>>(), [
Limb { kind: LimbKind::Arm, side: Side::Left },
Limb { kind: LimbKind::Arm, side: Side::Right },
Limb { kind: LimbKind::Leg, side: Side::Left },
Limb { kind: LimbKind::Leg, side: Side::Right },
]);
Required Associated Constants§
sourceconst CARDINALITY: usize
const CARDINALITY: usize
Number of values of type Self
.
Example
use enum_iterator::Sequence;
#[derive(Sequence)]
enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
assert_eq!(Day::CARDINALITY, 7);
Required Methods§
sourcefn next(&self) -> Option<Self>
fn next(&self) -> Option<Self>
Returns value following *self
or None
if this was the end.
Values are yielded in the following order. Comparisons between values are based on their
relative order as yielded by next
; an element yielded after another is considered greater.
- For primitive types, in increasing order (same as
Ord
). - For arrays and tuples, in lexicographic order of the sequence of their elements.
- When derived for an enumeration, in variant definition order.
- When derived for a structure, in lexicographic order of the sequence of its fields taken in definition order.
The order described above is the same as Ord
if any custom Sequence
implementation
follows Ord
and any enumeration has its variants defined in increasing order of
discriminant.
Example
use enum_iterator::Sequence;
#[derive(Debug, PartialEq, Sequence)]
enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
assert_eq!(Day::Tuesday.next(), Some(Day::Wednesday));
sourcefn previous(&self) -> Option<Self>
fn previous(&self) -> Option<Self>
Returns value preceding *self
or None
if this was the beginning.
Example
use enum_iterator::Sequence;
#[derive(Debug, PartialEq, Sequence)]
enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
assert_eq!(Day::Wednesday.previous(), Some(Day::Tuesday));