[−][src]Crate rotate_enum
rotate-enum crate
This crate provides simple macros that implements prev()
and next()
methods to an enum.
Motivation
Sometimes you define an enum like this
enum Direction { Up, Left, Down, Right, }
and you want to rotate them in some logic,
let up = Direction::Up; let left = Direction::Left; let down = Direction::Down; let right = Direction::Right; assert!(up.next() == left); assert!(left.next() == down); assert!(down.next() == right); assert!(right.next() == up); assert!(up.prev() == right); assert!(left.prev() == up); assert!(down.prev() == left); assert!(right.prev() == down);
You can of course implement these methods manually, but it's repetitive and error prone.
Don't you think it should be automated?
This crate provides a RotateEnum
derive macro to just do this.
Shifting
This crate also provides ShiftEnum
, which will exhaust at the end of the enum list,
rather than rotating.
let up = Direction::Up; let left = Direction::Left; let down = Direction::Down; let right = Direction::Right; assert!(up.next() == Some(left)); assert!(left.next() == Some(down)); assert!(down.next() == Some(right)); assert!(right.next() == None); assert!(up.prev() == None); assert!(left.prev() == Some(up)); assert!(down.prev() == Some(left)); assert!(right.prev() == Some(down));
Note that you can only derive either one of RotateEnum
or ShiftEnum
, but not both, because their semantics conflict.
Iterating
This crate also provides IterEnum
, which will implement Iterator
object
that yields enum variants in sequence. The first yield result will be the same
variant as the one started the iterator, i.e. Direction::Up.iter().next() == Some(Direction::Up)
.
let up = Direction::Up; let left = Direction::Left; let down = Direction::Down; let right = Direction::Right; let mut iter = up.iter(); assert!(iter.next() == Some(up)); assert!(iter.next() == Some(left)); assert!(iter.next() == Some(down)); assert!(iter.next() == Some(right)); assert!(iter.next() == None); assert_eq!(up.iter().collect::<Vec<_>>(), vec![up, left, down, right]);
Or, you could start from "YourEnum"Iterator::new()
.
assert_eq!(DirectionIterator::new().collect::<Vec<_>>(), vec![ Direction::Up, Direction::Left, Direction::Down, Direction::Right, ]);
Note that it is not the same as ShiftEnum
in the sense that the iterator is one-directional, which means you can go only forward and not prev()
.
It can also be used with iterator methods like collect()
.
IterEnum
also requires deriving Clone
.
Usage
Use #[derive(...)]
macro to annotate your enum.
use rotate_enum::RotateEnum; #[derive(RotateEnum)] enum Direction { Up, Left, Down, Right, }
Note
These macros seem trivial, but it's only possible with procedural macros!
Derive Macros
IterEnum | This derive macro will implement |
RotateEnum | This derive macro will implement |
ShiftEnum | This derive macro will implement |