Skip to main content

TryFromStructural

Trait TryFromStructural 

Source
pub trait TryFromStructural<T>: Sized {
    type Error;

    // Required method
    fn try_from_structural(
        from: T,
    ) -> Result<Self, TryFromError<T, Self::Error>>;
}
Expand description

For fallible conversions between structural types.

Usually conversions between enums require the from enum to have at least the fields and variants of the into enum.

All the examples in this crate are for enums, since converting from an enum to another with a subset of the variants in the first is the motivating usecase for defining this trait.

§Implementations

§Enums

This trait is usually implemented for enums by:

  • Bounding the trait’s type parameter with the *_SI structural alias generated for the enum by the Structural derive.

  • Matching on all the variants of the enum with the switch macro, returning Ok with a variant if the parameter matches that enum variant. If the parameter doesn’t match any of the enum variants,an error is returned.

§Enum Examples

§Derived

This example demonstrates how this trait can be derived.

use structural::{
    convert::{EmptyTryFromError, TryFromError},
    for_examples::{Enum3, Enum4},
    Structural, StructuralExt, switch,
};

use std::cmp::Ordering;

assert_eq!(
    Enum3::Foo(3, 5).try_into_struc::<Variants>(),
    Ok(Variants::Foo(3)),
);
assert_eq!(
    Enum3::Bar(Ordering::Less, None).try_into_struc::<Variants>(),
    Ok(Variants::Bar),
);
assert_eq!(
    Enum3::Baz{foom: "hi"}.try_into_struc::<Variants>(),
    Ok(Variants::Baz{foom: "hi"}),
);

let qux=Enum4::Qux { uh: [0; 4], what: (false, false) };
assert_eq!(
    qux.try_into_struc::<Variants>(),
    Err(TryFromError::with_empty_error(qux)),
);


