#枚举 #类型 #变体 #求和 #either

无需std sum_type

创建包装枚举的便捷宏,该枚举可以是几种不同类型之一

3个不稳定版本

使用旧的Rust 2015

0.2.0 2019年7月14日
0.1.1 2018年11月23日
0.1.0 2018年7月25日

2557Rust模式

Download history 189/week @ 2024-03-25 235/week @ 2024-04-01 179/week @ 2024-04-08 203/week @ 2024-04-15 192/week @ 2024-04-22 170/week @ 2024-04-29 174/week @ 2024-05-06 201/week @ 2024-05-13 203/week @ 2024-05-20 173/week @ 2024-05-27 137/week @ 2024-06-03 164/week @ 2024-06-10 175/week @ 2024-06-17 157/week @ 2024-06-24 98/week @ 2024-07-01 142/week @ 2024-07-08

599 每月下载量

MIT 许可证

17KB
221

sum_type

Build Status license Crates.io Docs.rs

创建包装枚举的便捷宏,该枚举可以是几种不同类型之一


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 查看。

无运行时依赖

功能