1use crate::complex_types::{decode_varint_len, encode_varint_len};
2use crate::types::{Key, TypeName, Value};
3use std::borrow::Borrow;
4use std::cmp::Ordering;
5
6fn serialize_tuple_elements_variable<const N: usize>(
7 is_fixed_width: [bool; N],
8 slices: [&[u8]; N],
9) -> Vec<u8> {
10 let total_len: usize = slices.iter().map(|x| x.len()).sum();
11 let worst_case_len_overhead: usize =
12 is_fixed_width.iter().map(|x| if *x { 0 } else { 5 }).sum();
13 let mut output = Vec::with_capacity(total_len + worst_case_len_overhead);
14 let zipped = is_fixed_width.iter().zip(slices.iter());
15 for len in zipped
16 .map(|(fixed, x)| if *fixed { None } else { Some(x.len()) })
17 .take(slices.len() - 1)
18 .flatten()
19 {
20 encode_varint_len(len, &mut output);
21 }
22
23 for slice in slices {
24 output.extend_from_slice(slice);
25 }
26
27 debug_assert!(output.len() <= total_len + worst_case_len_overhead);
28
29 output
30}
31
32fn serialize_tuple_elements_fixed(slices: &[&[u8]]) -> Vec<u8> {
33 let total_len: usize = slices.iter().map(|x| x.len()).sum();
34 let mut output = Vec::with_capacity(total_len);
35 for slice in slices {
36 output.extend_from_slice(slice);
37 }
38 output
39}
40
41fn parse_lens<const N: usize>(fixed_width: [Option<usize>; N], data: &[u8]) -> (usize, [usize; N]) {
42 let mut result = [0; N];
43 let mut offset = 0;
44 for (i, &fixed) in fixed_width.iter().enumerate() {
45 if let Some(len) = fixed {
46 result[i] = len;
47 } else {
48 let (len, bytes_read) = decode_varint_len(&data[offset..]);
49 result[i] = len;
50 offset += bytes_read;
51 }
52 }
53 (offset, result)
54}
55
56fn not_equal<T: Key>(data1: &[u8], data2: &[u8]) -> Option<Ordering> {
57 match T::compare(data1, data2) {
58 Ordering::Less => Some(Ordering::Less),
59 Ordering::Equal => None,
60 Ordering::Greater => Some(Ordering::Greater),
61 }
62}
63
64macro_rules! fixed_width_impl {
65 ( $( $t:ty ),+ ) => {
66 {
67 let mut sum = 0;
68 $(
69 sum += <$t>::fixed_width()?;
70 )+
71 Some(sum)
72 }
73 };
74}
75
76macro_rules! as_bytes_impl {
77 ( $value:expr, $( $t:ty, $i:tt ),+ ) => {{
78 if Self::fixed_width().is_some() {
79 serialize_tuple_elements_fixed(&[
80 $(
81 <$t>::as_bytes($value.$i.borrow()).as_ref(),
82 )+
83 ])
84 } else {
85 serialize_tuple_elements_variable(
86 [
87 $(
88 <$t>::fixed_width().is_some(),
89 )+
90 ],
91 [
92 $(
93 <$t>::as_bytes($value.$i.borrow()).as_ref(),
94 )+
95 ])
96 }
97 }};
98}
99
100macro_rules! type_name_impl {
101 ( $head:ty $(,$tail:ty)+ ) => {
102 {
103 let mut result = String::new();
104 result.push('(');
105 result.push_str(&<$head>::type_name().name());
106 $(
107 result.push(',');
108 result.push_str(&<$tail>::type_name().name());
109 )+
110 result.push(')');
111
112 if Self::fixed_width().is_some() {
113 TypeName::internal(&result)
114 } else {
115 TypeName::internal2(&result)
116 }
117 }
118 };
119}
120
121macro_rules! from_bytes_variable_impl {
122 ( $data:expr $(,$t:ty, $v:ident, $i:literal )+ | $t_last:ty, $v_last:ident, $i_last:literal ) => {
123 #[allow(clippy::manual_bits)]
124 {
125 let (mut offset, lens) = parse_lens::<$i_last>(
126 [
127 $(
128 <$t>::fixed_width(),
129 )+
130 ],
131 $data);
132 $(
133 let len = lens[$i];
134 let $v = <$t>::from_bytes(&$data[offset..(offset + len)]);
135 offset += len;
136 )+
137 let $v_last = <$t_last>::from_bytes(&$data[offset..]);
138 ($(
139 $v,
140 )+
141 $v_last
142 )
143 }
144 };
145}
146
147macro_rules! from_bytes_fixed_impl {
148 ( $data:expr $(,$t:ty, $v:ident )+ ) => {
149 {
150 let mut offset = 0;
151 $(
152 let len = <$t>::fixed_width().unwrap();
153 let $v = <$t>::from_bytes(&$data[offset..(offset + len)]);
154 #[allow(unused_assignments)]
155 {
156 offset += len;
157 }
158 )+
159
160 ($(
161 $v,
162 )+)
163 }
164 };
165}
166
167macro_rules! compare_variable_impl {
168 ( $data0:expr, $data1:expr $(,$t:ty, $i:literal )+ | $t_last:ty, $i_last:literal ) => {
169 #[allow(clippy::manual_bits)]
170 {
171 let fixed_width = [
172 $(
173 <$t>::fixed_width(),
174 )+
175 ];
176 let (mut offset0, lens0) = parse_lens::<$i_last>(fixed_width, $data0);
177 let (mut offset1, lens1) = parse_lens::<$i_last>(fixed_width, $data1);
178 $(
179 let index = $i;
180 let len0 = lens0[index];
181 let len1 = lens1[index];
182 if let Some(order) = not_equal::<$t>(
183 &$data0[offset0..(offset0 + len0)],
184 &$data1[offset1..(offset1 + len1)],
185 ) {
186 return order;
187 }
188 offset0 += len0;
189 offset1 += len1;
190 )+
191
192 <$t_last>::compare(&$data0[offset0..], &$data1[offset1..])
193 }
194 };
195}
196
197macro_rules! compare_fixed_impl {
198 ( $data0:expr, $data1:expr, $($t:ty),+ ) => {
199 {
200 let mut offset0 = 0;
201 let mut offset1 = 0;
202 $(
203 let len = <$t>::fixed_width().unwrap();
204 if let Some(order) = not_equal::<$t>(
205 &$data0[offset0..(offset0 + len)],
206 &$data1[offset1..(offset1 + len)],
207 ) {
208 return order;
209 }
210 #[allow(unused_assignments)]
211 {
212 offset0 += len;
213 offset1 += len;
214 }
215 )+
216
217 Ordering::Equal
218 }
219 };
220}
221
222macro_rules! tuple_impl {
223 ( $($t:ident, $v:ident, $i:tt ),+ | $t_last:ident, $v_last:ident, $i_last:tt ) => {
224 impl<$($t: Value,)+ $t_last: Value> Value for ($($t,)+ $t_last) {
225 type SelfType<'a> = (
226 $(<$t>::SelfType<'a>,)+
227 <$t_last>::SelfType<'a>,
228 )
229 where
230 Self: 'a;
231 type AsBytes<'a> = Vec<u8>
232 where
233 Self: 'a;
234
235 fn fixed_width() -> Option<usize> {
236 fixed_width_impl!($($t,)+ $t_last)
237 }
238
239 fn from_bytes<'a>(data: &'a [u8]) -> Self::SelfType<'a>
240 where
241 Self: 'a,
242 {
243 if Self::fixed_width().is_some() {
244 from_bytes_fixed_impl!(data $(,$t,$v)+, $t_last, $v_last)
245 } else {
246 from_bytes_variable_impl!(data $(,$t,$v,$i)+ | $t_last, $v_last, $i_last)
247 }
248 }
249
250 fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> Vec<u8>
251 where
252 Self: 'a,
253 Self: 'b,
254 {
255 as_bytes_impl!(value, $($t,$i,)+ $t_last, $i_last)
256 }
257
258 fn type_name() -> TypeName {
259 type_name_impl!($($t,)+ $t_last)
260 }
261 }
262
263 impl<$($t: Key,)+ $t_last: Key> Key for ($($t,)+ $t_last) {
264 fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
265 if Self::fixed_width().is_some() {
266 compare_fixed_impl!(data1, data2, $($t,)+ $t_last)
267 } else {
268 compare_variable_impl!(data1, data2 $(,$t,$i)+ | $t_last, $i_last)
269 }
270 }
271 }
272 };
273}
274
275impl<T: Value> Value for (T,) {
276 type SelfType<'a>
277 = (T::SelfType<'a>,)
278 where
279 Self: 'a;
280 type AsBytes<'a>
281 = T::AsBytes<'a>
282 where
283 Self: 'a;
284
285 fn fixed_width() -> Option<usize> {
286 T::fixed_width()
287 }
288
289 fn from_bytes<'a>(data: &'a [u8]) -> Self::SelfType<'a>
290 where
291 Self: 'a,
292 {
293 (T::from_bytes(data),)
294 }
295
296 fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> Self::AsBytes<'a>
297 where
298 Self: 'a,
299 Self: 'b,
300 {
301 T::as_bytes(&value.0)
302 }
303
304 fn type_name() -> TypeName {
305 TypeName::internal(&format!("({},)", T::type_name().name()))
306 }
307}
308
309impl<T: Key> Key for (T,) {
310 fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
311 T::compare(data1, data2)
312 }
313}
314
315tuple_impl! {
316 T0, t0, 0
317 | T1, t1, 1
318}
319
320tuple_impl! {
321 T0, t0, 0,
322 T1, t1, 1
323 | T2, t2, 2
324}
325
326tuple_impl! {
327 T0, t0, 0,
328 T1, t1, 1,
329 T2, t2, 2
330 | T3, t3, 3
331}
332
333tuple_impl! {
334 T0, t0, 0,
335 T1, t1, 1,
336 T2, t2, 2,
337 T3, t3, 3
338 | T4, t4, 4
339}
340
341tuple_impl! {
342 T0, t0, 0,
343 T1, t1, 1,
344 T2, t2, 2,
345 T3, t3, 3,
346 T4, t4, 4
347 | T5, t5, 5
348}
349
350tuple_impl! {
351 T0, t0, 0,
352 T1, t1, 1,
353 T2, t2, 2,
354 T3, t3, 3,
355 T4, t4, 4,
356 T5, t5, 5
357 | T6, t6, 6
358}
359
360tuple_impl! {
361 T0, t0, 0,
362 T1, t1, 1,
363 T2, t2, 2,
364 T3, t3, 3,
365 T4, t4, 4,
366 T5, t5, 5,
367 T6, t6, 6
368 | T7, t7, 7
369}
370
371tuple_impl! {
372 T0, t0, 0,
373 T1, t1, 1,
374 T2, t2, 2,
375 T3, t3, 3,
376 T4, t4, 4,
377 T5, t5, 5,
378 T6, t6, 6,
379 T7, t7, 7
380 | T8, t8, 8
381}
382
383tuple_impl! {
384 T0, t0, 0,
385 T1, t1, 1,
386 T2, t2, 2,
387 T3, t3, 3,
388 T4, t4, 4,
389 T5, t5, 5,
390 T6, t6, 6,
391 T7, t7, 7,
392 T8, t8, 8
393 | T9, t9, 9
394}
395
396tuple_impl! {
397 T0, t0, 0,
398 T1, t1, 1,
399 T2, t2, 2,
400 T3, t3, 3,
401 T4, t4, 4,
402 T5, t5, 5,
403 T6, t6, 6,
404 T7, t7, 7,
405 T8, t8, 8,
406 T9, t9, 9
407 | T10, t10, 10
408}
409
410tuple_impl! {
411 T0, t0, 0,
412 T1, t1, 1,
413 T2, t2, 2,
414 T3, t3, 3,
415 T4, t4, 4,
416 T5, t5, 5,
417 T6, t6, 6,
418 T7, t7, 7,
419 T8, t8, 8,
420 T9, t9, 9,
421 T10, t10, 10
422 | T11, t11, 11
423}
424
425#[cfg(test)]
426mod test {
427 use crate::types::Value;
428
429 #[test]
430 fn width() {
431 assert!(<(&str, u8)>::fixed_width().is_none());
432 assert!(<(u16, u8, &str, u128)>::fixed_width().is_none());
433 assert_eq!(<(u16,)>::fixed_width().unwrap(), 2);
434 assert_eq!(<(u16, u8)>::fixed_width().unwrap(), 3);
435 assert_eq!(<(u16, u8, u128)>::fixed_width().unwrap(), 19);
436 assert_eq!(<(u16, u8, i8, u128)>::fixed_width().unwrap(), 20);
437 assert_eq!(
439 <(u8, &str)>::as_bytes(&(1, "hello")).len(),
440 "hello".len() + size_of::<u8>()
441 );
442 assert_eq!(
444 <(&str, u8)>::as_bytes(&("hello", 1)).len(),
445 "hello".len() + size_of::<u8>() + size_of::<u8>()
446 );
447 }
448}