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
46pub 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 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 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 fn pack_into_vec(&self, output: &mut Vec<u8>) -> VersionstampOffset {
89 self.pack_root(output).expect(PACK_ERR_MSG)
90 }
91
92 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
109pub 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
527impl_ux!(u16);
529impl_ux!(u32);
530impl_ux!(u64);
531impl_ux!(u128, MAX_SZ);
532impl_ux!(usize);
533
534impl_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 for byte in bytes.iter_mut() {
555 *byte = !*byte;
556 }
557 }
558
559 fn inverted(bytes: &[u8]) -> Vec<u8> {
560 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 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}