pub trait Cycle: SizedEnum {
// Required methods
fn try_cycle_to(self, idx: usize) -> Result<Self, CycleError>;
fn cycle_to(self, idx: usize) -> Self;
fn cycle_by(self, step: isize) -> Self;
fn next(self) -> Self;
fn prev(self) -> Self;
}Expand description
A derivable trait for cyclic linear populated enums.
A cyclic enum is one whose variants can be iterated through bidirectionally and wraps around at each boundary.
§Derivable
It is preferable to derive this trait instead of implementing it yourself.
You can use this trait with #[derive] for any enum so long as it has more
than one variant (i.e. its bit representation is greater than zero), none of
its variants have alternate discriminants (i.e. it starts at 0 and each
variant increments in value by 1) and all of its variants are unit variants.
When it is derived, you get a free implementation of SizedEnum and
TryFrom<usize>.
Required Methods§
Sourcefn try_cycle_to(self, idx: usize) -> Result<Self, CycleError>
fn try_cycle_to(self, idx: usize) -> Result<Self, CycleError>
Returns a result containing the variant at the specified index, or a
CycleError::OutOfBounds if the index was out of bounds. This method
is intended for custom error handling - generally, if you can ensure a
correct index, it is easier to use Cycle::cycle_to.
§Errors
This errors if the specified index was out of bounds for the enum. See
CycleError::OutOfBounds for more information.
§Examples
#[derive(Cycle, Debug, PartialEq)]
enum Kind {
A,
B,
C,
}
assert_eq!(Kind::A.try_cycle_to(0)?, Kind::A);
assert_eq!(Kind::A.try_cycle_to(1)?, Kind::B);
assert_eq!(Kind::A.try_cycle_to(2)?, Kind::C);
assert_eq!(Kind::A.try_cycle_to(3), Err(CycleError::OutOfBounds));No matter what variant this is called on, it behaves the same.
assert_eq!(Kind::B.try_cycle_to(0)?, Kind::A);
assert_eq!(Kind::B.try_cycle_to(1)?, Kind::B);
assert_eq!(Kind::B.try_cycle_to(2)?, Kind::C);
assert_eq!(Kind::B.try_cycle_to(3), Err(CycleError::OutOfBounds));§Roadmap
In future, this will be a static (selfless) method of another trait.
Sourcefn cycle_to(self, idx: usize) -> Self
fn cycle_to(self, idx: usize) -> Self
Returns the variant at the specified index, or panics if the index was
out of bounds. This is semantically equivalent to unwrapping the result
of Cycle::try_cycle_to.
§Panics
This panics if the specified index was out of bounds for the enum. See
CycleError::OutOfBounds for more information.
#[derive(Cycle, Debug, PartialEq)]
enum Kind {
A,
B,
C,
}
let x = Kind::A;
// kind has 3 variants so the highest index is 2 so this will panic
x.cycle_to(5);§Examples
#[derive(Cycle, Debug, PartialEq)]
enum Kind {
A,
B,
C,
}
assert_eq!(Kind::A.cycle_to(0), Kind::A);
assert_eq!(Kind::A.cycle_to(1), Kind::B);
assert_eq!(Kind::A.cycle_to(2), Kind::C);No matter what variant this is called on, it behaves the same.
assert_eq!(Kind::B.cycle_to(0), Kind::A);
assert_eq!(Kind::B.cycle_to(1), Kind::B);
assert_eq!(Kind::B.cycle_to(2), Kind::C);§Roadmap
In future, this will be a static (selfless) method of another trait.
Sourcefn cycle_by(self, step: isize) -> Self
fn cycle_by(self, step: isize) -> Self
Returns the variant step variants ahead if step is positive, or
step variants behind if step is negative, wrapping at the first and
last variant.
Sourcefn next(self) -> Self
fn next(self) -> Self
Returns the next variant. See Cycle::cycle_by.
Note that this wraps at the last variant.
§Examples
#[derive(Cycle, Debug, PartialEq)]
enum Kind {
A,
B,
C,
}
assert_eq!(Kind::A.next(), Kind::B);
assert_eq!(Kind::B.next(), Kind::C);
assert_eq!(Kind::C.next(), Kind::A);Sourcefn prev(self) -> Self
fn prev(self) -> Self
Returns the previous variant. See Cycle::cycle_by.
Note that this wraps at the first variant.
§Examples
#[derive(Cycle, Debug, PartialEq)]
enum Kind {
A,
B,
C,
}
assert_eq!(Kind::C.prev(), Kind::B);
assert_eq!(Kind::B.prev(), Kind::A);
assert_eq!(Kind::A.prev(), Kind::C);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.