into_variant 0.1.1

Easily convert your types into the corresponding enum variant
Documentation

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 could have various kinds of app messages:

enum AppMessage {
    SaveMessage(SaveMessage),
    EditorMessage(EditorMessage),
}

struct SaveMessage {
    overwrite: bool,
}

Now, you'll probably want to construct an app message. To do this, you'd have to type:

fn main() {
    let save_message = SaveMessage{overwrite: true};
    let message = AppMessage::SaveMessage(save_message);
}

But you'll notice that a part of this is actually redundant – if we want to create an AppMessage with a payload of SaveMessage{overwrite: true}, we can infer that the enum type should be AppMessage::SaveMessage. Why type this out?

With this crate, just slap derive(VariantFrom) on your enums, and you can automatically convert values to the corresponding enum variant:

use into_variant::{IntoVariant, VariantFrom};

#[derive(VariantFrom, PartialEq)]
enum AppMessage {
    SaveMessage(SaveMessage),
    EditorMessage(EditorMessage),
}

#[derive(PartialEq)]
struct SaveMessage {
    overwrite: bool,
}

#[test]
fn test_from_save_message() {
    let save_message = SaveMessage { overwrite: true };

    let app_message: AppMessage = save_message.into_variant();
    assert!(app_message == AppMessage::SaveMessage(SaveMessage { overwrite: true }))
}

So instead of writing AppMessage::SaveMessage(save_message), we have save_message.into_variant() (the type AppMessage can be inferred in most cases, such as function parameters). But wait, it gets better!

Nested enums

Sometimes, you want to have a hierarchy of message types – with enum variant fields being other enums – and that's when into_enum gets really useful. Continuing from our previous example, suppose you have:


#[derive(VariantFrom, PartialEq)]
enum EditorMessage {
    Insert(InsertMessage),
    Formatting(FormattingMessage),
}

#[derive(VariantFrom, PartialEq)]
enum FormattingMessage {
    ClearFormatting(ClearFormattingMessage),
    // etc, whatever...
}

#[derive(PartialEq)]
struct ClearFormattingMessage {}

#[test]
fn test_from_clear_formatting() {
    let clear_formatting = ClearFormattingMessage {};

    let app_message: AppMessage = clear_formatting.into_variant();

    let expected = AppMessage::EditorMessage(EditorMessage::Formatting(
        FormattingMessage::ClearFormatting(ClearFormattingMessage {}),
    ));
    assert!(app_message == expected)
}

So instead of AppMessage::EditorMessage(EditorMessage::Formatting(FormattingMessage::ClearFormatting(clear_formatting))), all you need is clear_formatting.into_variant()!

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.