Expand description
This module holds the machinery behind LabelledGeneric.
A LabelledGeneric
instance is pretty much exactly the same as a Generic
instance, except that the generic representation should contain information
about field names.
Having a separate trait for LabelledGeneric
s gives us the freedom to
derive both labelled and non-labelled generic trait instances for our types.
Aside from the main LabelledGeneric
trait, this module holds helper
methods that allow users to use LabelledGeneric
without using universal
function call syntax.
In addition, this module holds macro-generated enums that map to letters in field names (identifiers).
§Examples
use frunk::labelled::chars::*;
use frunk_core::field;
// Optionally alias our tuple that represents our type-level string
type name = (n, a, m, e);
let labelled = field![name, "Lloyd"];
assert_eq!(labelled.name, "name");
assert_eq!(labelled.value, "Lloyd")
A more common usage is to use LabelledGeneric
to transform structs that
have mismatched fields!
// required when using custom derives
use frunk::LabelledGeneric;
#[derive(LabelledGeneric)]
struct NewUser<'a> {
first_name: &'a str,
last_name: &'a str,
age: usize,
}
// Notice that the fields are mismatched in terms of ordering
// *and* also in terms of the number of fields.
#[derive(LabelledGeneric)]
struct ShortUser<'a> {
last_name: &'a str,
first_name: &'a str,
}
let n_user = NewUser {
first_name: "Joe",
last_name: "Blow",
age: 30,
};
// transform_from automagically sculpts the labelled generic
// representation of the source object to that of the target type
let s_user: ShortUser = frunk::transform_from(n_user); // done
If you have the need to transform types that are similarly-shaped recursively, then use the Transmogrifier trait.
// required when using custom derives
use frunk::labelled::Transmogrifier;
use frunk::LabelledGeneric;
#[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);
Modules§
- chars
- Types for building type-level labels from character sequences.
Structs§
- Field
- A Label contains a type-level Name, a runtime value, and
a reference to a
&'static str
name. - Value
Field - A version of Field that doesn’t have a type-level label, just a value-level one
Traits§
- ByName
Field Plucker - Trait for plucking out a
Field
from a type by type-levelTargetKey
. - Into
Labelled Generic - Into
Unlabelled - Trait for turning a Field HList into an un-labelled HList
- Into
Value Labelled - A trait that strips type-level strings from the labels
- Labelled
Generic - A trait that converts from a type to a labelled generic representation.
- Transmogrifier
- Trait for transmogrifying a
Source
type into aTarget
type.
Functions§
- field_
with_ name - Returns a new Field for a given value and custom name.
- from_
labelled_ generic - Given a labelled generic representation of a
Dst
, returnsDst
- into_
labelled_ generic - Given a
Src
, returns its labelled generic representation. - labelled_
convert_ from - Converts one type into another assuming they have the same labelled generic representation.
- sculpted_
convert_ from Deprecated - Converts from one type into another assuming that their labelled generic representations can be sculpted into each other.
- transform_
from - Converts from one type into another assuming that their labelled generic representations can be sculpted into each other.