@@ -175,7 +175,13 @@ pub fn h_cons<H, T: HList>(h: H, tail: T) -> HCons<H, T> {
175175/// let (h1, (h2, h3)) = h.into_tuple2();
176176/// assert_eq!(h1, 13.5f32);
177177/// assert_eq!(h2, "hello");
178- /// assert_eq!(h3, Some(41))
178+ /// assert_eq!(h3, Some(41));
179+ ///
180+ /// // Also works when you have trailing commas
181+ /// let h4 = hlist!["yo",];
182+ /// let h5 = hlist![13.5f32, "hello", Some(41),];
183+ /// assert_eq!(h4, hlist!["yo"]);
184+ /// assert_eq!(h5, hlist![13.5f32, "hello", Some(41)]);
179185/// # }
180186/// ```
181187#[ macro_export]
@@ -193,6 +199,16 @@ macro_rules! hlist {
193199 $crate:: hlist:: HCons { head: $first, tail: hlist!( $( $repeated) , * ) }
194200 } ;
195201
202+ // <-- Forwarding of trailing comma variants
203+ ( $first: expr, $( $repeated: expr, ) +) => {
204+ hlist!( $first, $( $repeated) ,* )
205+ } ;
206+
207+ ( $first: expr, ) => {
208+ hlist!( $first)
209+ } ;
210+ // Forwarding of trailing comma variants -->
211+
196212}
197213
198214/// Macro for pattern-matching on HLists.
@@ -207,14 +223,19 @@ macro_rules! hlist {
207223/// let hlist_pat![h1, h2, h3] = h;
208224/// assert_eq!(h1, 13.5f32);
209225/// assert_eq!(h2, "hello");
210- /// assert_eq!(h3, Some(41))
226+ /// assert_eq!(h3, Some(41));
211227/// # }
212228/// ```
213229#[ macro_export]
214230macro_rules! hlist_pat {
215231 { } => { $crate:: hlist:: HNil } ;
216232 { $head: pat, $( $tail: tt) , +} => { $crate:: hlist:: HCons { head: $head, tail: hlist_pat!( $( $tail) ,* ) } } ;
217233 { $head: pat } => { $crate:: hlist:: HCons { head: $head, tail: $crate:: hlist:: HNil } } ;
234+
235+ // <-- Forward trailing comma variants
236+ { $head: pat, $( $tail: tt, ) +} => { hlist_pat!( $head, $( $tail) ,* ) } ;
237+ { $head: pat, } => { hlist_pat!( $head) } ;
238+ // Forward trailing comma variants -->
218239}
219240
220241/// Returns a type signature for an HList of the provided types
@@ -242,6 +263,16 @@ macro_rules! Hlist {
242263 ( $first: ty, $( $repeated: ty ) , +) => {
243264 $crate:: hlist:: HCons <$first, Hlist !( $( $repeated) , * ) >
244265 } ;
266+
267+ // <-- Forward trailing comma variants
268+ ( $single: ty, ) => {
269+ Hlist ![ $single]
270+ } ;
271+
272+ ( $first: ty, $( $repeated: ty, ) +) => {
273+ Hlist ![ $first, $( $repeated) ,* ]
274+ } ;
275+ // Forward trailing comma variants -->
245276}
246277
247278impl < RHS > Add < RHS > for HNil
@@ -407,12 +438,11 @@ impl<Source> Sculptor<HNil, HNil> for Source {
407438/// Indices is HCons<IndexHead, IndexTail> here because the compiler is being asked to figure out the
408439/// Index for Plucking the first item of type THead out of Self and the rest (IndexTail) is for the
409440/// Plucker's remainder induce.
410- impl < THead , TTail , SHead , STail , IndexHead , IndexTail > Sculptor < HCons < THead , TTail > , HCons < IndexHead , IndexTail > >
411- for HCons < SHead , STail >
441+ impl < THead , TTail , SHead , STail , IndexHead , IndexTail > Sculptor < HCons < THead , TTail > , HCons < IndexHead , IndexTail > >
442+ for HCons < SHead , STail >
412443 where
413444 HCons < SHead , STail > : Plucker < THead , IndexHead > ,
414445 <HCons < SHead , STail > as Plucker < THead , IndexHead > >:: Remainder : Sculptor < TTail , IndexTail > {
415-
416446 type Remainder = <<HCons < SHead , STail > as Plucker < THead , IndexHead > >:: Remainder as Sculptor < TTail , IndexTail > >:: Remainder ;
417447
418448 fn sculpt ( self ) -> ( HCons < THead , TTail > , Self :: Remainder ) {
@@ -426,7 +456,6 @@ impl <THead, TTail, SHead, STail, IndexHead, IndexTail> Sculptor<HCons<THead, TT
426456 tail_remainder
427457 )
428458 }
429-
430459}
431460
432461
@@ -468,10 +497,10 @@ impl<H, Tail> IntoReverse for HCons<H, Tail>
468497
469498 fn into_reverse ( self ) -> Self :: Output {
470499 self . tail . into_reverse ( ) +
471- HCons {
472- head : self . head ,
473- tail : HNil ,
474- }
500+ HCons {
501+ head : self . head ,
502+ tail : HNil ,
503+ }
475504 }
476505}
477506
@@ -624,7 +653,7 @@ impl<F, Acc> HFoldLeftable<F, Acc> for HNil {
624653}
625654
626655impl < F , FolderHeadR , FolderTail , H , Tail , Acc > HFoldLeftable < HCons < F , FolderTail > , Acc >
627- for HCons < H , Tail >
656+ for HCons < H , Tail >
628657 where Tail : HFoldLeftable < FolderTail , FolderHeadR > ,
629658 F : FnOnce ( Acc , H ) -> FolderHeadR
630659{
@@ -714,16 +743,14 @@ mod tests {
714743
715744 #[ test]
716745 fn test_pluck ( ) {
717-
718746 let h = hlist ! [ 1 , "hello" , true , 42f32 ] ;
719747 let ( t, r) : ( f32 , _ ) = h. pluck ( ) ;
720748 assert_eq ! ( t, 42f32 ) ;
721749 assert_eq ! ( r, hlist![ 1 , "hello" , true ] )
722-
723750 }
724751
725752 #[ test]
726- fn test_macro ( ) {
753+ fn test_hlist_macro ( ) {
727754 assert_eq ! ( hlist![ ] , HNil ) ;
728755 let h: Hlist
729756 ! ( i32 , & str , i32 ) = hlist ! [ 1 , "2" , 3 ] ;
@@ -738,14 +765,37 @@ mod tests {
738765 assert_eq ! ( tail3, HNil ) ;
739766 }
740767
768+
769+ #[ test]
770+ #[ allow( non_snake_case) ]
771+ fn test_Hlist_macro ( ) {
772+ let h1: Hlist ! ( i32 , & str , i32 ) = hlist ! [ 1 , "2" , 3 ] ;
773+ let h2: Hlist ! ( i32 , & str , i32 , ) = hlist ! [ 1 , "2" , 3 ] ;
774+ let h3: Hlist ! ( i32 ) = hlist ! [ 1 ] ;
775+ let h4: Hlist ! ( i32 , ) = hlist ! [ 1 , ] ;
776+ assert_eq ! ( h1, h2) ;
777+ assert_eq ! ( h3, h4) ;
778+ }
779+
741780 #[ test]
742781 fn test_pattern_matching ( ) {
782+ let hlist_pat ! ( one1) = hlist ! [ "one" ] ;
783+ assert_eq ! ( one1, "one" ) ;
784+ let hlist_pat ! ( one2, ) = hlist ! [ "one" ] ;
785+ assert_eq ! ( one2, "one" ) ;
786+
743787 let h = hlist ! [ 5 , 3.2f32 , true , "blue" . to_owned( ) ] ;
744788 let hlist_pat ! ( five, float, right, s) = h;
745789 assert_eq ! ( five, 5 ) ;
746790 assert_eq ! ( float, 3.2f32 ) ;
747791 assert_eq ! ( right, true ) ;
748792 assert_eq ! ( s, "blue" . to_owned( ) ) ;
793+
794+ let h2 = hlist ! [ 13.5f32 , "hello" , Some ( 41 ) ] ;
795+ let hlist_pat ! [ a, b, c, ] = h2;
796+ assert_eq ! ( a, 13.5f32 ) ;
797+ assert_eq ! ( b, "hello" ) ;
798+ assert_eq ! ( c, Some ( 41 ) ) ;
749799 }
750800
751801 #[ test]
@@ -793,11 +843,9 @@ mod tests {
793843
794844 #[ test]
795845 fn test_sculpt ( ) {
796-
797846 let h = hlist ! [ 9000 , "joe" , 41f32 ] ;
798847 let ( reshaped, remainder) : ( Hlist ! ( f32 , i32 ) , _ ) = h. sculpt ( ) ;
799848 assert_eq ! ( reshaped, hlist![ 41f32 , 9000 ] ) ;
800849 assert_eq ! ( remainder, hlist![ "joe" ] )
801-
802850 }
803851}
0 commit comments