4 个版本
使用旧的 Rust 2015
0.1.7 | 2016 年 8 月 3 日 |
---|---|
0.1.3 | 2015 年 12 月 1 日 |
0.1.2 | 2015 年 9 月 16 日 |
0.1.1 | 2015 年 8 月 16 日 |
1802 在 Rust 模式
11,471 每月下载量
用于 31 个软件包(其中 13 个直接使用)
30KB
678 行
本软件包提供了一些宏,用于派生一些针对单元枚举(即,变体没有有效负载的枚举)的有用方法。
所有这些宏都是为与 custom_derive
软件包一起使用而设计的,尽管它们可以在不依赖它的前提下使用。
注意:还可以查看
conv
软件包提供的TryFrom!
宏,用于从整数值派生创建枚举值的功能。
示例
派生迭代器,返回枚举的所有变体。
#[macro_use] extern crate custom_derive;
#[macro_use] extern crate enum_derive;
custom_derive! {
#[derive(Debug, PartialEq, Eq,
IterVariants(CandyVariants), IterVariantNames(CandyVariantNames))]
pub enum Candy { Musk, FruitRock, BoPeeps, LemonSherbert }
}
let vars: CandyVariants = Candy::iter_variants();
let names: CandyVariantNames = Candy::iter_variant_names();
assert_eq!(&*vars.zip(names).collect::<Vec<_>>(), &[
(Candy::Musk, "Musk"),
(Candy::FruitRock, "FruitRock"),
(Candy::BoPeeps, "BoPeeps"),
(Candy::LemonSherbert, "LemonSherbert"),
]);
或者,派生 next_variant
和 prev_variant
方法。
#[macro_use] extern crate custom_derive;
#[macro_use] extern crate enum_derive;
use Hanagami::*;
custom_derive! {
#[derive(Debug, PartialEq, Eq, NextVariant, PrevVariant)]
pub enum Hanagami { Sakigami, Hasugami, Tsutagami }
}
assert_eq!(Sakigami.next_variant(), Some(Hasugami));
assert_eq!(Hasugami.next_variant(), Some(Tsutagami));
assert_eq!(Tsutagami.next_variant(), None);
assert_eq!(Sakigami.prev_variant(), None);
assert_eq!(Hasugami.prev_variant(), Some(Sakigami));
assert_eq!(Tsutagami.prev_variant(), Some(Hasugami));
概述
本软件包提供宏以派生以下单元变体枚举的方法
EnumDisplay
派生Display
,输出变体的名称。注意,对于单元变体,这与派生的Debug
实现的行为相同。EnumFromStr
派生FromStr
,允许使用str::parse
。它需要变体名称的精确匹配。IterVariants
派生iter_variants()
,返回一个迭代器,按词典顺序遍历枚举的变体。IterVariantNames
派生iter_variant_names()
,返回一个迭代器,按词典顺序遍历枚举变体的字符串名称。NextVariant
派生next_variant(&self)
,返回下一个变体,或者当调用最后一个时返回None
。PrevVariant
继承了prev_variant(&self)
,它返回前一个变体,或者在第一次调用时返回None
。EnumFromInner
为每个变体的有效负载继承From<T>
,假设所有变体都是一元。EnumInnerAsTrait
继承了一个方法,用于返回一个指向内部值的借用指针,并将其转换为特质对象。
这两个 IterVariant*
宏都接受一个继承形式。以 IterVariants
为例,它必须如下调用
custom_derive! {
#[derive(IterVariants(GetVariants))]
pub enum Get { Up, Down, AllAround }
}
参数是生成的迭代器类型的名称。这两个宏都不强制命名要求,除了明显的:名称不能与其他任何类型冲突。
EnumInnerAsTrait
接受一个继承形式,指定要继承的方法的名称、借用是否可变以及感兴趣的特质。例如
custom_derive! {
#[derive(EnumInnerAsTrait(pub as_display -> &std::fmt::Display))]
enum Value {
U32(u32),
U64(u64),
}
}
let s = format!("{}", Value::U64(42).as_display());
assert_eq!(&s[..], "42");
其他宏不接受任何参数。
生成的方法和迭代器类型如果是公有的,则将是公开的;否则,它们将是私有的。
使用 custom_derive!
之外的方法
尽管设计为与 custom_derive!
一起使用,但这个crate中的所有宏都可以不使用它来使用。以下
custom_derive! {
#[derive(Copy, Clone, Debug, IterVariants(Vars))]
enum ItAintRight { BabeNo, NoNo, BoyBoy }
}
也可以写成这样
#[derive(Copy, Clone, Debug)]
enum ItAintRight { BabeNo, NoNo, BoyBoy }
IterVariants! { (Vars) enum ItAintRight { BabeNo, NoNo, BoyBoy } }
其他示例
这显示了如何使用 Display
和 FromStr
来执行枚举的字符串往返。
#[macro_use] extern crate custom_derive;
#[macro_use] extern crate enum_derive;
custom_derive! {
#[derive(Debug, PartialEq, EnumDisplay, EnumFromStr)]
pub enum TrollDigit { One, Two, Three, Many, Lots }
}
fn to_troll(mut n: u32) -> String {
use std::fmt::Write;
let mut s = String::new();
if n == 0 {
panic!("I dun' see nuffin'; how's I s'posed to count it?!");
}
while n > 0 {
let (del, dig) = match n {
n if n >= 16 => (16, TrollDigit::Lots),
n if n >= 4 => (4, TrollDigit::Many),
n if n >= 3 => (3, TrollDigit::Three),
n if n >= 2 => (2, TrollDigit::Two),
_ => (1, TrollDigit::One),
};
n -= del;
if s.len() > 0 { s.push_str(" "); }
write!(&mut s, "{}", dig).unwrap();
}
s
}
fn from_troll(s: &str) -> Result<u32, enum_derive::ParseEnumError> {
let mut n = 0;
for word in s.split_whitespace() {
n += match try!(word.parse()) {
TrollDigit::One => 1,
TrollDigit::Two => 2,
TrollDigit::Three => 3,
TrollDigit::Many => 4,
TrollDigit::Lots => 16,
};
}
if n == 0 {
Err(enum_derive::ParseEnumError)
} else {
Ok(n)
}
}
let number = 42;
let troll_number = to_troll(number);
assert_eq!(troll_number, "Lots Lots Many Many Two");
assert_eq!(from_troll(&troll_number), Ok(number));