frunk 0.2.0
Thanks to amazing contributions from 2 awesome new main contributors, @Centril and @ExpHP, v0.2.0 of frunk contains heaps of improvements in terms of utility, ergonomics, and documentation.
What is frunk?
At it's core, frunk brings Generic and LabelledGeneric to Rust. Why? Because these abstractions can help you Scrap Your Boilerplate, for example, by allowing totally boilerplate-free transformations between different struct
s.
Examples
Type-safe, boilerplate-free, zero-cost transformations between different struct
s:
#[derive(LabelledGeneric)]
struct SavedUser<'a> {
id: u32,
first_name: &'a str,
last_name: &'a str,
age: usize,
}
// id is gone, and fields are swapped :(
#[derive(LabelledGeneric)]
struct DeletedUser<'a> {
last_name: &'a str,
age: usize,
first_name: &'a str,
}
let s_user = SavedUser {
id: 1,
first_name: "Joe",
last_name: "Blow",
age: 30,
};
// transform !
let d_user: DeletedUser = frunk::transform_from(s_user);
Coproduct types
// I32Bool is a type that can only contain one of i32 or bool.
type I32Bool = Coprod!(i32, bool);
fn work_it(v: I32Bool) -> String {
v.fold(
poly_fn!(
|_b: bool| -> String { format!("bool {}", i) },
|i: i32 | -> String { format!("i32 {}", i) },
)
)
}
assert_eq!(
work_it(I32Bool::inject(3)),
"i32 3".to_string()
);
This is a small sample of what frunk offers. For more info, check out the repo and the docs.
Links
Credit
Credit where it's due, frunk was heavily inspired by existing Haskell and Scala utilities and libraries.