Crate into_variant

Source
Expand description

§into_variant

Easily convert your types into the corresponding enum variant.

§Usage

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.

§Project Status

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.

Traits§

IntoVariant
Similar to Into, converts a value into an enum variant containing the value.
VariantFrom
Similar to From, creates an enum variant containing the specified value.

Derive Macros§

VariantFrom
Implements conversion from inner types into enum variants.