| 1 | //! A generic wrapper which can be used to represent recursive types.
|
| 2 | //! Supports conversion from and to tuples of the same size.
|
| 3 |
|
| 4 | /// No more recursion. Can be used within any `Recursive<NoneMore, YourValue>` type.
|
| 5 | #[derive (Copy, Clone, Debug, Default, Eq, PartialEq)]
|
| 6 | pub struct NoneMore;
|
| 7 |
|
| 8 | /// A recursive type-level linked list of `Value` entries.
|
| 9 | /// Mainly used to represent an arbitrary number of channels.
|
| 10 | /// The recursive architecture removes the need to implement traits for many different tuples.
|
| 11 | #[derive (Copy, Clone, Debug, Default, Eq, PartialEq)]
|
| 12 | pub struct Recursive<Inner, Value> {
|
| 13 | /// The remaining values of this linked list,
|
| 14 | /// probably either `NoneMore` or another instance of the same `Recursive<Inner - 1, Value>`.
|
| 15 | pub inner: Inner,
|
| 16 |
|
| 17 | /// The next item in this linked list.
|
| 18 | pub value: Value,
|
| 19 | }
|
| 20 |
|
| 21 | impl<Inner, Value> Recursive<Inner, Value> {
|
| 22 | /// Create a new recursive type. Equivalent to the manual constructor, but less verbose.
|
| 23 | pub fn new(inner: Inner, value: Value) -> Self { Self { inner, value } }
|
| 24 | }
|
| 25 |
|
| 26 | /// Convert this recursive type into a tuple.
|
| 27 | /// This is nice as it will require less typing for the same type.
|
| 28 | /// A type might or might not be convertible to the specified `Tuple` type.
|
| 29 | pub trait IntoTuple<Tuple> {
|
| 30 | /// Convert this recursive type to a nice tuple.
|
| 31 | fn into_tuple(self) -> Tuple;
|
| 32 | }
|
| 33 |
|
| 34 | /// Convert this recursive type into a tuple.
|
| 35 | /// This is nice as it will require less typing for the same type.
|
| 36 | /// A type will be converted to the specified `Self::NonRecursive` type.
|
| 37 | pub trait IntoNonRecursive {
|
| 38 | /// The resulting tuple type.
|
| 39 | type NonRecursive;
|
| 40 |
|
| 41 | /// Convert this recursive type to a nice tuple.
|
| 42 | fn into_non_recursive(self) -> Self::NonRecursive;
|
| 43 | }
|
| 44 |
|
| 45 | /// Create a recursive type from this tuple.
|
| 46 | pub trait IntoRecursive {
|
| 47 | /// The recursive type resulting from this tuple.
|
| 48 | type Recursive;
|
| 49 |
|
| 50 | /// Create a recursive type from this tuple.
|
| 51 | fn into_recursive(self) -> Self::Recursive;
|
| 52 | }
|
| 53 |
|
| 54 | impl IntoRecursive for NoneMore {
|
| 55 | type Recursive = Self;
|
| 56 | fn into_recursive(self) -> Self::Recursive { self }
|
| 57 | }
|
| 58 |
|
| 59 | impl<Inner: IntoRecursive, Value> IntoRecursive for Recursive<Inner, Value> {
|
| 60 | type Recursive = Recursive<Inner::Recursive, Value>;
|
| 61 | fn into_recursive(self) -> Self::Recursive { Recursive::new(self.inner.into_recursive(), self.value) }
|
| 62 | }
|
| 63 |
|
| 64 | // Automatically implement IntoTuple so we have to generate less code in the macros
|
| 65 | impl<I: IntoNonRecursive> IntoTuple<I::NonRecursive> for I {
|
| 66 | fn into_tuple(self) -> <I as IntoNonRecursive>::NonRecursive {
|
| 67 | self.into_non_recursive()
|
| 68 | }
|
| 69 | }
|
| 70 |
|
| 71 | //Implement traits for the empty tuple, the macro doesn't handle that
|
| 72 | impl IntoRecursive for () {
|
| 73 | type Recursive = NoneMore;
|
| 74 | fn into_recursive(self) -> Self::Recursive { NoneMore }
|
| 75 | }
|
| 76 |
|
| 77 | impl IntoNonRecursive for NoneMore {
|
| 78 | type NonRecursive = ();
|
| 79 |
|
| 80 | fn into_non_recursive(self) -> Self::NonRecursive {
|
| 81 | ()
|
| 82 | }
|
| 83 | }
|
| 84 |
|
| 85 | /// Generates the recursive type corresponding to this tuple:
|
| 86 | /// ```nocheck
|
| 87 | /// gen_recursive_type!(A, B, C)
|
| 88 | /// => Recursive<Recursive<Recursive<NoneMore, A>, B>, C>
|
| 89 | /// ```
|
| 90 | macro_rules! gen_recursive_type {
|
| 91 | () => { NoneMore };
|
| 92 | ($last:ident $(,$not_last:ident)*) => {
|
| 93 | Recursive<gen_recursive_type!($($not_last),*), $last>
|
| 94 | };
|
| 95 | }
|
| 96 |
|
| 97 | /// Generates the recursive value corresponding to the given indices:
|
| 98 | /// ```nocheck
|
| 99 | /// gen_recursive_value(self; 1, 0)
|
| 100 | /// => Recursive { inner: Recursive { inner: NoneMore, value: self.0 }, value: self.1 }
|
| 101 | /// ```
|
| 102 | macro_rules! gen_recursive_value {
|
| 103 | ($self:ident;) => { NoneMore };
|
| 104 | ($self:ident; $last:tt $(,$not_last:tt)*) => {
|
| 105 | Recursive { inner: gen_recursive_value!($self; $($not_last),*), value: $self.$last }
|
| 106 | };
|
| 107 | }
|
| 108 |
|
| 109 | /// Generates the into_tuple value corresponding to the given type names:
|
| 110 | /// ```nocheck
|
| 111 | /// gen_tuple_value(self; A, B, C)
|
| 112 | /// => (self.inner.inner.value, self.inner.value, self.value)
|
| 113 | /// ```
|
| 114 | macro_rules! gen_tuple_value {
|
| 115 | ($self:ident; $($all:ident),* ) => {
|
| 116 | gen_tuple_value!(@ $self; (); $($all),* )
|
| 117 | };
|
| 118 |
|
| 119 | (@ $self:ident; ($($state:expr),*);) => { ($($state .value,)*) };
|
| 120 | (@ $self:ident; ($($state:expr),*); $last:ident $(,$not_last:ident)* ) => {
|
| 121 | gen_tuple_value!(@ $self; ($($state .inner,)* $self); $($not_last),* )
|
| 122 | };
|
| 123 | }
|
| 124 |
|
| 125 | /// Generate the trait implementations given a sequence of type names in both directions and the indices backwards:
|
| 126 | /// ```nocheck
|
| 127 | /// generate_single(A, B, C; C, B, A; 2, 1, 0)
|
| 128 | /// ```
|
| 129 | macro_rules! generate_single {
|
| 130 | ( $($name_fwd:ident),* ; $($name_back:ident),* ; $($index_back:tt),*) => {
|
| 131 | impl<$($name_fwd),*> IntoNonRecursive for gen_recursive_type!($($name_back),*) {
|
| 132 | type NonRecursive = ($($name_fwd,)*);
|
| 133 | fn into_non_recursive(self) -> Self::NonRecursive {
|
| 134 | gen_tuple_value!(self; $($name_fwd),*)
|
| 135 | }
|
| 136 | }
|
| 137 |
|
| 138 | impl<$($name_fwd),*> IntoRecursive for ($($name_fwd,)*) {
|
| 139 | type Recursive = gen_recursive_type!($($name_back),*);
|
| 140 | fn into_recursive(self) -> Self::Recursive {
|
| 141 | gen_recursive_value!(self; $($index_back),*)
|
| 142 | }
|
| 143 | }
|
| 144 | };
|
| 145 | }
|
| 146 |
|
| 147 | generate_single!(A; A; 0);
|
| 148 | generate_single!(A,B; B,A; 1,0);
|
| 149 | generate_single!(A,B,C; C,B,A; 2,1,0);
|
| 150 | generate_single!(A,B,C,D; D,C,B,A; 3,2,1,0);
|
| 151 | generate_single!(A,B,C,D,E; E,D,C,B,A; 4,3,2,1,0);
|
| 152 | generate_single!(A,B,C,D,E,F; F,E,D,C,B,A; 5,4,3,2,1,0);
|
| 153 | generate_single!(A,B,C,D,E,F,G; G,F,E,D,C,B,A; 6,5,4,3,2,1,0);
|
| 154 | generate_single!(A,B,C,D,E,F,G,H; H,G,F,E,D,C,B,A; 7,6,5,4,3,2,1,0);
|
| 155 | generate_single!(A,B,C,D,E,F,G,H,I; I,H,G,F,E,D,C,B,A; 8,7,6,5,4,3,2,1,0);
|
| 156 | generate_single!(A,B,C,D,E,F,G,H,I,J; J,I,H,G,F,E,D,C,B,A; 9,8,7,6,5,4,3,2,1,0);
|
| 157 | generate_single!(A,B,C,D,E,F,G,H,I,J,K; K,J,I,H,G,F,E,D,C,B,A; 10,9,8,7,6,5,4,3,2,1,0);
|
| 158 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L; L,K,J,I,H,G,F,E,D,C,B,A; 11,10,9,8,7,6,5,4,3,2,1,0);
|
| 159 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M; M,L,K,J,I,H,G,F,E,D,C,B,A; 12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 160 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N; N,M,L,K,J,I,H,G,F,E,D,C,B,A; 13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 161 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O; O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 162 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P; P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 163 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q; Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 164 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R; R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 165 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S; S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 166 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T; T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 167 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U; U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 168 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V; V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 169 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W; W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 170 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X; X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 171 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y; Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 172 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z; Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 173 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1; A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 174 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1; B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 175 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1; C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 176 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1; D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 177 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1; E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 178 | generate_single!(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1; F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A; 31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
| 179 | |