3个不稳定版本
使用旧的Rust 2015
0.2.0 | 2019年7月14日 |
---|---|
0.1.1 | 2018年11月23日 |
0.1.0 | 2018年7月25日 |
2557 在 Rust模式 中
599 每月下载量
17KB
221 行
sum_type
创建包装枚举的便捷宏,该枚举可以是几种不同类型之一
lib.rs
:
创建包装枚举的便捷宏,该枚举可以是几种不同类型之一。在类型理论中,这通常被称为求和类型。
此包将支持 no_std
代码。
示例
使用 sum_type!()
宏相当简单。你只需在其中定义一个普通的 enum
,宏会自动添加一些有用的特质实现。
为了方便,所有属性都会传递,并且宏将为每个变体推导出 From
。
#[macro_use]
extern crate sum_type;
sum_type! {
#[derive(Debug, Clone, PartialEq)]
pub enum MySumType {
/// The first variant.
First(u32),
/// The second variant.
Second(String),
/// A list of bytes.
Third(Vec<u8>),
}
}
let first: MySumType = 52.into();
assert_eq!(first, MySumType::First(52));
你也可以偷懒,省略变体名称。这会将变体的名称与它的类型相同。
sum_type!{
pub enum Lazy {
f32, u32, String,
}
}
let s = Lazy::String("Hello World!".to_string());
SumType
特质也得到了实现,允许基本的反射和动态类型。
use sum_type::SumType;
let first = MySumType::First(52);
assert_eq!(first.variant(), "First");
assert_eq!(first.variants(), &["First", "Second", "Third"]);
assert!(first.variant_is::<u32>());
assert_eq!(first.downcast_ref::<u32>(), Some(&52));
假设
你需要确保你的类型有多个变体,这意味着以下示例将无法编译。
#[macro_use]
extern crate sum_type;
sum_type!{
pub enum OneVariant {
First(String),
}
}
使用 compile_error!()
宏提供(希望)有用的错误信息。
error: The `OneVariant` type must have more than one variant
--> src/lib.rs:37:1
|
7 | / sum_type!{
8 | | pub enum OneVariant {
9 | | First(String),
10 | | }
11 | | }
| |_^
|
= note: this error originates in a macro outside of the current crate
包含泛型(包括生命周期)或使用可见性修饰符(例如 pub(crate)
)的求和类型(尚不支持)。这意味着这会失败
sum_type!{
TypeWithLifetime<'a> {
First(&'a str),
Second(usize),
}
}
同样,这也会失败
sum_type!{
pub(crate) ModifiedVisibility {
First(u32),
Second(String),
}
}
尝试From
TryFrom
自动在您的求和类型上实现,以将其转换回其变体类型之一。
#[macro_use]
extern crate sum_type;
use std::convert::TryFrom;
let first = MySumType::First(52);
let as_u32 = u32::try_from(first);
assert_eq!(as_u32, Ok(52));
let second = MySumType::Second(String::from("Not a Vec<u8>"));
let as_vec_u8 = Vec::<u8>::try_from(second);
assert!(as_vec_u8.is_err());
let err = as_vec_u8.unwrap_err();
assert_eq!(err.expected_variant, "Third");
assert_eq!(err.actual_variant, "Second");
启用 generated_example
功能标志将创建一个 MySumType
的示例,可以使用 rustdoc
查看。