[−][src]Trait frunk::labelled::Transmogrifier
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
Consume this current object and return an object of the Target type.
Although similar to sculpting, transmogrifying does its job recursively.
Implementors
impl Transmogrifier<HNil, HNil> for HNil[src]
Implementation of Transmogrifier for when the Target is empty and the Source is empty.
fn transmogrify(self) -> HNil[src]
impl<Key, Source, Target, InnerIndices> Transmogrifier<Option<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, Option<Source>> where
Source: Transmogrifier<Target, InnerIndices>, [src]
Source: Transmogrifier<Target, InnerIndices>,
Implementation of Transmogrifier that maps over an Option in a Field, transmogrifying the
contained element on the way past if present.
fn transmogrify(self) -> Option<Target>[src]
impl<Key, Source, Target, InnerIndices> Transmogrifier<Box<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, Box<Source>> where
Source: Transmogrifier<Target, InnerIndices>, [src]
Source: Transmogrifier<Target, InnerIndices>,
Implementation of Transmogrifier that maps over an Box in a Field, transmogrifying the
contained element on the way past.
fn transmogrify(self) -> Box<Target>[src]
impl<Key, Source, Target, InnerIndices> Transmogrifier<LinkedList<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, LinkedList<Source>> where
Source: Transmogrifier<Target, InnerIndices>, [src]
Source: Transmogrifier<Target, InnerIndices>,
Implementation of Transmogrifier that maps over a $container in a Field, transmogrifying the
elements on the way past.
fn transmogrify(self) -> LinkedList<Target>[src]
impl<Key, Source, Target, InnerIndices> Transmogrifier<VecDeque<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, VecDeque<Source>> where
Source: Transmogrifier<Target, InnerIndices>, [src]
Source: Transmogrifier<Target, InnerIndices>,
Implementation of Transmogrifier that maps over a $container in a Field, transmogrifying the
elements on the way past.
fn transmogrify(self) -> VecDeque<Target>[src]
impl<Key, Source, Target, InnerIndices> Transmogrifier<Vec<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, Vec<Source>> where
Source: Transmogrifier<Target, InnerIndices>, [src]
Source: Transmogrifier<Target, InnerIndices>,
Implementation of Transmogrifier that maps over a $container in a Field, transmogrifying the
elements on the way past.
fn transmogrify(self) -> Vec<Target>[src]
impl<Key, SourceValue> Transmogrifier<SourceValue, IdentityTransMog> for Field<Key, SourceValue>[src]
Implementation of Transmogrifier for identity plucked Field to Field Transforms.
fn transmogrify(self) -> SourceValue[src]
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>, [src]
Source: LabelledGeneric,
Target: LabelledGeneric,
<Source as LabelledGeneric>::Repr: Transmogrifier<<Target as LabelledGeneric>::Repr, TransmogIndices>,
fn transmogrify(self) -> Target[src]
impl<Source, TargetName, TargetValue, TransmogIndices> Transmogrifier<TargetValue, PluckedLabelledGenericIndicesWrapper<TransmogIndices>> for Field<TargetName, Source> where
Source: LabelledGeneric + Transmogrifier<TargetValue, TransmogIndices>,
TargetValue: LabelledGeneric, [src]
Source: LabelledGeneric + Transmogrifier<TargetValue, TransmogIndices>,
TargetValue: LabelledGeneric,
fn transmogrify(self) -> TargetValue[src]
impl<SourceHead, SourceTail> Transmogrifier<HNil, HNil> for HCons<SourceHead, SourceTail>[src]
Implementation of Transmogrifier for when the Target is empty and the Source is non-empty.
fn transmogrify(self) -> HNil[src]
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>, [src]
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>,
Non-trivial implementation of Transmogrifier where similarly-shaped Source and Target types are
both Labelled HLists, but do not immediately transform into one another due to mis-matched
fields, possibly recursively so.
fn transmogrify(
self
) -> HCons<Field<TargetHeadName, TargetHeadValue>, TargetTail>[src]
self
) -> HCons<Field<TargetHeadName, TargetHeadValue>, TargetTail>
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>>, [src]
HCons<SourceHead, SourceTail>: Transmogrifier<HCons<TargetHead, TargetTail>, HCons<TransmogHeadIndex, TransmogTailIndices>>,
Implementation of Transmogrifier for when the target is an HList, and the Source is a plucked
HList.