#[derive(Structural, Copy, Clone, Debug, PartialEq)]
// This attribute tells the `Structural` derive to generate the
// `TryFromStructural` and `FromStructural` impls
#[struc(from_structural)]
enum Variants {
    Foo(u8),
    Bar,
    Baz { foom: &'static str },
}

  

§Semi-manual impl

This example demonstrates how this trait can be implemented with the z_impl_try_from_structural_for_enum macro.

use structural::{
    convert::{EmptyTryFromError, TryFromError},
    for_examples::{Enum3, Enum4},
    Structural, StructuralExt, switch,
};

use std::cmp::Ordering;

assert_eq!(
    Enum3::Foo(3, 5).try_into_struc::<Variants>(),
    Ok(Variants::Foo(3)),
);
assert_eq!(
    Enum3::Bar(Ordering::Less, None).try_into_struc::<Variants>(),
    Ok(Variants::Bar),
);
assert_eq!(
    Enum3::Baz{foom: "hi"}.try_into_struc::<Variants>(),
    Ok(Variants::Baz{foom: "hi"}),
);

let qux=Enum4::Qux { uh: [0; 4], what: (false, false) };
assert_eq!(
    qux.try_into_struc::<Variants>(),
    Err(TryFromError::with_empty_error(qux)),
);


#[derive(Structural, Copy, Clone, Debug, PartialEq)]
enum Variants {
    Foo(u8),
    Bar,
    Baz { foom: &'static str },
}

// This macro implements FromStructural in terms of TryFromStructural,
//
// In order to implement FromStructural,
// this macro assumes that the TryFromStructural implementation written by users:
//   - Matches on all the variants of the enum
//   - Returns `Ok` for all the variants of the enum that were matches by name.
structural::z_impl_try_from_structural_for_enum!{
    impl[F] TryFromStructural<F> for Variants
    // `Variants_SI` was generated by the `Structural` derive for `Variants`
    // aliasing its accessor trait impls,
    // and allows `F` to have more variants than `Foo`,`Bar`,and `Baz`.
    where[ F: Variants_SI, ]
    {
        type Error = EmptyTryFromError;

        fn try_from_structural(this){
            switch! {this;
                Foo(x) => Ok(Self::Foo(x)),
                Bar => Ok(Self::Bar),
                Baz{foom} => Ok(Self::Baz{foom}),
                _ => Err(TryFromError::with_empty_error(this)),
            }
        }
    }

    // `Variants_ESI` was generated by the `Structural` derive for `Variants`
    // aliasing its accessor trait impls,
    // and requires `F` to only have the `Foo`,`Bar`,and `Baz` variants.
    FromStructural
    where[ F: Variants_ESI, ]
}
  

§Example: Manual implementation

use structural::{
    convert::{EmptyTryFromError, FromStructural, TryFromError, TryFromStructural},
    for_examples::{Enum3, Enum4},
    Structural, StructuralExt, switch,
};

use std::cmp::Ordering;

assert_eq!(
    Enum3::Foo(3, 5).try_into_struc::<Variants>(),
    Ok(Variants::Foo(3)),
);
assert_eq!(
    Enum3::Bar(Ordering::Less, None).try_into_struc::<Variants>(),
    Ok(Variants::Bar),
);
assert_eq!(
    Enum3::Baz{foom: "hi"}.try_into_struc::<Variants>(),
    Ok(Variants::Baz{foom: "hi"}),
);

let qux=Enum4::Qux { uh: [0; 4], what: (false, false) };
assert_eq!(
    qux.try_into_struc::<Variants>(),
    Err(TryFromError::with_empty_error(qux)),
);


#[derive(Structural, Copy, Clone, Debug, PartialEq)]
enum Variants {
    Foo(u8),
    Bar,
    Baz { foom: &'static str },
}
  
impl<F> FromStructural<F> for Variants
where
    // `Variants_ESI` was generated by the `Structural` derive for `Variants`
    // aliasing its accessor trait impls,
    // and requires `F` to only have the `Foo`,`Bar`,and `Baz` variants.
    F: Variants_ESI,
{
    fn from_structural(this: F) -> Self {
        switch! {this;
            Foo(x) => Self::Foo(x),
            Bar => Self::Bar,
            Baz{foom} => Self::Baz{foom},
        }
    }
}

impl<F> TryFromStructural<F> for Variants
where
    // `Variants_SI` was generated by the `Structural` derive for `Variants`
    // aliasing its accessor trait impls,
    // and allows `F` to have more variants than `Foo`,`Bar`,and `Baz`.
    F: Variants_SI,
{
    type Error = EmptyTryFromError;

    fn try_from_structural(this: F) -> Result<Self, TryFromError<F, Self::Error>> {
        switch! {this;
            Foo(x) => Ok(Self::Foo(x)),
            Bar => Ok(Self::Bar),
            Baz{foom} => Ok(Self::Baz{foom}),
            _ => Err(TryFromError::with_empty_error(this)),
        }
    }
}
  

Required Associated Types§

Source

type Error

The error parameter of TryFromError, returned from try_into_structural on conversion error.

Required Methods§

Source

fn try_from_structural(from: T) -> Result<Self, TryFromError<T, Self::Error>>

Performs the conversion

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<F, T> TryFromStructural<F> for Option<T>
where F: OptionMove_SI<T>,

Source§

impl<F, T> TryFromStructural<F> for Range<T>
where F: IntoField<TStr<__TS<(__s, __t, __a, __r, __t)>>, Ty = T> + IntoField<TStr<__TS<(__e, __n, __d)>>, Ty = T>,

Source§

impl<F, T> TryFromStructural<F> for RangeFrom<T>
where F: IntoField<TStr<__TS<(__s, __t, __a, __r, __t)>>, Ty = T>,

Source§

impl<F, T> TryFromStructural<F> for RangeInclusive<T>
where F: IntoField<TStr<__TS<(__s, __t, __a, __r, __t)>>, Ty = T> + IntoField<TStr<__TS<(__e, __n, __d)>>, Ty = T>,

Source§

impl<F, T> TryFromStructural<F> for RangeTo<T>
where F: IntoField<TStr<__TS<(__e, __n, __d)>>, Ty = T>,

Source§

impl<F, T> TryFromStructural<F> for RangeToInclusive<T>
where F: IntoField<TStr<__TS<(__e, __n, __d)>>, Ty = T>,

Source§

impl<F, T, E> TryFromStructural<F> for Result<T, E>
where F: ResultMove_SI<T, E>,

Source§

impl<P, __From, __Err> TryFromStructural<__From> for Pin<P>
where P: Deref + TryFromStructural<__From, Error = __Err>, P::Target: Sized + Unpin,

Source§

type Error = __Err

Source§

fn try_from_structural( from: __From, ) -> Result<Self, TryFromError<__From, __Err>>

Source§

impl<T> TryFromStructural<T> for ()

Source§

impl<T, C0> TryFromStructural<T> for (C0,)
where T: TupleMove1<C0>,

Source§

impl<T, C0, C1> TryFromStructural<T> for (C0, C1)
where T: TupleMove2<C0, C1>,

Source§

impl<T, C0, C1, C2> TryFromStructural<T> for (C0, C1, C2)
where T: TupleMove3<C0, C1, C2>,

Source§

impl<T, C0, C1, C2, C3> TryFromStructural<T> for (C0, C1, C2, C3)
where T: TupleMove4<C0, C1, C2, C3>,

Source§

impl<T, C0, C1, C2, C3, C4> TryFromStructural<T> for (C0, C1, C2, C3, C4)
where T: TupleMove5<C0, C1, C2, C3, C4>,

Source§

impl<T, C0, C1, C2, C3, C4, C5> TryFromStructural<T> for (C0, C1, C2, C3, C4, C5)
where T: TupleMove6<C0, C1, C2, C3, C4, C5>,

Source§

impl<T, C0, C1, C2, C3, C4, C5, C6> TryFromStructural<T> for (C0, C1, C2, C3, C4, C5, C6)
where T: TupleMove7<C0, C1, C2, C3, C4, C5, C6>,

Source§

impl<T, C0, C1, C2, C3, C4, C5, C6, C7> TryFromStructural<T> for (C0, C1, C2, C3, C4, C5, C6, C7)
where T: TupleMove8<C0, C1, C2, C3, C4, C5, C6, C7>,

Source§

impl<T, C0, C1, C2, C3, C4, C5, C6, C7, C8> TryFromStructural<T> for (C0, C1, C2, C3, C4, C5, C6, C7, C8)
where T: TupleMove9<C0, C1, C2, C3, C4, C5, C6, C7, C8>,

Source§

impl<T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9> TryFromStructural<T> for (C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)
where T: TupleMove10<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>,

Source§

impl<T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10> TryFromStructural<T> for (C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10)
where T: TupleMove11<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10>,

Source§

impl<T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11> TryFromStructural<T> for (C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11)
where T: TupleMove12<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11>,

Source§

impl<T, F> TryFromStructural<F> for [T; 0]
where F: ArrayMove0<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 1]
where F: ArrayMove1<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 2]
where F: ArrayMove2<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 3]
where F: ArrayMove3<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 4]
where F: ArrayMove4<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 5]
where F: ArrayMove5<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 6]
where F: ArrayMove6<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 7]
where F: ArrayMove7<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 8]
where F: ArrayMove8<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 9]
where F: ArrayMove9<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 10]
where F: ArrayMove10<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 11]
where F: ArrayMove11<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 12]
where F: ArrayMove12<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 13]
where F: ArrayMove13<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 14]
where F: ArrayMove14<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 15]
where F: ArrayMove15<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 16]
where F: ArrayMove16<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 17]
where F: ArrayMove17<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 18]
where F: ArrayMove18<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 19]
where F: ArrayMove19<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 20]
where F: ArrayMove20<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 21]
where F: ArrayMove21<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 22]
where F: ArrayMove22<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 23]
where F: ArrayMove23<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 24]
where F: ArrayMove24<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 25]
where F: ArrayMove25<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 26]
where F: ArrayMove26<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 27]
where F: ArrayMove27<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 28]
where F: ArrayMove28<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 29]
where F: ArrayMove29<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 30]
where F: ArrayMove30<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 31]
where F: ArrayMove31<T>,

