From 7e0869b800cf938660b04fc37f4347f34289a262 Mon Sep 17 00:00:00 2001 From: Lloyd Date: Thu, 16 Mar 2017 13:46:37 +0900 Subject: [PATCH 1/3] 0.0.9 core (#42) Update Gitter badge 0.0.10 derives 0.1.19 release Update crate description --- Cargo.toml | 8 ++++---- README.md | 2 +- core/Cargo.toml | 2 +- derives/Cargo.toml | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 42171dcb4..5b95d0cf9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "frunk" -version = "0.1.18" +version = "0.1.19" authors = ["Lloyd "] -description = "Frunk provides developers with a number of functional programming tools like HList, Generic, Validated, Monoid, Semigroup and friends." +description = "Frunk provides developers with a number of functional programming tools like HList, Generic, LabelledGeneric, Validated, Monoid, Semigroup and friends." license = "MIT" homepage = "https://github.com/lloydmeta/frunk" keywords = [ "HList", "Generic", "Validated", "Semigroup", "Monoid"] @@ -12,8 +12,8 @@ time = "0.1.36" [dependencies.frunk_core] path = "core" -version = "0.0.8" +version = "0.0.9" [dependencies.frunk_derives] path = "derives" -version = "0.0.9" \ No newline at end of file +version = "0.0.10" \ No newline at end of file diff --git a/README.md b/README.md index 33312943f..8ab1357a1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Frunk [![Crates.io](https://img.shields.io/crates/v/frunk.svg)](https://crates.io/crates/frunk) [![Build Status](https://travis-ci.org/lloydmeta/frunk.svg?branch=master)](https://travis-ci.org/lloydmeta/frunk) [![Join the chat at https://gitter.im/lloydmeta/frunk](https://img.shields.io/badge/gitter-join_chat-1dce73.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSIwIiB5PSI1IiBmaWxsPSIjZmZmIiB3aWR0aD0iMSIgaGVpZ2h0PSI1Ii8%2BPHJlY3QgeD0iMiIgeT0iNiIgZmlsbD0iI2ZmZiIgd2lkdGg9IjEiIGhlaWdodD0iNyIvPjxyZWN0IHg9IjQiIHk9IjYiIGZpbGw9IiNmZmYiIHdpZHRoPSIxIiBoZWlnaHQ9IjciLz48cmVjdCB4PSI2IiB5PSI2IiBmaWxsPSIjZmZmIiB3aWR0aD0iMSIgaGVpZ2h0PSI0Ii8%2BPC9zdmc%2B&logoWidth=8)](https://gitter.im/lloydmeta/frunk?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +# Frunk [![Crates.io](https://img.shields.io/crates/v/frunk.svg)](https://crates.io/crates/frunk) [![Build Status](https://travis-ci.org/lloydmeta/frunk.svg?branch=master)](https://travis-ci.org/lloydmeta/frunk) [![Gitter](https://badges.gitter.im/lloydmeta/frunk.svg)](https://gitter.im/lloydmeta/frunk?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) > **frunk** *frəNGk* > * Functional programming toolbelt in Rust. diff --git a/core/Cargo.toml b/core/Cargo.toml index a637b9d34..15e893850 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frunk_core" -version = "0.0.8" +version = "0.0.9" authors = ["Lloyd "] description = "Frunk core provides developers with HList and Generic" license = "MIT" diff --git a/derives/Cargo.toml b/derives/Cargo.toml index 6ed727d50..2ea203063 100644 --- a/derives/Cargo.toml +++ b/derives/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frunk_derives" -version = "0.0.9" +version = "0.0.10" authors = ["Lloyd "] description = "frunk_derives contains the custom derivations for certain traits in Frunk." license = "MIT" @@ -11,9 +11,9 @@ keywords = [ "HList", "Generic", "derives"] proc-macro = true [dependencies] -syn = "0.11.8" -quote = "0.3.12" +syn = "0.11.9" +quote = "0.3.15" [dependencies.frunk_core] path = "../core" -version = "0.0.8" +version = "0.0.9" From d2d6bbbf024cd94bb1e991fa9a93c2cab054de45 Mon Sep 17 00:00:00 2001 From: John Wrenn Date: Thu, 16 Mar 2017 12:38:03 -0400 Subject: [PATCH 2/3] Improve 'frunk', 'frunk_core', and 'frunk_derives' package metadata. (#43) * Improve 'frunk', 'frunk_core', and 'frunk_derives' package metadata. Added `documentation` key to rendering of documentation for latest published version of this crate. Renamed `homepage` key to `repository`. Added `badges` table and `travis-ci` item. * Remove version number from manifest documentation link. * Add "LabelledGeneric" to keywords of funk_core package manifest. * Modified keyword lists in package manifests. Removed "HList" and generic "Generic" from frunk_derives manifest. Added "Frunk" as a keyword to each package, following the convention of serde. --- Cargo.toml | 8 ++++++-- core/Cargo.toml | 8 ++++++-- derives/Cargo.toml | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5b95d0cf9..9237a6118 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,12 @@ version = "0.1.19" authors = ["Lloyd "] description = "Frunk provides developers with a number of functional programming tools like HList, Generic, LabelledGeneric, Validated, Monoid, Semigroup and friends." license = "MIT" -homepage = "https://github.com/lloydmeta/frunk" -keywords = [ "HList", "Generic", "Validated", "Semigroup", "Monoid"] +documentation = "https://docs.rs/frunk" +repository = "https://github.com/lloydmeta/frunk" +keywords = ["Frunk", "HList", "Generic", "Validated", "Semigroup", "Monoid"] + +[badges] +travis-ci = { repository = "lloydmeta/frunk" } [dev-dependencies] time = "0.1.36" diff --git a/core/Cargo.toml b/core/Cargo.toml index 15e893850..46a9ef6f1 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -4,5 +4,9 @@ version = "0.0.9" authors = ["Lloyd "] description = "Frunk core provides developers with HList and Generic" license = "MIT" -homepage = "https://github.com/lloydmeta/frunk" -keywords = [ "HList", "Generic"] \ No newline at end of file +documentation = "https://docs.rs/frunk_core" +repository = "https://github.com/lloydmeta/frunk" +keywords = ["Frunk", "HList", "Generic", "LabelledGeneric"] + +[badges] +travis-ci = { repository = "lloydmeta/frunk" } diff --git a/derives/Cargo.toml b/derives/Cargo.toml index 2ea203063..0cc261b0c 100644 --- a/derives/Cargo.toml +++ b/derives/Cargo.toml @@ -4,8 +4,12 @@ version = "0.0.10" authors = ["Lloyd "] description = "frunk_derives contains the custom derivations for certain traits in Frunk." license = "MIT" -homepage = "https://github.com/lloydmeta/frunk" -keywords = [ "HList", "Generic", "derives"] +documentation = "https://docs.rs/frunk_derives" +repository = "https://github.com/lloydmeta/frunk" +keywords = ["Frunk", "derives"] + +[badges] +travis-ci = { repository = "lloydmeta/frunk" } [lib] proc-macro = true From 28f1dc838c1955b14e2a904a016c514ec963ef47 Mon Sep 17 00:00:00 2001 From: Lloyd Date: Fri, 17 Mar 2017 14:39:45 +0900 Subject: [PATCH 3/3] Trailing commas in Hlist macros, more doc tests (#44) * Add support for trailing commas in hlist! and Hlist! * Support trailing comma pattern matches as well * Stop ignoring doctests for LabelledGeneric and Generic * Try tweaking travis.yml * Core 0.0.10 release * Derives 0.0.11 release * 0.1.20 release * One less kw --- .travis.yml | 2 +- Cargo.toml | 8 ++-- core/Cargo.toml | 6 ++- core/src/generic.rs | 20 +++++----- core/src/hlist.rs | 80 ++++++++++++++++++++++++++++++++-------- core/src/labelled.rs | 25 ++++++++----- derives/Cargo.toml | 4 +- derives/src/lib.rs | 1 - src/lib.rs | 2 + tests/validated_tests.rs | 1 - 10 files changed, 105 insertions(+), 44 deletions(-) diff --git a/.travis.yml b/.travis.yml index b6e442587..943864703 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ script: - | travis-cargo build && travis-cargo test && - travis-cargo test -- -p frunk_core && + cd core && travis-cargo test && travis-cargo doc after_success: diff --git a/Cargo.toml b/Cargo.toml index 9237a6118..db3885fcd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "frunk" -version = "0.1.19" +version = "0.1.20" authors = ["Lloyd "] description = "Frunk provides developers with a number of functional programming tools like HList, Generic, LabelledGeneric, Validated, Monoid, Semigroup and friends." license = "MIT" documentation = "https://docs.rs/frunk" repository = "https://github.com/lloydmeta/frunk" -keywords = ["Frunk", "HList", "Generic", "Validated", "Semigroup", "Monoid"] +keywords = ["Frunk", "HList", "Generic", "Validated", "Monoid"] [badges] travis-ci = { repository = "lloydmeta/frunk" } @@ -16,8 +16,8 @@ time = "0.1.36" [dependencies.frunk_core] path = "core" -version = "0.0.9" +version = "0.0.10" [dependencies.frunk_derives] path = "derives" -version = "0.0.10" \ No newline at end of file +version = "0.0.11" \ No newline at end of file diff --git a/core/Cargo.toml b/core/Cargo.toml index 46a9ef6f1..ca8da57b4 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frunk_core" -version = "0.0.9" +version = "0.0.10" authors = ["Lloyd "] description = "Frunk core provides developers with HList and Generic" license = "MIT" @@ -10,3 +10,7 @@ keywords = ["Frunk", "HList", "Generic", "LabelledGeneric"] [badges] travis-ci = { repository = "lloydmeta/frunk" } + +[dev-dependencies.frunk_derives] +path = "../derives" +version = "0.0.11" diff --git a/core/src/generic.rs b/core/src/generic.rs index ec97c1133..53ba5e73a 100644 --- a/core/src/generic.rs +++ b/core/src/generic.rs @@ -8,14 +8,15 @@ /// For the most part, you should be using the derivation that is available through /// frunk_derive to generate instances of this typeclass for your types. /// -/// I would highly recommend you check out `derivation_tests.rs` to see how to actually use -/// this trait in real life. Since frunk_derive depends on this trait, I can't actually -/// pull it in as a dependency here (otherwise the dependency would be circular) and show -/// how to use it in a proper doc test. -/// /// # Examples /// -/// ```rust,ignore +/// ```rust +/// #[allow(unused_imports)] +/// # #[macro_use] extern crate frunk_derives; +/// # #[macro_use] extern crate frunk_core; +/// # use frunk_core::hlist::*; fn main() { +/// use frunk_core::hlist::*; +/// use frunk_core::generic::*; /// #[derive(Generic)] /// struct ApiPerson<'a> { /// FirstName: &'a str, @@ -31,11 +32,12 @@ /// } /// /// let a_person = ApiPerson { -/// first_name: "Joe", -/// last_name: "Blow", -/// age: 30, +/// FirstName: "Joe", +/// LastName: "Blow", +/// Age: 30, /// }; /// let d_person: DomainPerson = convert_from(a_person); // done +/// # } /// ``` pub trait Generic { /// The generic representation type diff --git a/core/src/hlist.rs b/core/src/hlist.rs index 319a430d8..7549fd5ff 100644 --- a/core/src/hlist.rs +++ b/core/src/hlist.rs @@ -175,7 +175,13 @@ pub fn h_cons(h: H, tail: T) -> HCons { /// let (h1, (h2, h3)) = h.into_tuple2(); /// assert_eq!(h1, 13.5f32); /// assert_eq!(h2, "hello"); -/// assert_eq!(h3, Some(41)) +/// assert_eq!(h3, Some(41)); +/// +/// // Also works when you have trailing commas +/// let h4 = hlist!["yo",]; +/// let h5 = hlist![13.5f32, "hello", Some(41),]; +/// assert_eq!(h4, hlist!["yo"]); +/// assert_eq!(h5, hlist![13.5f32, "hello", Some(41)]); /// # } /// ``` #[macro_export] @@ -193,6 +199,16 @@ macro_rules! hlist { $crate::hlist::HCons { head: $first, tail: hlist!($($repeated), *)} }; + // <-- Forwarding of trailing comma variants + ($first: expr, $( $repeated: expr, ) +) => { + hlist!($first, $($repeated),*) + }; + + ($first: expr, ) => { + hlist!($first) + }; + // Forwarding of trailing comma variants --> + } /// Macro for pattern-matching on HLists. @@ -207,7 +223,7 @@ macro_rules! hlist { /// let hlist_pat![h1, h2, h3] = h; /// assert_eq!(h1, 13.5f32); /// assert_eq!(h2, "hello"); -/// assert_eq!(h3, Some(41)) +/// assert_eq!(h3, Some(41)); /// # } /// ``` #[macro_export] @@ -215,6 +231,11 @@ macro_rules! hlist_pat { {} => { $crate::hlist::HNil }; { $head:pat, $($tail:tt), +} => { $crate::hlist::HCons{ head: $head, tail: hlist_pat!($($tail),*) } }; { $head:pat } => { $crate::hlist::HCons { head: $head, tail: $crate::hlist::HNil } }; + + // <-- Forward trailing comma variants + { $head:pat, $($tail:tt,) +} => { hlist_pat!($head, $($tail),*) }; + { $head:pat, } => { hlist_pat!($head) }; + // Forward trailing comma variants --> } /// Returns a type signature for an HList of the provided types @@ -242,6 +263,16 @@ macro_rules! Hlist { ($first: ty, $( $repeated: ty ), +) => { $crate::hlist::HCons<$first, Hlist!($($repeated), *)> }; + + // <-- Forward trailing comma variants + ($single: ty,) => { + Hlist![$single] + }; + + ($first: ty, $( $repeated: ty, ) +) => { + Hlist![$first, $($repeated),*] + }; + // Forward trailing comma variants --> } impl Add for HNil @@ -407,12 +438,11 @@ impl Sculptor for Source { /// Indices is HCons here because the compiler is being asked to figure out the /// Index for Plucking the first item of type THead out of Self and the rest (IndexTail) is for the /// Plucker's remainder induce. -impl Sculptor, HCons> - for HCons +impl Sculptor, HCons> +for HCons where HCons: Plucker, as Plucker>::Remainder: Sculptor { - type Remainder = < as Plucker>::Remainder as Sculptor>::Remainder; fn sculpt(self) -> (HCons, Self::Remainder) { @@ -426,7 +456,6 @@ impl Sculptor IntoReverse for HCons fn into_reverse(self) -> Self::Output { self.tail.into_reverse() + - HCons { - head: self.head, - tail: HNil, - } + HCons { + head: self.head, + tail: HNil, + } } } @@ -624,7 +653,7 @@ impl HFoldLeftable for HNil { } impl HFoldLeftable, Acc> - for HCons +for HCons where Tail: HFoldLeftable, F: FnOnce(Acc, H) -> FolderHeadR { @@ -714,16 +743,14 @@ mod tests { #[test] fn test_pluck() { - let h = hlist![1, "hello", true, 42f32]; let (t, r): (f32, _) = h.pluck(); assert_eq!(t, 42f32); assert_eq!(r, hlist![1, "hello", true]) - } #[test] - fn test_macro() { + fn test_hlist_macro() { assert_eq!(hlist![], HNil); let h: Hlist !(i32, &str, i32) = hlist![1, "2", 3]; @@ -738,14 +765,37 @@ mod tests { assert_eq!(tail3, HNil); } + + #[test] + #[allow(non_snake_case)] + fn test_Hlist_macro() { + let h1: Hlist!(i32, &str, i32) = hlist![1, "2", 3]; + let h2: Hlist!(i32, &str, i32,) = hlist![1, "2", 3]; + let h3: Hlist!(i32) = hlist![1]; + let h4: Hlist!(i32,) = hlist![1,]; + assert_eq!(h1, h2); + assert_eq!(h3, h4); + } + #[test] fn test_pattern_matching() { + let hlist_pat!(one1) = hlist!["one"]; + assert_eq!(one1, "one"); + let hlist_pat!(one2,) = hlist!["one"]; + assert_eq!(one2, "one"); + let h = hlist![5, 3.2f32, true, "blue".to_owned()]; let hlist_pat!(five, float, right, s) = h; assert_eq!(five, 5); assert_eq!(float, 3.2f32); assert_eq!(right, true); assert_eq!(s, "blue".to_owned()); + + let h2 = hlist![13.5f32, "hello", Some(41)]; + let hlist_pat![a, b, c,] = h2; + assert_eq!(a, 13.5f32); + assert_eq!(b, "hello"); + assert_eq!(c, Some(41)); } #[test] @@ -793,11 +843,9 @@ mod tests { #[test] fn test_sculpt() { - let h = hlist![9000, "joe", 41f32]; let (reshaped, remainder): (Hlist!(f32, i32), _) = h.sculpt(); assert_eq!(reshaped, hlist![41f32, 9000]); assert_eq!(remainder, hlist!["joe"]) - } } diff --git a/core/src/labelled.rs b/core/src/labelled.rs index 7b521b306..fbffe7c1d 100644 --- a/core/src/labelled.rs +++ b/core/src/labelled.rs @@ -30,17 +30,21 @@ use std::fmt; /// A trait that converts from a type to a labelled generic representation /// +/// LabelledGenerics allow us to have completely type-safe, boilerplate free conversions +/// between different structs. +/// /// For the most part, you should be using the derivation that is available through /// frunk_derive to generate instances of this typeclass for your types. /// -/// I would highly recommend you check out `derivation_tests.rs` to see how to actually use -/// this trait in real life. Since frunk_derive depends on this trait, I can't actually -/// pull it in as a dependency here (otherwise the dependency would be circular) and show -/// how to use it in a proper doc test. -/// /// # Examples /// -/// ```rust,ignore +/// ```rust +/// #[allow(unused_imports)] +/// # #[macro_use] extern crate frunk_derives; +/// # #[macro_use] extern crate frunk_core; +/// # use frunk_core::hlist::*; fn main() { +/// use frunk_core::hlist::*; +/// use frunk_core::labelled::*; /// #[derive(LabelledGeneric)] /// struct NewUser<'a> { /// first_name: &'a str, @@ -48,11 +52,12 @@ use std::fmt; /// age: usize, /// } /// +/// // Notice that the fields are mismatched in terms of ordering /// #[derive(LabelledGeneric)] /// struct SavedUser<'a> { -/// first_name: &'a str, /// last_name: &'a str, /// age: usize, +/// first_name: &'a str, /// } /// /// let n_user = NewUser { @@ -61,8 +66,10 @@ use std::fmt; /// age: 30, /// }; /// -/// let s_user = ::sculpted_convert_from(n_user); // done -/// ``` +/// // sculpted_convert_from automagically sculpts the labelled generic +/// // representation of the source object to that of the target type +/// let s_user: SavedUser = sculpted_convert_from(n_user); // done +/// # } pub trait LabelledGeneric { /// The labelled generic representation type type Repr; diff --git a/derives/Cargo.toml b/derives/Cargo.toml index 0cc261b0c..3c83d012b 100644 --- a/derives/Cargo.toml +++ b/derives/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frunk_derives" -version = "0.0.10" +version = "0.0.11" authors = ["Lloyd "] description = "frunk_derives contains the custom derivations for certain traits in Frunk." license = "MIT" @@ -20,4 +20,4 @@ quote = "0.3.15" [dependencies.frunk_core] path = "../core" -version = "0.0.9" +version = "0.0.10" diff --git a/derives/src/lib.rs b/derives/src/lib.rs index fd06488d5..4252aaa19 100644 --- a/derives/src/lib.rs +++ b/derives/src/lib.rs @@ -8,7 +8,6 @@ //! 2. [Crates.io page](https://crates.io/crates/frunk) extern crate proc_macro; -#[macro_use] extern crate frunk_core; #[macro_use] extern crate quote; diff --git a/src/lib.rs b/src/lib.rs index 75b2bdb8e..4e8ea97a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -101,8 +101,10 @@ //! 1. [Source on Github](https://github.com/lloydmeta/frunk) //! 2. [Crates.io page](https://crates.io/crates/frunk) +#[allow(unused_imports)] #[macro_use] extern crate frunk_core; +#[allow(unused_imports)] #[macro_use] extern crate frunk_derives; diff --git a/tests/validated_tests.rs b/tests/validated_tests.rs index 515ec71cf..2f23f7bd1 100644 --- a/tests/validated_tests.rs +++ b/tests/validated_tests.rs @@ -1,5 +1,4 @@ extern crate frunk; -#[macro_use] // for the hlist macro extern crate frunk_core; use frunk::*; // for the Generic trait and HList