Proc macro derive to generate structs from enum variants.
This is a poor-man's implementation of rust-lang/rfcs#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));
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,
# },
# }
#
#[evt(derive(Clone, Copy))]
: DerivesClone
,Copy
on every variant.#[evt(module = "module1")]
: Generated structs are placed intomod module1 { ... }
.#[evt(implement_marker_traits(MarkerTrait1))]
: Generated structs allimpl MarkerTrait1
.
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
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.