#枚举 #旋转 #方法 #下一个 # #方向 #上一个

rotate-enum

一个简单的宏,为枚举实现prev()和next()方法

3个版本

0.1.2 2021年1月26日
0.1.1 2021年1月25日
0.1.0 2021年1月24日

#1015 in 过程宏

MIT 许可证

16KB
118

Rust

rotate-enum 包

简单的派生宏,为Rust中的枚举实现prev()和next()方法

动机

有时你定义一个枚举,如下所示

enum Direction {
    Up,
    Left,
    Down,
    Right,
}

并希望在某种逻辑中旋转它们

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);

当然,你可以手动实现这些方法,但这很重复且容易出错。你不认为应该自动化吗?这个crate提供了一个RotateEnum派生宏来完成这项工作。

移位

这个crate还提供了ShiftEnum,它会在枚举列表的末尾耗尽,而不是旋转。

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));

请注意,你只能派生RotateEnumShiftEnum中的一个,而不能同时派生两个,因为它们的语义冲突。

迭代

这个crate还提供了IterEnum,它将实现一个Iterator对象,按顺序生成枚举变体。第一个生成结果是开始迭代时的同一变体,即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]);

请注意,这与ShiftEnum不同,因为迭代器是单向的,这意味着你可以向前移动,但不能prev()。它也可以与迭代器方法(如collect())一起使用。

IterEnum还需要派生Clone

用法

使用 #[derive(...)] 宏来注解您的枚举。

use rotate_enum::RotateEnum;

#[derive(RotateEnum)]
enum Direction {
    Up,
    Left,
    Down,
    Right,
}

依赖关系

~1.5MB
~35K SLoC