#named-fields #mapping #convert #derive #traits-structs #map #from

structural-convert

Derive conversion traits (From, Into, TryFrom, TryInto) when fields are structurally similar in enums or structs

17 releases (breaking)

0.13.0 Mar 11, 2024
0.11.0 Mar 10, 2024

#629 in Rust patterns

Download history 1794/week @ 2024-07-21 3139/week @ 2024-07-28 2386/week @ 2024-08-04 1770/week @ 2024-08-11 2109/week @ 2024-08-18 1981/week @ 2024-08-25 1940/week @ 2024-09-01 2398/week @ 2024-09-08 1442/week @ 2024-09-15 2386/week @ 2024-09-22 842/week @ 2024-09-29 1692/week @ 2024-10-06 1974/week @ 2024-10-13 1273/week @ 2024-10-20 813/week @ 2024-10-27 2122/week @ 2024-11-03

6,322 downloads per month

MIT license

21KB
327 lines

structural-convert

Derive conversion traits when items are structurally similar.

Inspired by serde and struct-convert crates.

Features

  • One to one fields mapping derive for
    • From
    • Into
    • TryFrom
    • TryInto
  • Inner fields type conversion using .into()/.try_into()
  • Rename enum variants and named fields
  • Skip enum variants and named fields
  • Fallback to default enum variant
  • Named fields conversion fallback to default
  • Enum not matched variants fallback to enum default
  • Struct named fields only - Middle man type conversion using as attribute
  • handles std types:
    • Option
    • Result
    • types from std::collections like Vec, HashMap, etc...

Features Wishlist

  • Implement attributes for unnamed fields (default, skip, as)
  • Handle Type to Option<Type>
  • Add more data on try error and provide ability to inject your own error type

Examples

Check the tests folder for more examples, but here is some samples:

Struct

#[derive(Debug, PartialEq)]
struct Rhs {
    z: i8,
    x: u32,
}

#[derive(Debug, PartialEq, StructuralConvert)]
#[convert(from(Rhs))]
struct Lhs {
    z: i32,
    x: u32,
}

assert_eq!(Lhs { z: 1, x: 2 }, Rhs { z: 1, x: 2 }.into());
assert_eq!(Lhs { z: 1, x: 2 }, Rhs { z: 1, x: 2 }.into());

Generated code:

impl From<Rhs> for Lhs {
    fn from(value: Rhs) -> Self {
        match value {
            Rhs { z, x } => Lhs {
                z: z.into(),
                x: x.into(),
            },
        }
    }
}

Enum

    #[derive(Debug, PartialEq)]
    enum Rhs {
        A { z: i8, x: u32 },
    }

    #[derive(Debug, PartialEq, StructuralConvert)]
    #[convert(from(Rhs))]
    enum Lhs {
        A { z: i32, x: u32 },
    }

    assert_eq!(Lhs::A { z: 1, x: 2 }, Rhs::A { z: 1, x: 2 }.into());

Generated code:

impl From<Rhs> for Lhs {
    fn from(value: Rhs) -> Self {
        match value {
            Rhs::A { z, x } => Lhs::A {
                z: z.into(),
                x: x.into(),
            },
        }
    }
}

Dependencies

~2MB
~44K SLoC