Trait frunk_core::labelled::Transmogrifier [−][src]
pub trait Transmogrifier<Target, TransmogrifyIndexIndices> { fn transmogrify(self) -> Target; }
Expand description
Trait for transmogrifying a Source
type into a Target
type.
What is “transmogrifying”? In this context, it means to convert some data of type A
into data of type B
, in a typesafe, recursive way, as long as A
and B
are “similarly-shaped”.
In other words, as long as B
’s fields and their subfields are subsets of A
’s fields and
their respective subfields, then A
can be turned into B
.
Example
#[macro_use] extern crate frunk; #[macro_use] extern crate frunk_core; // required when using custom derives use frunk::labelled::Transmogrifier; #[derive(LabelledGeneric)] struct InternalPhoneNumber { emergency: Option<usize>, main: usize, secondary: Option<usize>, } #[derive(LabelledGeneric)] struct InternalAddress<'a> { is_whitelisted: bool, name: &'a str, phone: InternalPhoneNumber, } #[derive(LabelledGeneric)] struct InternalUser<'a> { name: &'a str, age: usize, address: InternalAddress<'a>, is_banned: bool, } #[derive(LabelledGeneric, PartialEq, Debug)] struct ExternalPhoneNumber { main: usize, } #[derive(LabelledGeneric, PartialEq, Debug)] struct ExternalAddress<'a> { name: &'a str, phone: ExternalPhoneNumber, } #[derive(LabelledGeneric, PartialEq, Debug)] struct ExternalUser<'a> { age: usize, address: ExternalAddress<'a>, name: &'a str, } let internal_user = InternalUser { name: "John", age: 10, address: InternalAddress { is_whitelisted: true, name: "somewhere out there", phone: InternalPhoneNumber { main: 1234, secondary: None, emergency: Some(5678), }, }, is_banned: true, }; /// Boilerplate-free conversion of a top-level InternalUser into an /// ExternalUser, taking care of subfield conversions as well. let external_user: ExternalUser = internal_user.transmogrify(); let expected_external_user = ExternalUser { name: "John", age: 10, address: ExternalAddress { name: "somewhere out there", phone: ExternalPhoneNumber { main: 1234, }, } }; assert_eq!(external_user, expected_external_user);Run
Credit:
- Haskell “transmogrify” Github repo: https://github.com/ivan-m/transmogrify
Required methods
fn transmogrify(self) -> Target
fn transmogrify(self) -> Target
Consume this current object and return an object of the Target type.
Although similar to sculpting, transmogrifying does its job recursively.
Implementors
impl<Key, Source, Target, InnerIndices> Transmogrifier<Option<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, Option<Source>> where
Source: Transmogrifier<Target, InnerIndices>,
impl<Key, Source, Target, InnerIndices> Transmogrifier<Box<Target, Global>, MappingIndicesWrapper<InnerIndices>> for Field<Key, Box<Source>> where
Source: Transmogrifier<Target, InnerIndices>,
impl<Key, Source, Target, InnerIndices> Transmogrifier<LinkedList<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, LinkedList<Source>> where
Source: Transmogrifier<Target, InnerIndices>,
impl<Key, Source, Target, InnerIndices> Transmogrifier<VecDeque<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, VecDeque<Source>> where
Source: Transmogrifier<Target, InnerIndices>,
impl<Key, Source, Target, InnerIndices> Transmogrifier<Vec<Target, Global>, MappingIndicesWrapper<InnerIndices>> for Field<Key, Vec<Source>> where
Source: Transmogrifier<Target, InnerIndices>,
impl<Key, SourceValue> Transmogrifier<SourceValue, IdentityTransMog> for Field<Key, SourceValue>
impl<Source, Target, TransmogIndices> Transmogrifier<Target, LabelledGenericTransmogIndicesWrapper<TransmogIndices>> for Source where
Source: LabelledGeneric,
Target: LabelledGeneric,
<Source as LabelledGeneric>::Repr: Transmogrifier<<Target as LabelledGeneric>::Repr, TransmogIndices>,
impl<Source, TargetName, TargetValue, TransmogIndices> Transmogrifier<TargetValue, PluckedLabelledGenericIndicesWrapper<TransmogIndices>> for Field<TargetName, Source> where
Source: LabelledGeneric,
TargetValue: LabelledGeneric,
Source: Transmogrifier<TargetValue, TransmogIndices>,
impl<SourceHead, SourceTail, TargetHeadName, TargetHeadValue, TargetTail, PluckSourceHeadNameIndex, TransMogSourceHeadValueIndices, TransMogTailIndices> Transmogrifier<HCons<Field<TargetHeadName, TargetHeadValue>, TargetTail>, HCons<DoTransmog<PluckSourceHeadNameIndex, TransMogSourceHeadValueIndices>, TransMogTailIndices>> for HCons<SourceHead, SourceTail> where
HCons<SourceHead, SourceTail>: ByNameFieldPlucker<TargetHeadName, PluckSourceHeadNameIndex>,
Field<TargetHeadName, <HCons<SourceHead, SourceTail> as ByNameFieldPlucker<TargetHeadName, PluckSourceHeadNameIndex>>::TargetValue>: Transmogrifier<TargetHeadValue, TransMogSourceHeadValueIndices>,
<HCons<SourceHead, SourceTail> as ByNameFieldPlucker<TargetHeadName, PluckSourceHeadNameIndex>>::Remainder: Transmogrifier<TargetTail, TransMogTailIndices>,
impl<SourceHead, SourceTail, TargetName, TargetHead, TargetTail, TransmogHeadIndex, TransmogTailIndices> Transmogrifier<HCons<TargetHead, TargetTail>, HCons<TransmogHeadIndex, TransmogTailIndices>> for Field<TargetName, HCons<SourceHead, SourceTail>> where
HCons<SourceHead, SourceTail>: Transmogrifier<HCons<TargetHead, TargetTail>, HCons<TransmogHeadIndex, TransmogTailIndices>>,