Funktional generic type-level programming in Rust: HList, Coproduct, Generic, LabelledGeneric, Validated, Monoid and friends.
Bumped due to new quickcheck (1.x-based now!)
See changelog for details.
Much thanks to the efforts of @CobaltCause.
Lots of good stuff thanks to team work from a number of contributors (incl steffahn, kpp, agluszak, rosefromthedead, and BGR360)
From the Changelog
Hcons::sculpt
(https://github.com/lloydmeta/frunk/pull/194)extract
to get value out of 1-type coproduct (https://github.com/lloydmeta/frunk/pull/201)Coproduct::map
(https://github.com/lloydmeta/frunk/pull/204)Lots of good stuff thanks to team work from a number of contributors (incl @mbrobbel, @ImmemorConsultrixContrarie , @ExpHP)
From the Changelog
Hlist!
type macro to HList!
(https://github.com/lloydmeta/frunk/issues/132)HList.length()
(https://github.com/lloydmeta/frunk/issues/125)HFoldRightable
rework: now HFoldRightable::foldr
does not differ from HFoldLeftable::foldl
in calling, like std::iter::DoubleEndedIterator::rfold
does not differ from std::iter::Iterator::fold
. Note: though foldr
behavior wasn't changed, all old foldr
calls would either stop compiling or produce wrong results (https://github.com/lloydmeta/frunk/issues/171)Box
, Option
, Vec
and more.ToMut
trait, which allows borrowing mutably from a Coproduct or HList.#[derive(LabelledGeneric)]
on tuple structsPath
model and PathTraverser
trait, which allows for composable lens-like-usage
$crate::
Adds support for transmogrifying data of different types
#[macro_use]
extern crate frunk_core;
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);
Upgraded syn and quote versions in frunk_derives.
Lock-step bump in versions for all libs to keep things straightforward.