Crates.io | rotate-enum |
lib.rs | rotate-enum |
version | 0.1.2 |
source | src |
created_at | 2021-01-24 01:54:49.552439 |
updated_at | 2021-01-26 22:17:09.276571 |
description | A simple macro that implements prev() and next() methods to an enum |
homepage | |
repository | https://github.com/msakuta/rotate-enum |
max_upload_size | |
id | 345872 |
size | 19,330 |
Simple derive macros that implement prev()
and next()
methods to an enum in Rust
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.
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.
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]);
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
.
Use #[derive(...)]
macro to annotate your enum.
use rotate_enum::RotateEnum;
#[derive(RotateEnum)]
enum Direction {
Up,
Left,
Down,
Right,
}