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");
RunThere 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());
RunStructs
Traits
- Trait for traversing based on Path