[][src]Module frunk_core::labelled

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 LabelledGenerics 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

#[macro_use]
extern crate frunk;

use frunk::labelled::chars::*;

// 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")Run

A more common usage is to use LabelledGeneric to transform structs that have mismatched fields!

#[macro_use] extern crate frunk;
#[macro_use] extern crate frunk_core; // required when using custom derives
#[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); // doneRun

If you have the need to transform types that are similarly-shaped recursively, then use the Transmogrifier trait.

#[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

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.

ValueField

A version of Field that doesn't have a type-level label, just a value-level one

Traits

ByNameFieldPlucker

Trait for plucking out a Field from a type by type-level TargetKey.

IntoLabelledGeneric
IntoUnlabelled

Trait for turning a Field HList into an un-labelled HList

IntoValueLabelled

A trait that strips type-level strings from the labels

LabelledGeneric

A trait that converts from a type to a labelled generic representation.

Transmogrifier

Trait for transmogrifying a Source type into a Target 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, returns Dst

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_fromDeprecated

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.