| Crates.io | enum_convert |
| lib.rs | enum_convert |
| version | 0.2.0 |
| created_at | 2025-08-15 18:35:49.950997+00 |
| updated_at | 2025-09-24 16:35:58.170426+00 |
| description | A Rust procedural macro library for deriving automatic conversions between enum variants |
| homepage | |
| repository | https://github.com/avandecreme/enum_convert |
| max_upload_size | |
| id | 1797290 |
| size | 133,735 |
Crate to derive From implementations between enums.
From<Source> for AnnotatedEnumFrom<AnnotatedEnum> for Target.into()use enum_convert::EnumFrom;
enum Source {
Unit,
Tuple(i32, String),
Struct { x: i32, y: i32 },
}
#[derive(EnumFrom)]
#[enum_from(Source)]
enum Target {
#[enum_from] // Maps from Source::Unit
Unit,
#[enum_from] // Maps from Source::Tuple with type conversion
Tuple(i64, String),
#[enum_from] // Maps from Source::Struct with type conversion
Struct { x: f64, y: f64 },
Extra, // This variant has no mapping
}
// Usage
let source = Source::Tuple(42, "hello".to_string());
let target: Target = source.into();
ℹ️ While the macro is named EnumInto, it still implements From<AnnotatedEnum> for TargetEnum and thus has an indirect implementation of Into as recommended by the docs.
This is similar to derive_more's Into.
use enum_convert::EnumInto;
#[derive(EnumInto)]
#[enum_into(Target)]
enum Source {
Unit, // Maps to Target::Unit
#[enum_into(Target::Different)] // Maps to Target::Different
Variant(i32),
}
enum Target {
Unit,
Different(i64),
Extra,
}
// Usage
let source = Source::Variant(42);
let target: Target = source.into();
use enum_convert::EnumFrom;
enum FirstSource {
Unit,
Data(String),
}
enum SecondSource {
Empty,
}
#[derive(EnumFrom)]
#[enum_from(FirstSource, SecondSource)]
enum Target {
#[enum_from(FirstSource, SecondSource::Empty)]
Unit,
#[enum_from(FirstSource)]
Data(String),
}
use enum_convert::EnumFrom;
enum Source {
Tuple(String, u8),
Record {
name: String,
value: i32,
},
Point(i32, i32),
}
#[derive(EnumFrom)]
#[enum_from(Source)]
enum Target {
#[enum_from]
Tuple(
// We effectively re-order fields
#[enum_from(Source::Tuple.1)] u8,
#[enum_from(Source::Tuple.0)] String,
),
#[enum_from]
Record {
#[enum_from(Source::Record.name)] // Maps Source::Record.name to Target::Record.title
title: String,
value: i32,
},
#[enum_from]
Point {
#[enum_from(Source::Point.0)]
x: i64,
#[enum_from(Source::Point.1)]
y: i64,
},
}
This crate has some similarities with derive_more's From and Into derive macros.
The difference is that with derive_more the conversion is field → variant (From) and variant → field (Into); with this crate it is variant ↔ variant.
#[derive(derive_more::From, enum_convert::EnumFrom)]
#[enum_from(OtherEnum)]
enum MyEnum {
#[enum_from]
Variant1(i32),
}
enum OtherEnum {
Variant1(i32),
}
// `derive_more::From` get expanded to
impl From<i32> for MyEnum {
fn from(value: i32) -> MyEnum {
MyEnum::Variant1(value)
}
}
// `enum_convert::EnumFrom` get expanded to
impl From<OtherEnum> for MyEnum {
fn from(value: OtherEnum) -> MyEnum {
match value {
OtherEnum::Variant1(i) => MyEnum::Variant1(i),
}
}
}
This crate is very similar to enum_to_enum.
At the time of writing (enum_to_enum in version 0.1.0) the differences are:
enum_convert does not support many-to-one conversion with try_into logic .enum_convert does not support effectful conversion.enum_to_enum does not support EnumInto.enum_to_enum does not support having variants in the target for which there is no mapping from source.enum_to_enum does not support fields mapping.For the common features, here is a comparison of how they are expressed in both crates:
enum SourceA {
Unit,
Tuple(i32, String),
Struct { x: i32, y: i32 },
}
enum SourceB {
Unit,
NoField,
Tuple(i32, String),
Struct { x: i32, y: i32 },
}
#[derive(enum_to_enum::FromEnum)]
#[from_enum(SourceA, SourceB)]
enum TargetEnumToEnum {
#[from_case(SourceB = NoField, Unit)]
Unit,
Tuple(i64, String),
Struct { x: f64, y: f64 },
}
#[derive(enum_convert::EnumFrom)]
#[enum_from(SourceA, SourceB)]
enum TargetEnumConvert {
#[enum_from(SourceA, SourceB::Unit, SourceB::NoField)]
Unit,
#[enum_from(SourceA, SourceB)]
Tuple(i64, String),
#[enum_from(SourceA, SourceB)]
Struct { x: f64, y: f64 },
}
The subenum crate allows to implement easily subset of enums with conversion between parent and child.
However, there are cases where it is not desirable or possible to use subenum.
For example: