Module frunk_core::path

source ·
Expand description

Holds models, traits, and logic for generic traversal of models

#[derive(LabelledGeneric)]
struct Address<'a> {
    name: &'a str,
}

#[derive(LabelledGeneric)]
struct User<'a> {
    name: &'a str,
    address: Address<'a>,
}

let u = User {
  name: "Joe",
  address: Address { name: "blue pond" },
};

let name_path = path!(name);

{
let traversed_name = name_path.get(&u);
assert_eq!(*traversed_name, "Joe");
}

// You can also **add** paths together
let address_path = path!(address);
let address_name_path = address_path + name_path;

let traversed_address_name = address_name_path.get(u);
assert_eq!(traversed_address_name, "blue pond");
Run

There is also a Path! type macro that allows you to declare type constraints for shape-dependent functions on LabelledGeneric types.

#[derive(LabelledGeneric)]
struct Dog<'a> {
    name: &'a str,
    dimensions: Dimensions,
}

#[derive(LabelledGeneric)]
struct Cat<'a> {
    name: &'a str,
    dimensions: Dimensions,
}

#[derive(LabelledGeneric)]
struct Dimensions {
    height: usize,
    width: usize,
    unit: SizeUnit,
}

#[derive(Debug)]
enum SizeUnit {
    Cm,
    Inch,
}

let dog = Dog {
    name: "Joe",
    dimensions: Dimensions {
        height: 10,
        width: 5,
        unit: SizeUnit::Inch,
    },
};

let cat = Cat {
    name: "Schmoe",
    dimensions: Dimensions {
        height: 7,
        width: 3,
        unit: SizeUnit::Cm,
    },
};

// Prints height as long as `A` has the right "shape" (e.g.
// has `dimensions.height: usize` and `dimension.unit: SizeUnit)
fn print_height<'a, A, HeightIdx, UnitIdx>(obj: &'a A) -> String
where
    &'a A: PathTraverser<Path!(dimensions.height), HeightIdx, TargetValue = &'a usize>
        + PathTraverser<Path!(dimensions.unit), UnitIdx, TargetValue = &'a SizeUnit>,
{
    format!(
        "Height [{} {:?}]",
        path!(dimensions.height).get(obj),
        path!(dimensions.unit).get(obj)
    )
}

assert_eq!(print_height(&dog), "Height [10 Inch]".to_string());
assert_eq!(print_height(&cat), "Height [7 Cm]".to_string());
Run

Structs§

Traits§