#enums #derive #single #fields #try-into #convert #variant

macro derive-enum-from-into

Derive for From and TryInto for enums with single fields

3 unstable releases

0.2.0 Mar 1, 2024
0.1.1 Jan 18, 2022
0.1.0 Jan 3, 2022

#2052 in Rust patterns

Download history 1479/week @ 2024-01-05 2302/week @ 2024-01-12 1772/week @ 2024-01-19 1759/week @ 2024-01-26 881/week @ 2024-02-02 1406/week @ 2024-02-09 1184/week @ 2024-02-16 2047/week @ 2024-02-23 2269/week @ 2024-03-01 2221/week @ 2024-03-08 2582/week @ 2024-03-15 1853/week @ 2024-03-22 2181/week @ 2024-03-29 2437/week @ 2024-04-05 2353/week @ 2024-04-12 1573/week @ 2024-04-19

8,787 downloads per month
Used in 5 crates (3 directly)

MIT license

19KB
399 lines

Derive enum from try into

Implements From and TryInto for enums

use derive_enum_from_into::{EnumFrom, EnumTryInto};
use std::convert::TryInto;

#[derive(EnumFrom, EnumTryInto, PartialEq, Debug)]
enum Enum1 {
    A(i32),
    B,
}

assert_eq!(
    Enum1::from(54i32),
    Enum1::A(54i32)
);

let num: Result<i32, _> = Enum1::B.try_into();
assert!(num.is_err());

Ignores variants with duplicate type definitions or named fields

use derive_enum_from_into::{EnumFrom, EnumTryInto};
use std::convert::TryInto;

#[derive(EnumFrom, EnumTryInto, PartialEq, Debug)]
enum Enum1 {
    A(String),
    B(String),
    C { 
        something: bool 
    },
}

// Results in compile errors
let enum1: Result<String, _> = Enum1::A("Hello".to_owned()).try_into();
let enum1: Result<bool, _> = (Enum1::C { something: true }).try_into();

From can be ignored for variants with #[from_ignore]

TryInto can also be implemented for references of the enum. Specific variants can be ignored with #[try_into_ignore]

use derive_enum_from_into::{EnumFrom, EnumTryInto};
use std::convert::TryInto;

#[derive(EnumTryInto, PartialEq, Debug)]
#[try_into_references(&, &mut, owned)]
enum NumberOrString {
    Number(f32),
    #[try_into_ignore]
    String(String)
}

let x = NumberOrString::Number(4.);
assert_eq!(TryInto::<&f32>::try_into(&x), Ok(&4.));

// This won't compile as cannot TryInto String
// assert!(TryInto::<String>::try_into(NumberOrString::String("Hello World".to_owned())).is_err());

// `TryInto` comes in handy for `filter_map` cases
fn filter_only_f32s(iter: impl Iterator<Item=NumberOrString>) -> impl Iterator<Item=f32> {
    iter.filter_map(|item| item.try_into().ok())
}

// `TryInto` returns `self` if it does not match
assert_eq!(TryInto::<f32>::try_into(NumberOrString::String("Hello World".to_owned())), Err(NumberOrString::String("Hello World".to_owned())));

Note that because of the default implementation of TryInto the following will not compile. There are workarounds with wrapping X in a newtype pattern

#[derive(derive_enum_from_into::EnumTryInto)]
enum X {
    Leaf(i32),
    Nested(X)
}

Dependencies

~0.4–0.8MB
~20K SLoC