#variant #enums #type #macro-derive

enum_variant_type

为每个枚举变体生成类型和转换特质实现

5个不稳定版本

0.3.1 2021年12月22日
0.3.0 2021年12月18日
0.2.1 2021年4月23日
0.2.0 2020年1月13日
0.1.0 2020年1月10日

#1993Proc宏

Download history 736/week @ 2024-03-14 1070/week @ 2024-03-21 1520/week @ 2024-03-28 1215/week @ 2024-04-04 992/week @ 2024-04-11 949/week @ 2024-04-18 1070/week @ 2024-04-25 1019/week @ 2024-05-02 1292/week @ 2024-05-09 1089/week @ 2024-05-16 834/week @ 2024-05-23 583/week @ 2024-05-30 1424/week @ 2024-06-06 702/week @ 2024-06-13 443/week @ 2024-06-20 245/week @ 2024-06-27

2,878 每月下载量

MIT/Apache

33KB
513

Crates.io docs.rs CI Coverage Status

枚举变体类型

从枚举变体生成结构的proc宏推导。

这是对https://github.com/rust-lang/rfcs/pull/2593的简化实现。

[dependencies]
enum_variant_type = "0.3.1"

示例

use enum_variant_type::EnumVariantType;

#[derive(Debug, EnumVariantType, PartialEq)]
pub enum MyEnum {
    /// Unit variant.
    #[evt(derive(Clone, Copy, Debug, PartialEq))]
    Unit,
    /// Tuple variant.
    #[evt(derive(Debug, PartialEq))]
    Tuple(u32, u64),
    /// Struct variant.
    #[evt(derive(Debug))]
    Struct { field_0: u32, field_1: u64 },
    /// Skipped variant.
    #[evt(skip)]
    Skipped,
}

// Now you can do the following:
use core::convert::TryFrom;
let unit: Unit = Unit::try_from(MyEnum::Unit).unwrap();
let tuple: Tuple = Tuple::try_from(MyEnum::Tuple(12, 34)).unwrap();
let named: Struct = Struct::try_from(MyEnum::Struct {
    field_0: 12,
    field_1: 34,
})
.unwrap();

let enum_unit = MyEnum::from(unit);
let enum_tuple = MyEnum::from(tuple);
let enum_struct = MyEnum::from(named);

// If the enum variant doesn't match the variant type, then the original variant is returned in
// the `Result`'s `Err` variant.
assert_eq!(Err(MyEnum::Unit), Tuple::try_from(MyEnum::Unit));
生成的代码
use core::convert::TryFrom;

/// Unit variant.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Unit;

/// Tuple variant.
#[derive(Debug, PartialEq)]
pub struct Tuple(pub u32, pub u64);

/// Struct variant.
#[derive(Debug)]
pub struct Struct {
    pub field_0: u32,
    pub field_1: u64,
}

impl From<Unit> for MyEnum {
    fn from(variant_struct: Unit) -> Self {
        MyEnum::Unit
    }
}

impl TryFrom<MyEnum> for Unit {
    type Error = MyEnum;
    fn try_from(enum_variant: MyEnum) -> Result<Self, Self::Error> {
        if let MyEnum::Unit = enum_variant {
            Ok(Unit)
        } else {
            Err(enum_variant)
        }
    }
}

impl From<Tuple> for MyEnum {
    fn from(variant_struct: Tuple) -> Self {
        let Tuple(_0, _1) = variant_struct;
        MyEnum::Tuple(_0, _1)
    }
}

impl TryFrom<MyEnum> for Tuple {
    type Error = MyEnum;
    fn try_from(enum_variant: MyEnum) -> Result<Self, Self::Error> {
        if let MyEnum::Tuple(_0, _1) = enum_variant {
            Ok(Tuple(_0, _1))
        } else {
            Err(enum_variant)
        }
    }
}

impl From<Struct> for MyEnum {
    fn from(variant_struct: Struct) -> Self {
        let Struct { field_0, field_1 } = variant_struct;
        MyEnum::Struct { field_0, field_1 }
    }
}

impl TryFrom<MyEnum> for Struct {
    type Error = MyEnum;
    fn try_from(enum_variant: MyEnum) -> Result<Self, Self::Error> {
        if let MyEnum::Struct { field_0, field_1 } = enum_variant {
            Ok(Struct { field_0, field_1 })
        } else {
            Err(enum_variant)
        }
    }
}

# pub enum MyEnum {
#     /// Unit variant.
#     Unit,
#     /// Tuple variant.
#     Tuple(u32, u64),
#     /// Struct variant.
#     Struct {
#         field_0: u32,
#         field_1: u64,
#     },
# }
#

由枚举上的evt属性指定的附加选项

  • #[evt(derive(Clone, Copy))]导出的CloneCopy在每一个变体上。
  • #[evt(module = "module1")]:生成的结构体被放置在mod module1 { ... }中。
  • #[evt(implement_marker_traits(MarkerTrait1))]:生成的结构体都实现了impl MarkerTrait1

许可证

许可协议为以下之一

任选其一。

贡献

除非您明确声明,否则根据 Apache-2.0 许可证定义的,您有意提交的、旨在包含在本作品中的任何贡献,将按上述方式双许可,不附加任何额外的条款或条件。

依赖项

~1.5MB
~37K SLoC