#enum #variant #type

macro enum_variant_type

Generates types for each enum variant and conversion trait impls

5 unstable releases

0.3.1 Dec 22, 2021
0.3.0 Dec 18, 2021
0.2.1 Apr 23, 2021
0.2.0 Jan 13, 2020
0.1.0 Jan 10, 2020

#33 in #variant

Download history 994/week @ 2023-10-16 1004/week @ 2023-10-23 1084/week @ 2023-10-30 713/week @ 2023-11-06 799/week @ 2023-11-13 516/week @ 2023-11-20 887/week @ 2023-11-27 969/week @ 2023-12-04 1202/week @ 2023-12-11 736/week @ 2023-12-18 115/week @ 2023-12-25 538/week @ 2024-01-01 876/week @ 2024-01-08 654/week @ 2024-01-15 865/week @ 2024-01-22 1296/week @ 2024-01-29

3,744 downloads per month
Used in 4 crates (via ezno-parser)

MIT/Apache

33KB
513 lines

Crates.io docs.rs CI Coverage Status

Enum Variant Type

Proc macro derive to generate structs from enum variants.

This is a poor-man's implementation of https://github.com/rust-lang/rfcs/pull/2593.

[dependencies]
enum_variant_type = "0.3.1"

Examples

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));
Generated code
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,
#     },
# }
#

Additional options specified by an evt attribute on enum:

  • #[evt(derive(Clone, Copy))]: Derives Clone, Copy on every variant.
  • #[evt(module = "module1")]: Generated structs are placed into mod module1 { ... }.
  • #[evt(implement_marker_traits(MarkerTrait1))]: Generated structs all impl MarkerTrait1.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~1.5MB
~34K SLoC