Crates.io | into_variant |
lib.rs | into_variant |
version | 0.3.0 |
source | src |
created_at | 2022-04-06 19:44:10.792068 |
updated_at | 2022-05-14 12:11:33.12096 |
description | Easily convert your types into the corresponding enum variant |
homepage | |
repository | https://gitlab.com/dawn_best/into_variant |
max_upload_size | |
id | 563317 |
size | 15,721 |
Easily convert your types into the corresponding enum variant.
Commonly in Rust, you'll have enum variants with a single field – such enums let you differentiate between different types of values. For example, you might have a hierarchy of possible app messages:
use into_variant::VariantFrom;
#[derive(VariantFrom)]
enum AppMessage {
File(FileMessage),
Editor(EditorMessage),
}
#[derive(VariantFrom)]
enum FileMessage {
Save(SaveMessage),
Close(CloseMessage),
}
#[derive(VariantFrom)]
enum EditorMessage {
Insert(InsertMessage),
Formatting(FormattingMessage),
}
struct SaveMessage {}
struct CloseMessage {}
struct InsertMessage {}
Normally, if you wanted to construct one of these messages, you'd have to type a long chain of nested enums:
AppMessage::File(FileMessage::Save(SaveMessage {}))
// ^^^^^^^^^^^^^^^^^^^^^^^^ this bit is redundant, let's infer it automatically!
However, since there is only one way to create an AppMessage
with a SaveMessage
inside, we can infer the enum variants automatically – that's what this crate is for!
#[test]
fn test_variant_from() {
assert!(matches!(
AppMessage::variant_from(SaveMessage {}),
AppMessage::File(FileMessage::Save(SaveMessage {}))
));
assert!(matches!(
AppMessage::variant_from(InsertMessage {}),
AppMessage::Editor(EditorMessage::Insert(InsertMessage {}))
));
}
You also get into_variant
, which gets even shorter if AppMessage
can be inferred too – for example, in function calls:
#[test]
fn test_into_variant() {
function_that_takes_app_message(SaveMessage {}.into_variant())
}
fn function_that_takes_app_message(_message: AppMessage) {}
Works for arbitrarily deeply nested enums!
#[derive(VariantFrom)]
enum FormattingMessage {
ClearFormatting(ClearFormattingMessage),
}
struct ClearFormattingMessage {}
#[test]
fn test_deeper_nesting() {
assert!(matches!(
AppMessage::variant_from(ClearFormattingMessage {}),
AppMessage::Editor(EditorMessage::Formatting(
FormattingMessage::ClearFormatting(ClearFormattingMessage {})
))
))
}
You can find the full example, along with others, in tests/app_message.rs
.
I needed this for a thing, so it might get maintained for a while. Suggestions are appreciated, but I can't guarantee I'll address them.