[−][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
.