4
4
/// `(A, B)`, `(A,)`, and `()` would all be valid choices for `P`, but `(B,)` would not be.
5
5
pub trait Split < P > : Sized {
6
6
/// 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.
7
10
type Suffix : Sized ;
8
11
9
12
/// Splits a tuple into a prefix and a suffix.
@@ -20,6 +23,12 @@ pub trait Split<P>: Sized {
20
23
}
21
24
}
22
25
26
+ macro_rules! fwd {
27
+ ( ) => { ( ) } ;
28
+ ( $T: ident) => { $T } ;
29
+ ( $( $T: ident) * ) => { ( $( $T) ,* ) } ;
30
+ }
31
+
23
32
macro_rules! rev {
24
33
( $( $T: ident) * ) => {
25
34
rev!( @REV [ $( $T) * ] )
@@ -60,13 +69,15 @@ macro_rules! impls {
60
69
impls!( @imp [ $( $t) * ] [ ] [ $( $r) * ] ) ;
61
70
} ;
62
71
72
+ ( @imp [ $( $t: ident) ?] [ $( $p: ident) * ] [ $( $r: ident) * ] ) => { } ;
73
+
63
74
( @imp [ $( $t: ident) +] [ $( $p: ident) * ] [ $( $r: ident) * ] ) => {
64
75
impl <$( $t) ,* > Split <rev!( $( $p) * ) > for rev!( $( $t) * ) {
65
- type Suffix = ( $( $r, ) * ) ;
76
+ type Suffix = fwd! ( $( $r) * ) ;
66
77
67
78
fn split( self ) -> ( rev!( $( $p) * ) , Self :: Suffix ) {
68
79
let rev!( $( $t) * ) = self ;
69
- ( rev!( $( $p) * ) , ( $( $r, ) * ) )
80
+ ( rev!( $( $p) * ) , fwd! ( $( $r) * ) )
70
81
}
71
82
}
72
83
} ;
0 commit comments