Trait frunk_core::labelled::Transmogrifier
source · pub trait Transmogrifier<Target, TransmogrifyIndexIndices> {
// Required method
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
// required when using custom derives
use frunk::LabelledGeneric;
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);
Credit:
- Haskell “transmogrify” Github repo: https://github.com/ivan-m/transmogrify
Required Methods§
sourcefn 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 Transmogrifier<HNil, HNil> for HNil
Implementation of Transmogrifier
for when the Target
is empty and the Source
is empty.
impl<Key, Source, Target, InnerIndices> Transmogrifier<Option<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, Option<Source>>where
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.
impl<Key, Source, Target, InnerIndices> Transmogrifier<Box<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, Box<Source>>where
Source: Transmogrifier<Target, InnerIndices>,
Implementation of Transmogrifier
that maps over an Box
in a Field
, transmogrifying the
contained element on the way past.
impl<Key, Source, Target, InnerIndices> Transmogrifier<LinkedList<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, LinkedList<Source>>where
Source: Transmogrifier<Target, InnerIndices>,
Implementation of Transmogrifier
that maps over a $container
in a Field
, transmogrifying the
elements on the way past.
impl<Key, Source, Target, InnerIndices> Transmogrifier<VecDeque<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, VecDeque<Source>>where
Source: Transmogrifier<Target, InnerIndices>,
Implementation of Transmogrifier
that maps over a $container
in a Field
, transmogrifying the
elements on the way past.
impl<Key, Source, Target, InnerIndices> Transmogrifier<Vec<Target>, MappingIndicesWrapper<InnerIndices>> for Field<Key, Vec<Source>>where
Source: Transmogrifier<Target, InnerIndices>,
Implementation of Transmogrifier
that maps over a $container
in a Field
, transmogrifying the
elements on the way past.
impl<Key, SourceValue> Transmogrifier<SourceValue, IdentityTransMog> for Field<Key, SourceValue>
Implementation of Transmogrifier
for identity plucked Field
to Field
Transforms.
impl<Source, Target, TransmogIndices> Transmogrifier<Target, LabelledGenericTransmogIndicesWrapper<TransmogIndices>> for Sourcewhere
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 + Transmogrifier<TargetValue, TransmogIndices>,
TargetValue: LabelledGeneric,
impl<SourceHead, SourceTail> Transmogrifier<HNil, HNil> for HCons<SourceHead, SourceTail>
Implementation of Transmogrifier
for when the Target
is empty and the Source
is non-empty.
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>,
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.
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>>,
Implementation of Transmogrifier
for when the target is an HList
, and the Source
is a plucked
HList
.