44/// `(A, B)`, `(A,)`, and `()` would all be valid choices for `P`, but `(B,)` would not be.
55pub trait Split < P > : Sized {
66 /// The remaining fields after the input has been split.
7+ ///
8+ /// As a convenience, we unwrap unary tuples, so `<(A, B) as Split<(A,)>::Suffix` is `B`,
9+ /// **not** `(B,)`. We cannot do this for `P` itself though, due to coherence issues.
710 type Suffix : Sized ;
811
912 /// Splits a tuple into a prefix and a suffix.
@@ -20,6 +23,12 @@ pub trait Split<P>: Sized {
2023 }
2124}
2225
26+ macro_rules! fwd {
27+ ( ) => { ( ) } ;
28+ ( $T: ident) => { $T } ;
29+ ( $( $T: ident) * ) => { ( $( $T) ,* ) } ;
30+ }
31+
2332macro_rules! rev {
2433 ( $( $T: ident) * ) => {
2534 rev!( @REV [ $( $T) * ] )
@@ -60,13 +69,15 @@ macro_rules! impls {
6069 impls!( @imp [ $( $t) * ] [ ] [ $( $r) * ] ) ;
6170 } ;
6271
72+ ( @imp [ $( $t: ident) ?] [ $( $p: ident) * ] [ $( $r: ident) * ] ) => { } ;
73+
6374 ( @imp [ $( $t: ident) +] [ $( $p: ident) * ] [ $( $r: ident) * ] ) => {
6475 impl <$( $t) ,* > Split <rev!( $( $p) * ) > for rev!( $( $t) * ) {
65- type Suffix = ( $( $r, ) * ) ;
76+ type Suffix = fwd! ( $( $r) * ) ;
6677
6778 fn split( self ) -> ( rev!( $( $p) * ) , Self :: Suffix ) {
6879 let rev!( $( $t) * ) = self ;
69- ( rev!( $( $p) * ) , ( $( $r, ) * ) )
80+ ( rev!( $( $p) * ) , fwd! ( $( $r) * ) )
7081 }
7182 }
7283 } ;
0 commit comments