1#![allow(non_snake_case)]
2
3use crate::prelude::*;
4
5macro_rules! expr {
7 ($x:expr) => {
8 $x
9 };
10} macro_rules! tuple_index {
12 ($tuple:expr, $idx:tt) => {
13 expr!($tuple.$idx)
14 };
15}
16
17macro_rules! parallel_new_rhs {
18 ($opts:ident, ) => {
19 ()
20 };
21 ($opts:ident, $ts:ident) => {
22 $ts::new($ts, $opts)
23 };
24 ($opts:ident, $ts:ident, $($remainder:ident),+) => {
25 parallel(move || $ts::new($ts, $opts), move || parallel_new_rhs!($opts, $($remainder),*), $opts)
26 }
27}
28
29macro_rules! parallel_decode_rhs {
30 ($opts: ident) => {
31 ()
32 };
33 ($opts: ident, $ts:ident) => {
34 $ts::decode($ts, $opts)
35 };
36 ($opts: ident, $ts:ident, $($remainder:ident),+) => {
37 parallel(move || $ts::decode($ts, $opts), move || parallel_decode_rhs!($opts, $($remainder),*), $opts)
38 }
39}
40
41macro_rules! parallel_lhs {
42 () => {
43 ()
44 };
45 ($ts:ident) => {
46 $ts
47 };
48 ($ts:ident, $($remainder:ident),+) => {
49 ($ts, parallel_lhs!($($remainder),*))
50 }
51}
52
53macro_rules! parallel_new {
54 ($opts:ident, $($ts:ident),*) => {
55 let parallel_lhs!($($ts),*) = parallel_new_rhs!($opts, $($ts),*);
56 };
57}
58
59macro_rules! parallel_decode {
60 ($opts:ident, $($ts:ident),*) => {
61 let parallel_lhs!($($ts),*) = parallel_decode_rhs!($opts, $($ts),*);
62 };
63}
64
65macro_rules! impl_tuple {
66 ($count:expr, $trid:expr, $taid:expr, $($ts:ident, $ti:tt,)+) => {
67 #[cfg(feature = "encode")]
68 impl <$($ts: Encodable),+> Encodable for ($($ts),+) {
69 type EncoderArray=($($ts::EncoderArray),+);
70 fn encode_root<O: EncodeOptions>(&self, stream: &mut EncoderStream<'_, O>) -> RootTypeId {
71 profile_method!(encode_root);
72 $(
73 stream.encode_with_id(|stream| tuple_index!(self, $ti).encode_root(stream));
74 )+
75 $trid
76 }
77 }
78
79 #[cfg(feature = "encode")]
80 impl<$($ts: Encodable),+> EncoderArray<($($ts),+)> for ($($ts::EncoderArray),+) {
81 fn buffer_one<'a, 'b: 'a>(&'a mut self, value: &'b ($($ts),+)) {
82 $(
83 tuple_index!(self, $ti).buffer_one(&tuple_index!(value, $ti));
84 )+
85 }
86 fn flush<O: EncodeOptions>(self, stream: &mut EncoderStream<'_, O>) -> ArrayTypeId {
87 profile_method!(flush);
88 let ($($ts,)+) = self;
89 $(
90 stream.encode_with_id(|stream|
91 $ts.flush(stream)
92 );
93 )+
94 $taid
95 }
96 }
97
98 #[cfg(feature = "decode")]
99 impl <$($ts: Decodable + Send),+> Decodable for ($($ts),+)
100 where $(DecodeError : From<<$ts::DecoderArray as DecoderArray>::Error>),+ {
102 type DecoderArray=($($ts::DecoderArray),+);
103 fn decode(sticks: DynRootBranch<'_>, options: &impl DecodeOptions) -> DecodeResult<Self> {
104 profile_method!(decode);
105 match sticks {
106 DynRootBranch::Tuple { mut fields } => {
107 if fields.len() != $count {
109 return Err(DecodeError::SchemaMismatch)
110 }
111 let mut fields = fields.drain(..);
112
113 $(
115 let $ts = fields.next().unwrap();
117 )+
118
119 parallel_decode!(options, $($ts),*);
120
121 Ok(($($ts?),*))
122 },
123 _ => Err(DecodeError::SchemaMismatch),
124 }
125 }
126 }
127
128 #[cfg(feature = "decode")]
129 impl <$($ts: DecoderArray),+> DecoderArray for ($($ts),+)
130 where $(DecodeError : From<$ts::Error>),+ {
132 type Decode=($($ts::Decode),+);
133 type Error=DecodeError;
137 fn new(sticks: DynArrayBranch<'_>, options: &impl DecodeOptions) -> DecodeResult<Self> {
138 profile_method!(new);
139
140 match sticks {
141 DynArrayBranch::Tuple { mut fields } => {
142 if fields.len() != $count {
144 return Err(DecodeError::SchemaMismatch)
145 }
146 let mut fields = fields.drain(..);
147
148 $(
150 let $ts = fields.next().unwrap();
152 )+
153
154 parallel_new!(options, $($ts),*);
155
156 Ok(($($ts?),*))
157 },
158 _ => Err(DecodeError::SchemaMismatch)
159 }
160 }
161 fn decode_next(&mut self) -> Result<Self::Decode, Self::Error> {
162 Ok(($(
163 tuple_index!(self, $ti).decode_next()?,
164 )+))
165 }
166 }
167
168 impl<T, $($ts: Compressor<T>,)+> CompressorSet<T> for ($($ts,)+) {
169 fn len(&self) -> usize {
170 $count
171 }
172 fn fast_size_for<O: EncodeOptions>(&self, compressor: usize, data: &[T], options: &O) -> Result<usize, ()> {
173 match compressor {
174 $($ti => tuple_index!(self, $ti).fast_size_for(data, options),)+
175 _ => unreachable!("No compressor at that index"),
176 }
177 }
178 fn compress<O: EncodeOptions>(&self, compressor: usize, data: &[T], stream: &mut EncoderStream<'_, O>) -> Result<ArrayTypeId, ()> {
179 match compressor {
180 $($ti => tuple_index!(self, $ti).compress(data, stream),)+
181 _ => unreachable!("No compressor at that index"),
182 }
183 }
184 }
185 };
186}
187
188impl<T, T0: Compressor<T>> CompressorSet<T> for (T0,) {
189 fn len(&self) -> usize {
190 1
191 }
192 fn fast_size_for<O: EncodeOptions>(&self, compressor: usize, data: &[T], options: &O) -> Result<usize, ()> {
193 match compressor {
194 0 => self.0.fast_size_for(data, options),
195 _ => unreachable!("No compressor at that index"),
196 }
197 }
198 fn compress<O: EncodeOptions>(&self, compressor: usize, data: &[T], stream: &mut EncoderStream<'_, O>) -> Result<ArrayTypeId, ()> {
199 match compressor {
200 0 => self.0.compress(data, stream),
201 _ => unreachable!("No compressor at that index"),
202 }
203 }
204}
205
206impl_tuple!(2, RootTypeId::Tuple2, ArrayTypeId::Tuple2, T0, 0, T1, 1,);
213impl_tuple!(3, RootTypeId::Tuple3, ArrayTypeId::Tuple3, T0, 0, T1, 1, T2, 2,);
214impl_tuple!(4, RootTypeId::Tuple4, ArrayTypeId::Tuple4, T0, 0, T1, 1, T2, 2, T3, 3,);
215impl_tuple!(5, RootTypeId::Tuple5, ArrayTypeId::Tuple5, T0, 0, T1, 1, T2, 2, T3, 3, T4, 4,);
216impl_tuple!(6, RootTypeId::Tuple6, ArrayTypeId::Tuple6, T0, 0, T1, 1, T2, 2, T3, 3, T4, 4, T5, 5,);
217
218