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
*_SIstructural alias generated for the enum by theStructuralderive. -
Matching on all the variants of the enum with the switch macro, returning
Okwith 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§
Required Methods§
Sourcefn try_from_structural(from: T) -> Result<Self, TryFromError<T, Self::Error>>
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.