https://github.com/azriel91/enum_variant_type
Proc macro derive to generate structs from enum variants.
https://github.com/azriel91/enum_variant_type
derive enum proc-macro rust
Last synced: 11 months ago
JSON representation
Proc macro derive to generate structs from enum variants.
- Host: GitHub
- URL: https://github.com/azriel91/enum_variant_type
- Owner: azriel91
- Created: 2020-01-10T06:37:56.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2023-06-27T04:42:06.000Z (over 2 years ago)
- Last Synced: 2025-03-16T07:22:50.296Z (11 months ago)
- Topics: derive, enum, proc-macro, rust
- Language: Rust
- Size: 45.9 KB
- Stars: 28
- Watchers: 3
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
[](https://crates.io/crates/enum_variant_type)
[](https://docs.rs/enum_variant_type)
[](https://github.com/azriel91/enum_variant_type/actions/workflows/ci.yml)
[](https://codecov.io/gh/azriel91/enum_variant_type)
# Enum Variant Type
Proc macro derive to generate structs from enum variants.
This is a poor-man's implementation of .
```toml
[dependencies]
enum_variant_type = "0.3.1"
```
## Examples
```rust,edition2018
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
```rust,edition2018
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 for MyEnum {
fn from(variant_struct: Unit) -> Self {
MyEnum::Unit
}
}
impl TryFrom for Unit {
type Error = MyEnum;
fn try_from(enum_variant: MyEnum) -> Result {
if let MyEnum::Unit = enum_variant {
Ok(Unit)
} else {
Err(enum_variant)
}
}
}
impl From for MyEnum {
fn from(variant_struct: Tuple) -> Self {
let Tuple(_0, _1) = variant_struct;
MyEnum::Tuple(_0, _1)
}
}
impl TryFrom for Tuple {
type Error = MyEnum;
fn try_from(enum_variant: MyEnum) -> Result {
if let MyEnum::Tuple(_0, _1) = enum_variant {
Ok(Tuple(_0, _1))
} else {
Err(enum_variant)
}
}
}
impl From for MyEnum {
fn from(variant_struct: Struct) -> Self {
let Struct { field_0, field_1 } = variant_struct;
MyEnum::Struct { field_0, field_1 }
}
}
impl TryFrom for Struct {
type Error = MyEnum;
fn try_from(enum_variant: MyEnum) -> Result {
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
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
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.