Source§

impl<T, F> TryFromStructural<F> for [T; 32]
where F: ArrayMove32<T>,

Source§

impl<T, __From, __Err> TryFromStructural<__From> for Box<T>
where T: ?Sized + TryFromStructural<__From, Error = __Err>,

Source§

type Error = __Err

Source§

fn try_from_structural( from: __From, ) -> Result<Self, TryFromError<__From, __Err>>

Source§

impl<T, __From, __Err> TryFromStructural<__From> for Rc<T>
where T: ?Sized + TryFromStructural<__From, Error = __Err>,

Source§

type Error = __Err

Source§

fn try_from_structural( from: __From, ) -> Result<Self, TryFromError<__From, __Err>>

Source§

impl<T, __From, __Err> TryFromStructural<__From> for Arc<T>
where T: ?Sized + TryFromStructural<__From, Error = __Err>,

Source§

type Error = __Err

Source§

fn try_from_structural( from: __From, ) -> Result<Self, TryFromError<__From, __Err>>

Source§

impl<T, __From, __Err> TryFromStructural<__From> for ManuallyDrop<T>
where T: TryFromStructural<__From, Error = __Err>,

Source§

type Error = __Err

Source§

fn try_from_structural( from: __From, ) -> Result<Self, TryFromError<__From, __Err>>

Implementors§

Source§

impl<T, __From, __Err> TryFromStructural<__From> for FieldCloner<T>
where T: TryFromStructural<__From, Error = __Err>,

Source§

type Error = __Err

Source§

impl<T, __From, __Err> TryFromStructural<__From> for StrucWrapper<T>
where T: TryFromStructural<__From, Error = __Err>,

Source§

type Error = __Err