foundationdb_tuple/
pack.rs

1use super::*;
2use memchr::memchr_iter;
3use std::convert::TryFrom;
4use std::io;
5use std::mem;
6
7#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
8pub enum VersionstampOffset {
9    None { size: u32 },
10    OneIncomplete { offset: u32 },
11    MultipleIncomplete,
12}
13impl std::ops::AddAssign<u32> for VersionstampOffset {
14    fn add_assign(&mut self, r: u32) {
15        if let VersionstampOffset::None { size } = self {
16            *size += r;
17        }
18    }
19}
20impl std::ops::AddAssign for VersionstampOffset {
21    fn add_assign(&mut self, rhs: Self) {
22        match (&mut *self, rhs) {
23            (VersionstampOffset::None { size }, VersionstampOffset::None { size: r }) => {
24                *size += r;
25            }
26            (VersionstampOffset::None { size }, VersionstampOffset::OneIncomplete { offset }) => {
27                *self = VersionstampOffset::OneIncomplete {
28                    offset: *size + offset,
29                };
30            }
31            (
32                VersionstampOffset::OneIncomplete { .. },
33                VersionstampOffset::OneIncomplete { .. },
34            )
35            | (VersionstampOffset::None { .. }, VersionstampOffset::MultipleIncomplete)
36            | (VersionstampOffset::OneIncomplete { .. }, VersionstampOffset::MultipleIncomplete) => {
37                *self = VersionstampOffset::MultipleIncomplete;
38            }
39            _ => {}
40        }
41    }
42}
43
44const PACK_ERR_MSG: &str = "pack io error on Vec, data size didn't fit in `u32`?";
45
46/// A type that can be packed
47pub trait TuplePack {
48    fn pack<W: io::Write>(
49        &self,
50        w: &mut W,
51        tuple_depth: TupleDepth,
52    ) -> io::Result<VersionstampOffset>;
53
54    fn pack_root<W: io::Write>(&self, w: &mut W) -> io::Result<VersionstampOffset> {
55        self.pack(w, TupleDepth::new())
56    }
57
58    /// Pack value and returns the packed buffer
59    ///
60    /// # Panics
61    ///
62    /// Panics if the encoded data size doesn't fit in `u32`.
63    fn pack_to_vec(&self) -> Vec<u8> {
64        let mut vec = Vec::new();
65        self.pack_into_vec(&mut vec);
66        vec
67    }
68
69    /// Pack value and returns the packed buffer
70    ///
71    /// # Panics
72    ///
73    /// Panics if there is multiple versionstamp present or if the encoded data size doesn't fit in `u32`.
74    fn pack_to_vec_with_versionstamp(&self) -> Vec<u8> {
75        let mut vec = Vec::new();
76        let offset = self.pack_into_vec_with_versionstamp(&mut vec);
77        if let VersionstampOffset::MultipleIncomplete = offset {
78            panic!("pack_to_vec_with_versionstamp does not allow multiple versionstamps");
79        }
80        vec
81    }
82
83    /// Pack value into the given buffer
84    ///
85    /// # Panics
86    ///
87    /// Panics if the encoded data size doesn't fit in `u32`.
88    fn pack_into_vec(&self, output: &mut Vec<u8>) -> VersionstampOffset {
89        self.pack_root(output).expect(PACK_ERR_MSG)
90    }
91
92    /// Pack value into the given buffer
93    ///
94    /// # Panics
95    ///
96    /// Panics if the encoded data size doesn't fit in `u32`.
97    fn pack_into_vec_with_versionstamp(&self, output: &mut Vec<u8>) -> VersionstampOffset {
98        let mut offset = VersionstampOffset::None {
99            size: u32::try_from(output.len()).expect(PACK_ERR_MSG),
100        };
101        offset += self.pack_root(output).expect(PACK_ERR_MSG);
102        if let VersionstampOffset::OneIncomplete { offset } = offset {
103            output.extend_from_slice(&offset.to_le_bytes());
104        }
105        offset
106    }
107}
108
109/// A type that can be unpacked
110pub trait TupleUnpack<'de>: Sized {
111    fn unpack(input: &'de [u8], tuple_depth: TupleDepth) -> PackResult<(&'de [u8], Self)>;
112
113    fn unpack_root(input: &'de [u8]) -> PackResult<Self> {
114        let (input, this) = Self::unpack(input, TupleDepth::new())?;
115        if !input.is_empty() {
116            return Err(PackError::TrailingBytes);
117        }
118        Ok(this)
119    }
120}
121
122impl<T> TuplePack for &T
123where
124    T: TuplePack,
125{
126    fn pack<W: io::Write>(
127        &self,
128        w: &mut W,
129        tuple_depth: TupleDepth,
130    ) -> io::Result<VersionstampOffset> {
131        (*self).pack(w, tuple_depth)
132    }
133}
134
135#[inline]
136fn parse_bytes(input: &[u8], num: usize) -> PackResult<(&[u8], &[u8])> {
137    if input.len() < num {
138        Err(PackError::MissingBytes)
139    } else {
140        Ok((&input[num..], &input[..num]))
141    }
142}
143
144#[inline]
145fn parse_byte(input: &[u8]) -> PackResult<(&[u8], u8)> {
146    if input.is_empty() {
147        Err(PackError::MissingBytes)
148    } else {
149        Ok((&input[1..], input[0]))
150    }
151}
152
153fn parse_code(input: &[u8], expected: u8) -> PackResult<&[u8]> {
154    let (input, found) = parse_byte(input)?;
155    if found == expected {
156        Ok(input)
157    } else {
158        Err(PackError::BadCode {
159            found,
160            expected: Some(expected),
161        })
162    }
163}
164
165fn write_bytes<W: io::Write>(w: &mut W, v: &[u8]) -> io::Result<VersionstampOffset> {
166    let mut size =
167        u32::try_from(v.len()).map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
168    let mut pos = 0;
169    for idx in memchr_iter(NIL, v) {
170        let next_idx = idx + 1;
171        size += 1;
172        w.write_all(&v[pos..next_idx])?;
173        w.write_all(&[ESCAPE])?;
174        pos = next_idx;
175    }
176    w.write_all(&v[pos..])?;
177    w.write_all(&[NIL])?;
178    size += 2;
179    Ok(VersionstampOffset::None { size })
180}
181
182fn parse_slice(input: &[u8]) -> PackResult<(&[u8], Cow<[u8]>)> {
183    let mut bytes = Vec::new();
184    let mut pos = 0;
185    for idx in memchr_iter(NIL, input) {
186        let next_idx = idx + 1;
187        if input.get(next_idx) == Some(&ESCAPE) {
188            bytes.extend_from_slice(&input[pos..next_idx]);
189            pos = next_idx + 1;
190        } else {
191            let slice = &input[pos..idx];
192            return Ok((
193                &input[next_idx..],
194                (if pos == 0 {
195                    Cow::Borrowed(slice)
196                } else {
197                    bytes.extend_from_slice(slice);
198                    Cow::Owned(bytes)
199                }),
200            ));
201        }
202    }
203    Err(PackError::MissingBytes)
204}
205
206fn parse_string(input: &[u8]) -> PackResult<(&[u8], Cow<str>)> {
207    let (input, slice) = parse_slice(input)?;
208    Ok((
209        input,
210        match slice {
211            Cow::Borrowed(slice) => {
212                Cow::Borrowed(std::str::from_utf8(slice).map_err(|_| PackError::BadStringFormat)?)
213            }
214            Cow::Owned(vec) => {
215                Cow::Owned(String::from_utf8(vec).map_err(|_| PackError::BadStringFormat)?)
216            }
217        },
218    ))
219}
220
221impl TuplePack for () {
222    fn pack<W: io::Write>(
223        &self,
224        w: &mut W,
225        tuple_depth: TupleDepth,
226    ) -> io::Result<VersionstampOffset> {
227        if tuple_depth.depth() > 0 {
228            w.write_all(&[NESTED, NIL])?;
229            Ok(VersionstampOffset::None { size: 2 })
230        } else {
231            Ok(VersionstampOffset::None { size: 0 })
232        }
233    }
234}
235
236impl TupleUnpack<'_> for () {
237    fn unpack(mut input: &[u8], tuple_depth: TupleDepth) -> PackResult<(&[u8], Self)> {
238        if tuple_depth.depth() > 0 {
239            input = parse_code(input, NESTED)?;
240            input = parse_code(input, NIL)?;
241        }
242        Ok((input, ()))
243    }
244}
245
246macro_rules! tuple_impls {
247    ($(($($n:tt $name:ident $v:ident)+))+) => {
248        $(
249            impl<$($name),+> TuplePack for ($($name,)+)
250            where
251                $($name: TuplePack,)+
252            {
253                fn pack<W: io::Write>(&self, w: &mut W, tuple_depth: TupleDepth) -> io::Result<VersionstampOffset> {
254                    let mut offset = VersionstampOffset::None { size: 0 };
255                    if tuple_depth.depth() > 0 {
256                        w.write_all(&[NESTED])?;
257                        offset += 1;
258                    }
259
260                    $(
261                        offset += self.$n.pack(w, tuple_depth.increment())?;
262                    )*
263
264                    if tuple_depth.depth() > 0 {
265                        w.write_all(&[NIL])?;
266                        offset += 1;
267                    }
268                    Ok(offset)
269                }
270            }
271
272            impl<'de, $($name),+> TupleUnpack<'de> for ($($name,)+)
273            where
274                $($name: TupleUnpack<'de>,)+
275            {
276                fn unpack(input: &'de [u8], tuple_depth: TupleDepth) -> PackResult<(&'de [u8], Self)> {
277                    let input = if tuple_depth.depth() > 0 { parse_code(input, NESTED)? } else { input };
278
279                    $(
280                        let (input, $v) = $name::unpack(input, tuple_depth.increment())?;
281                    )*
282
283                    let input = if tuple_depth.depth() > 0 { parse_code(input, NIL)? } else { input };
284
285                    let tuple = ( $($v,)* );
286                    Ok((input, tuple))
287                }
288            }
289        )+
290    }
291}
292
293tuple_impls! {
294    (0 T0 t0)
295    (0 T0 t0 1 T1 t1)
296    (0 T0 t0 1 T1 t1 2 T2 t2)
297    (0 T0 t0 1 T1 t1 2 T2 t2 3 T3 t3)
298    (0 T0 t0 1 T1 t1 2 T2 t2 3 T3 t3 4 T4 t4)
299    (0 T0 t0 1 T1 t1 2 T2 t2 3 T3 t3 4 T4 t4 5 T5 t5)
300    (0 T0 t0 1 T1 t1 2 T2 t2 3 T3 t3 4 T4 t4 5 T5 t5 6 T6 t6)
301    (0 T0 t0 1 T1 t1 2 T2 t2 3 T3 t3 4 T4 t4 5 T5 t5 6 T6 t6 7 T7 t7)
302    (0 T0 t0 1 T1 t1 2 T2 t2 3 T3 t3 4 T4 t4 5 T5 t5 6 T6 t6 7 T7 t7 8 T8 t8)
303    (0 T0 t0 1 T1 t1 2 T2 t2 3 T3 t3 4 T4 t4 5 T5 t5 6 T6 t6 7 T7 t7 8 T8 t8 9 T9 t9)
304    (0 T0 t0 1 T1 t1 2 T2 t2 3 T3 t3 4 T4 t4 5 T5 t5 6 T6 t6 7 T7 t7 8 T8 t8 9 T9 t9 10 T10 t10)
305    (0 T0 t0 1 T1 t1 2 T2 t2 3 T3 t3 4 T4 t4 5 T5 t5 6 T6 t6 7 T7 t7 8 T8 t8 9 T9 t9 10 T10 t10 11 T11 t11)
306}
307
308const MAX_SZ: usize = 8;
309
310macro_rules! sign_bit {
311    ($type:ident) => {
312        (1 << (mem::size_of::<$type>() * 8 - 1))
313    };
314}
315
316macro_rules! unpack_ux {
317    ($ux: ident, $input: expr, $n: expr) => {{
318        let (input, bytes) = parse_bytes($input, $n)?;
319        let mut arr = [0u8; ::std::mem::size_of::<$ux>()];
320        (&mut arr[(::std::mem::size_of::<$ux>() - $n)..]).copy_from_slice(bytes);
321        (input, $ux::from_be_bytes(arr))
322    }};
323}
324
325macro_rules! unpack_px {
326    ($ix: ident, $ux: ident, $input: expr, $n: expr) => {{
327        let (input, bytes) = parse_bytes($input, $n)?;
328        let mut arr = [0u8; ::std::mem::size_of::<$ux>()];
329        (&mut arr[(::std::mem::size_of::<$ux>() - $n)..]).copy_from_slice(bytes);
330        let x = $ix::from_be_bytes(arr);
331        if x < 0 {
332            Err(PackError::UnsupportedIntLength)
333        } else {
334            Ok((input, x))
335        }
336    }};
337}
338macro_rules! unpack_nx {
339    ($ix: ident, $ux: ident, $input: expr, $n: expr) => {{
340        let (input, bytes) = parse_bytes($input, $n)?;
341        let mut arr = [0xffu8; ::std::mem::size_of::<$ix>()];
342        (&mut arr[(::std::mem::size_of::<$ix>() - $n)..]).copy_from_slice(bytes);
343        let x = $ix::from_be_bytes(arr).wrapping_add(1);
344        if x > 0 {
345            Err(PackError::UnsupportedIntLength)
346        } else {
347            Ok((input, x))
348        }
349    }};
350}
351
352macro_rules! impl_ux {
353    ($ux: ident) => {
354        impl_ux!($ux, mem::size_of::<$ux>());
355    };
356    ($ux: ident, $max_sz:expr) => {
357        impl TuplePack for $ux {
358            fn pack<W: io::Write>(
359                &self,
360                w: &mut W,
361                _tuple_depth: TupleDepth,
362            ) -> io::Result<VersionstampOffset> {
363                const SZ: usize = mem::size_of::<$ux>();
364                let u = *self;
365                let n = SZ - (u.leading_zeros() as usize) / 8;
366                let mut offset = VersionstampOffset::None { size: n as u32 + 1 };
367                if SZ <= MAX_SZ || n <= MAX_SZ {
368                    w.write_all(&[INTZERO + n as u8])?;
369                } else {
370                    w.write_all(&[POSINTEND, n as u8])?;
371                    offset += 1;
372                };
373                w.write_all(&u.to_be_bytes()[SZ - n..])?;
374
375                Ok(offset)
376            }
377        }
378
379        impl<'de> TupleUnpack<'de> for $ux {
380            fn unpack(input: &[u8], _tuple_depth: TupleDepth) -> PackResult<(&[u8], Self)> {
381                const SZ: usize = mem::size_of::<$ux>();
382                let (input, found) = parse_byte(input)?;
383                if INTZERO <= found && found <= INTZERO + $max_sz as u8 {
384                    let n = (found - INTZERO) as usize;
385                    Ok(unpack_ux!($ux, input, n))
386                } else if found == POSINTEND {
387                    let (input, raw_length) = parse_byte(input)?;
388                    let n: usize = usize::from(raw_length);
389                    if n > SZ {
390                        return Err(PackError::UnsupportedIntLength);
391                    }
392                    Ok(unpack_ux!($ux, input, n))
393                } else {
394                    Err(PackError::BadCode {
395                        found,
396                        expected: None,
397                    })
398                }
399            }
400        }
401    };
402}
403
404macro_rules! impl_ix {
405    ($ix: ident, $ux: ident) => {
406        impl_ix!($ix, $ux, mem::size_of::<$ix>());
407    };
408    ($ix: ident, $ux: ident, $max_sz:expr) => {
409        impl TuplePack for $ix {
410            fn pack<W: io::Write>(
411                &self,
412                w: &mut W,
413                _tuple_depth: TupleDepth,
414            ) -> io::Result<VersionstampOffset> {
415                const SZ: usize = mem::size_of::<$ix>();
416                let i = *self;
417                let u = self.wrapping_abs() as $ux;
418                let n = SZ - (u.leading_zeros() as usize) / 8;
419                let mut offset = VersionstampOffset::None { size: n as u32 + 1 };
420                let arr = if i >= 0 {
421                    if SZ <= MAX_SZ || n <= MAX_SZ {
422                        w.write_all(&[INTZERO + n as u8])?;
423                    } else {
424                        w.write_all(&[POSINTEND, n as u8])?;
425                        offset += 1;
426                    }
427                    (u.to_be_bytes())
428                } else {
429                    if SZ <= MAX_SZ || n <= MAX_SZ {
430                        w.write_all(&[INTZERO - n as u8])?;
431                    } else {
432                        w.write_all(&[NEGINTSTART, n as u8 ^ 0xff])?;
433                        offset += 1;
434                    }
435                    (i.wrapping_sub(1).to_be_bytes())
436                };
437                w.write_all(&arr[SZ - n..])?;
438
439                Ok(offset)
440            }
441        }
442
443        impl<'de> TupleUnpack<'de> for $ix {
444            fn unpack(input: &[u8], _tuple_depth: TupleDepth) -> PackResult<(&[u8], Self)> {
445                const SZ: usize = mem::size_of::<$ix>();
446                let (input, found) = parse_byte(input)?;
447                if INTZERO <= found && found <= INTZERO + $max_sz as u8 {
448                    let n = (found - INTZERO) as usize;
449                    unpack_px!($ix, $ux, input, n)
450                } else if INTZERO - $max_sz as u8 <= found && found < INTZERO {
451                    let n = (INTZERO - found) as usize;
452                    unpack_nx!($ix, $ux, input, n)
453                } else if found == NEGINTSTART {
454                    let (input, raw_length) = parse_byte(input)?;
455                    let n = usize::from(raw_length ^ 0xff);
456                    if n > SZ {
457                        return Err(PackError::UnsupportedIntLength);
458                    }
459                    unpack_nx!($ix, $ux, input, n)
460                } else if found == POSINTEND {
461                    let (input, raw_length) = parse_byte(input)?;
462                    let n: usize = usize::from(raw_length);
463                    if n > SZ {
464                        return Err(PackError::UnsupportedIntLength);
465                    }
466                    unpack_px!($ix, $ux, input, n)
467                } else {
468                    Err(PackError::BadCode {
469                        found,
470                        expected: None,
471                    })
472                }
473            }
474        }
475    };
476}
477
478macro_rules! impl_fx {
479    ( $fx: ident, $fx_to_ux_be_bytes: ident, $ux_width: tt, $parse_ux: ident, $ux: ident, $code: ident) => {
480        #[inline]
481        pub(super) fn $fx_to_ux_be_bytes(f: $fx) -> [u8; $ux_width] {
482            let u = if f.is_sign_negative() {
483                f.to_bits() ^ $ux::MAX
484            } else {
485                f.to_bits() ^ sign_bit!($ux)
486            };
487            u.to_be_bytes()
488        }
489        impl TuplePack for $fx {
490            fn pack<W: io::Write>(
491                &self,
492                w: &mut W,
493                _tuple_depth: TupleDepth,
494            ) -> io::Result<VersionstampOffset> {
495                let bytes = $fx_to_ux_be_bytes(*self);
496                w.write_all(&[$code])?;
497                w.write_all(&bytes)?;
498                Ok(VersionstampOffset::None {
499                    size: std::mem::size_of::<$fx>() as u32 + 1,
500                })
501            }
502        }
503
504        fn $parse_ux(input: &[u8]) -> PackResult<(&[u8], $ux)> {
505            let (input, bytes) = parse_bytes(input, mem::size_of::<$ux>())?;
506            let mut arr = [0u8; mem::size_of::<$ux>()];
507            arr.copy_from_slice(bytes);
508            Ok((input, $ux::from_be_bytes(arr)))
509        }
510        impl<'de> TupleUnpack<'de> for $fx {
511            fn unpack(input: &[u8], _tuple_depth: TupleDepth) -> PackResult<(&[u8], Self)> {
512                let input = parse_code(input, $code)?;
513                let (input, u) = $parse_ux(input)?;
514                Ok((
515                    input,
516                    $fx::from_bits(if (u & sign_bit!($ux)) == 0 {
517                        u ^ $ux::MAX
518                    } else {
519                        u ^ sign_bit!($ux)
520                    }),
521                ))
522            }
523        }
524    };
525}
526
527//impl_ux!(u8);
528impl_ux!(u16);
529impl_ux!(u32);
530impl_ux!(u64);
531impl_ux!(u128, MAX_SZ);
532impl_ux!(usize);
533
534//impl_ix!(i8, u8);
535impl_ix!(i16, u16);
536impl_ix!(i32, u32);
537impl_ix!(i64, u64);
538impl_ix!(i128, u128, MAX_SZ);
539impl_ix!(isize, usize);
540
541impl_fx!(f32, f32_to_u32_be_bytes, 4, parse_u32, u32, FLOAT);
542impl_fx!(f64, f64_to_u64_be_bytes, 8, parse_u64, u64, DOUBLE);
543
544#[cfg(feature = "num-bigint")]
545mod bigint {
546    use super::*;
547    use num_bigint::{BigInt, BigUint, Sign};
548    use std::convert::TryFrom;
549
550    fn invert(bytes: &mut [u8]) {
551        // The ones' complement of a binary number is defined as the value
552        // obtained by inverting all the bits in the binary representation
553        // of the number (swapping 0s for 1s and vice versa).
554        for byte in bytes.iter_mut() {
555            *byte = !*byte;
556        }
557    }
558
559    fn inverted(bytes: &[u8]) -> Vec<u8> {
560        // The ones' complement of a binary number is defined as the value
561        // obtained by inverting all the bits in the binary representation
562        // of the number (swapping 0s for 1s and vice versa).
563        bytes.iter().map(|byte| !*byte).collect()
564    }
565
566    fn bigint_n(n: usize) -> io::Result<u8> {
567        u8::try_from(n).map_err(|_| {
568            std::io::Error::new(
569                std::io::ErrorKind::InvalidInput,
570                "BigUint requires more than 255 bytes to be represented",
571            )
572        })
573    }
574
575    impl TuplePack for BigInt {
576        fn pack<W: io::Write>(
577            &self,
578            w: &mut W,
579            _tuple_depth: TupleDepth,
580        ) -> io::Result<VersionstampOffset> {
581            if self.sign() == Sign::NoSign {
582                w.write_all(&[INTZERO])?;
583                return Ok(VersionstampOffset::None { size: 1 });
584            }
585            let (sign, mut bytes) = self.to_bytes_be();
586            let n = bytes.len();
587            let mut offset = VersionstampOffset::None { size: n as u32 + 1 };
588            match sign {
589                Sign::Minus => {
590                    if n <= MAX_SZ {
591                        w.write_all(&[INTZERO - n as u8])?;
592                    } else {
593                        w.write_all(&[NEGINTSTART, bigint_n(n)? ^ 0xff])?;
594                        offset += 1;
595                    }
596                    invert(&mut bytes);
597                    w.write_all(&bytes)?;
598                }
599                Sign::NoSign => unreachable!(),
600                Sign::Plus => {
601                    if n <= MAX_SZ {
602                        w.write_all(&[INTZERO + n as u8])?;
603                    } else {
604                        w.write_all(&[POSINTEND, bigint_n(n)?])?;
605                        offset += 1;
606                    }
607                    w.write_all(&bytes)?;
608                }
609            }
610
611            Ok(offset)
612        }
613    }
614
615    impl TupleUnpack<'_> for BigInt {
616        fn unpack(input: &[u8], _tuple_depth: TupleDepth) -> PackResult<(&[u8], Self)> {
617            let (input, found) = parse_byte(input)?;
618            if INTZERO <= found && found <= INTZERO + MAX_SZ as u8 {
619                let n = (found - INTZERO) as usize;
620                let (input, bytes) = parse_bytes(input, n)?;
621                Ok((input, Self::from_bytes_be(Sign::Plus, bytes)))
622            } else if INTZERO - MAX_SZ as u8 <= found && found < INTZERO {
623                let n = (INTZERO - found) as usize;
624                let (input, bytes) = parse_bytes(input, n)?;
625                Ok((input, Self::from_bytes_be(Sign::Minus, &inverted(bytes))))
626            } else if found == NEGINTSTART {
627                let (input, raw_length) = parse_byte(input)?;
628                let n = usize::from(raw_length ^ 0xff);
629                let (input, bytes) = parse_bytes(input, n)?;
630                Ok((input, Self::from_bytes_be(Sign::Minus, &inverted(bytes))))
631            } else if found == POSINTEND {
632                let (input, raw_length) = parse_byte(input)?;
633                let n: usize = usize::from(raw_length);
634                let (input, bytes) = parse_bytes(input, n)?;
635                Ok((input, Self::from_bytes_be(Sign::Plus, bytes)))
636            } else {
637                Err(PackError::BadCode {
638                    found,
639                    expected: None,
640                })
641            }
642        }
643    }
644
645    impl TuplePack for BigUint {
646        fn pack<W: io::Write>(
647            &self,
648            w: &mut W,
649            _tuple_depth: TupleDepth,
650        ) -> io::Result<VersionstampOffset> {
651            let n = self.bits();
652            if n == 0 {
653                w.write_all(&[INTZERO])?;
654                return Ok(VersionstampOffset::None { size: 1 });
655            }
656            let bytes = self.to_bytes_be();
657            let n = bytes.len();
658            let mut offset = VersionstampOffset::None { size: n as u32 + 1 };
659            if n <= MAX_SZ {
660                w.write_all(&[INTZERO + n as u8])?;
661            } else {
662                w.write_all(&[POSINTEND, bigint_n(n)?])?;
663                offset += 1;
664            }
665            w.write_all(&bytes)?;
666
667            Ok(offset)
668        }
669    }
670
671    impl TupleUnpack<'_> for BigUint {
672        fn unpack(input: &[u8], _tuple_depth: TupleDepth) -> PackResult<(&[u8], Self)> {
673            let (input, found) = parse_byte(input)?;
674            if INTZERO <= found && found <= INTZERO + MAX_SZ as u8 {
675                let n = (found - INTZERO) as usize;
676                let (input, bytes) = parse_bytes(input, n)?;
677                Ok((input, Self::from_bytes_be(bytes)))
678            } else if found == POSINTEND {
679                let (input, raw_length) = parse_byte(input)?;
680                let n: usize = usize::from(raw_length);
681                let (input, bytes) = parse_bytes(input, n)?;
682                Ok((input, Self::from_bytes_be(bytes)))
683            } else {
684                Err(PackError::BadCode {
685                    found,
686                    expected: None,
687                })
688            }
689        }
690    }
691}
692
693impl TuplePack for bool {
694    fn pack<W: io::Write>(
695        &self,
696        w: &mut W,
697        _tuple_depth: TupleDepth,
698    ) -> io::Result<VersionstampOffset> {
699        w.write_all(&[if *self { TRUE } else { FALSE }])?;
700        Ok(VersionstampOffset::None { size: 1 })
701    }
702}
703
704impl TupleUnpack<'_> for bool {
705    fn unpack(input: &[u8], _tuple_depth: TupleDepth) -> PackResult<(&[u8], Self)> {
706        let (input, v) = parse_byte(input)?;
707        match v {
708            FALSE => Ok((input, false)),
709            TRUE => Ok((input, true)),
710            _ => Err(PackError::Message(
711                format!("{} is not a valid bool value", v).into_boxed_str(),
712            )),
713        }
714    }
715}
716
717impl<T> TuplePack for &[T]
718where
719    T: TuplePack,
720{
721    fn pack<W: io::Write>(
722        &self,
723        w: &mut W,
724        tuple_depth: TupleDepth,
725    ) -> io::Result<VersionstampOffset> {
726        let mut offset = VersionstampOffset::None { size: 0 };
727
728        if tuple_depth.depth() > 0 {
729            w.write_all(&[NESTED])?;
730            offset += 1;
731        }
732
733        for v in self.iter() {
734            offset += v.pack(w, tuple_depth.increment())?;
735        }
736
737        if tuple_depth.depth() > 0 {
738            w.write_all(&[NIL])?;
739            offset += 1;
740        }
741        Ok(offset)
742    }
743}
744
745impl<T> TuplePack for Vec<T>
746where
747    T: TuplePack,
748{
749    fn pack<W: io::Write>(
750        &self,
751        w: &mut W,
752        tuple_depth: TupleDepth,
753    ) -> io::Result<VersionstampOffset> {
754        self.as_slice().pack(w, tuple_depth)
755    }
756}
757
758fn is_end_of_tuple(input: &[u8], nested: bool) -> bool {
759    match input.first() {
760        None => true,
761        _ if !nested => false,
762        Some(&NIL) => Some(&ESCAPE) != input.get(1),
763        _ => false,
764    }
765}
766
767impl<'de, T> TupleUnpack<'de> for Vec<T>
768where
769    T: TupleUnpack<'de>,
770{
771    fn unpack(mut input: &'de [u8], tuple_depth: TupleDepth) -> PackResult<(&'de [u8], Self)> {
772        let nested = tuple_depth.depth() > 0;
773        if nested {
774            input = parse_code(input, NESTED)?;
775        }
776
777        let mut vec = Vec::new();
778
779        while !is_end_of_tuple(input, nested) {
780            let (rem, v) = T::unpack(input, tuple_depth.increment())?;
781            input = rem;
782            vec.push(v);
783        }
784
785        if nested {
786            input = parse_code(input, NIL)?;
787        }
788
789        Ok((input, vec))
790    }
791}
792
793impl TuplePack for Bytes<'_> {
794    fn pack<W: io::Write>(
795        &self,
796        w: &mut W,
797        _tuple_depth: TupleDepth,
798    ) -> io::Result<VersionstampOffset> {
799        w.write_all(&[BYTES])?;
800        write_bytes(w, self.as_ref())
801    }
802}
803
804impl<'de> TupleUnpack<'de> for Bytes<'de> {
805    fn unpack(input: &'de [u8], _tuple_depth: TupleDepth) -> PackResult<(&'de [u8], Self)> {
806        let input = parse_code(input, BYTES)?;
807        let (input, v) = parse_slice(input)?;
808        Ok((input, Bytes(v)))
809    }
810}
811
812impl TuplePack for &[u8] {
813    fn pack<W: io::Write>(
814        &self,
815        w: &mut W,
816        tuple_depth: TupleDepth,
817    ) -> io::Result<VersionstampOffset> {
818        Bytes::from(*self).pack(w, tuple_depth)
819    }
820}
821
822impl TuplePack for Vec<u8> {
823    fn pack<W: io::Write>(
824        &self,
825        w: &mut W,
826        tuple_depth: TupleDepth,
827    ) -> io::Result<VersionstampOffset> {
828        Bytes::from(self.as_slice()).pack(w, tuple_depth)
829    }
830}
831
832impl<'de> TupleUnpack<'de> for Vec<u8> {
833    fn unpack(input: &'de [u8], tuple_depth: TupleDepth) -> PackResult<(&'de [u8], Self)> {
834        let (input, bytes) = Bytes::unpack(input, tuple_depth)?;
835        Ok((input, bytes.into_owned()))
836    }
837}
838
839impl TuplePack for &str {
840    fn pack<W: io::Write>(
841        &self,
842        w: &mut W,
843        _tuple_depth: TupleDepth,
844    ) -> io::Result<VersionstampOffset> {
845        w.write_all(&[STRING])?;
846        write_bytes(w, self.as_bytes())
847    }
848}
849
850impl TuplePack for String {
851    fn pack<W: io::Write>(
852        &self,
853        w: &mut W,
854        tuple_depth: TupleDepth,
855    ) -> io::Result<VersionstampOffset> {
856        self.as_str().pack(w, tuple_depth)
857    }
858}
859
860impl TuplePack for Cow<'_, str> {
861    fn pack<W: io::Write>(
862        &self,
863        w: &mut W,
864        tuple_depth: TupleDepth,
865    ) -> io::Result<VersionstampOffset> {
866        self.as_ref().pack(w, tuple_depth)
867    }
868}
869
870impl<'de> TupleUnpack<'de> for Cow<'de, str> {
871    fn unpack(input: &'de [u8], _tuple_depth: TupleDepth) -> PackResult<(&'de [u8], Self)> {
872        let input = parse_code(input, STRING)?;
873        let (input, v) = parse_string(input)?;
874        Ok((input, v))
875    }
876}
877
878impl TupleUnpack<'_> for String {
879    fn unpack(input: &[u8], _tuple_depth: TupleDepth) -> PackResult<(&[u8], Self)> {
880        let input = parse_code(input, STRING)?;
881        let (input, v) = parse_string(input)?;
882        Ok((input, v.into_owned()))
883    }
884}
885
886impl<T> TuplePack for Option<T>
887where
888    T: TuplePack,
889{
890    fn pack<W: io::Write>(
891        &self,
892        w: &mut W,
893        tuple_depth: TupleDepth,
894    ) -> io::Result<VersionstampOffset> {
895        match self {
896            None => {
897                let size = if tuple_depth.depth() > 1 {
898                    // Empty value in nested tuple is encoded with [NIL, ESCAPE] to
899                    // disambiguate itself with end-of-tuple marker.
900                    w.write_all(&[NIL, ESCAPE])?;
901                    2
902                } else {
903                    w.write_all(&[NIL])?;
904                    1
905                };
906                Ok(VersionstampOffset::None { size })
907            }
908            Some(v) => v.pack(w, tuple_depth),
909        }
910    }
911}
912
913impl<'de, T> TupleUnpack<'de> for Option<T>
914where
915    T: TupleUnpack<'de>,
916{
917    fn unpack(mut input: &'de [u8], tuple_depth: TupleDepth) -> PackResult<(&'de [u8], Self)> {
918        if let Some(&NIL) = input.first() {
919            input = parse_code(input, NIL)?;
920            if tuple_depth.depth() > 1 {
921                input = parse_code(input, ESCAPE)?;
922            }
923            Ok((input, None))
924        } else {
925            let (input, v) = T::unpack(input, tuple_depth)?;
926            Ok((input, Some(v)))
927        }
928    }
929}
930
931impl TuplePack for Element<'_> {
932    fn pack<W: io::Write>(
933        &self,
934        w: &mut W,
935        tuple_depth: TupleDepth,
936    ) -> io::Result<VersionstampOffset> {
937        match self {
938            Element::Nil => Option::<()>::None.pack(w, tuple_depth),
939            Element::Bool(b) => b.pack(w, tuple_depth),
940            Element::Int(i) => i.pack(w, tuple_depth),
941            Element::Float(f) => f.pack(w, tuple_depth),
942            Element::Double(f) => f.pack(w, tuple_depth),
943            Element::String(ref c) => c.pack(w, tuple_depth),
944            Element::Bytes(ref b) => b.pack(w, tuple_depth),
945            Element::Versionstamp(ref b) => b.pack(w, tuple_depth),
946            Element::Tuple(ref v) => v.pack(w, tuple_depth),
947            #[cfg(feature = "uuid")]
948            Element::Uuid(v) => v.pack(w, tuple_depth),
949            #[cfg(feature = "num-bigint")]
950            Element::BigInt(v) => v.pack(w, tuple_depth),
951        }
952    }
953}
954
955impl<'de> TupleUnpack<'de> for Element<'de> {
956    fn unpack(input: &'de [u8], tuple_depth: TupleDepth) -> PackResult<(&'de [u8], Self)> {
957        const INTMIN: u8 = INTZERO - 8;
958        const INTMAX: u8 = INTZERO + 8;
959
960        let first = match input.first() {
961            None if tuple_depth.depth() == 0 => return Ok((input, Element::Tuple(Vec::new()))),
962            None => return Err(PackError::MissingBytes),
963            Some(byte) => byte,
964        };
965
966        let (mut input, mut v) = match *first {
967            NIL => {
968                let (input, _) = Option::<()>::unpack(input, tuple_depth)?;
969                (input, Element::Nil)
970            }
971            BYTES => {
972                let (input, v) = Bytes::unpack(input, tuple_depth)?;
973                (input, Element::Bytes(v))
974            }
975            STRING => {
976                let (input, v) = Cow::<'de, str>::unpack(input, tuple_depth)?;
977                (input, Element::String(v))
978            }
979            NESTED => {
980                let (input, v) = Vec::<Self>::unpack(input, tuple_depth)?;
981                (input, Element::Tuple(v))
982            }
983            INTMIN..=INTMAX => match i64::unpack(input, tuple_depth) {
984                Ok((input, v)) => (input, Element::Int(v)),
985                #[cfg(feature = "num-bigint")]
986                Err(PackError::UnsupportedIntLength) => {
987                    let (input, v) = num_bigint::BigInt::unpack(input, tuple_depth)?;
988                    (input, Element::BigInt(v))
989                }
990                Err(err) => return Err(err),
991            },
992            #[cfg(feature = "num-bigint")]
993            NEGINTSTART => {
994                let (input, v) = num_bigint::BigInt::unpack(input, tuple_depth)?;
995                (input, Element::BigInt(v))
996            }
997            #[cfg(feature = "num-bigint")]
998            POSINTEND => {
999                let (input, v) = num_bigint::BigInt::unpack(input, tuple_depth)?;
1000                (input, Element::BigInt(v))
1001            }
1002            #[cfg(not(feature = "num-bigint"))]
1003            NEGINTSTART => {
1004                let (input, v) = i64::unpack(input, tuple_depth)?;
1005                (input, Element::Int(v))
1006            }
1007            #[cfg(not(feature = "num-bigint"))]
1008            POSINTEND => {
1009                let (input, v) = i64::unpack(input, tuple_depth)?;
1010                (input, Element::Int(v))
1011            }
1012            FLOAT => {
1013                let (input, v) = f32::unpack(input, tuple_depth)?;
1014                (input, Element::Float(v))
1015            }
1016            DOUBLE => {
1017                let (input, v) = f64::unpack(input, tuple_depth)?;
1018                (input, Element::Double(v))
1019            }
1020            FALSE | TRUE => {
1021                let (input, v) = bool::unpack(input, tuple_depth)?;
1022                (input, Element::Bool(v))
1023            }
1024            VERSIONSTAMP => {
1025                let (input, v) = Versionstamp::unpack(input, tuple_depth)?;
1026                (input, Element::Versionstamp(v))
1027            }
1028            #[cfg(feature = "uuid")]
1029            UUID => {
1030                let (input, v) = uuid::Uuid::unpack(input, tuple_depth)?;
1031                (input, Element::Uuid(v))
1032            }
1033            found => {
1034                return Err(PackError::BadCode {
1035                    found,
1036                    expected: None,
1037                });
1038            }
1039        };
1040
1041        if tuple_depth.depth() == 0 && !input.is_empty() {
1042            let mut tuple = vec![v];
1043            while !input.is_empty() {
1044                let (rem, v) = Self::unpack(input, tuple_depth.increment())?;
1045                tuple.push(v);
1046                input = rem;
1047            }
1048            v = Element::Tuple(tuple);
1049        }
1050
1051        Ok((input, v))
1052    }
1053}
1054
1055impl TuplePack for Versionstamp {
1056    fn pack<W: io::Write>(
1057        &self,
1058        w: &mut W,
1059        _tuple_depth: TupleDepth,
1060    ) -> io::Result<VersionstampOffset> {
1061        w.write_all(&[VERSIONSTAMP])?;
1062        w.write_all(self.as_bytes())?;
1063        if self.is_complete() {
1064            Ok(VersionstampOffset::None { size: 1 + 12 })
1065        } else {
1066            Ok(VersionstampOffset::OneIncomplete { offset: 1 })
1067        }
1068    }
1069}
1070
1071impl TupleUnpack<'_> for Versionstamp {
1072    fn unpack(input: &[u8], _tuple_depth: TupleDepth) -> PackResult<(&[u8], Self)> {
1073        let input = parse_code(input, VERSIONSTAMP)?;
1074        let (input, slice) = parse_bytes(input, 12)?;
1075        let mut bytes = [0xff; 12];
1076        bytes.copy_from_slice(slice);
1077        Ok((input, Versionstamp::from(bytes)))
1078    }
1079}
1080
1081#[cfg(feature = "uuid")]
1082mod pack_uuid {
1083    use super::*;
1084    use uuid::Uuid;
1085
1086    impl TuplePack for Uuid {
1087        fn pack<W: io::Write>(
1088            &self,
1089            w: &mut W,
1090            _tuple_depth: TupleDepth,
1091        ) -> io::Result<VersionstampOffset> {
1092            w.write_all(&[UUID])?;
1093            w.write_all(self.as_bytes())?;
1094            Ok(VersionstampOffset::None { size: 1 + 16 })
1095        }
1096    }
1097
1098    impl TupleUnpack<'_> for Uuid {
1099        fn unpack(input: &[u8], _tuple_depth: TupleDepth) -> PackResult<(&[u8], Self)> {
1100            let input = parse_code(input, UUID)?;
1101            let (input, slice) = parse_bytes(input, 16)?;
1102            let uuid = Self::from_slice(slice).map_err(|_| PackError::BadUuid)?;
1103            Ok((input, uuid))
1104        }
1105    }
1106}