foundationdb_tuple/
lib.rs

1//! Implementation of the official tuple layer typecodes
2//!
3//! The official specification can be found [here](https://github.com/apple/foundationdb/blob/master/design/tuple.md).
4
5mod element;
6mod pack;
7mod subspace;
8mod versionstamp;
9
10use std::borrow::Cow;
11use std::fmt::{self, Display};
12use std::io;
13use std::ops::Deref;
14use std::result;
15
16#[cfg(feature = "uuid")]
17pub use uuid::Uuid;
18
19pub use element::Element;
20pub use pack::{TuplePack, TupleUnpack, VersionstampOffset};
21pub use subspace::Subspace;
22pub use versionstamp::Versionstamp;
23
24const NIL: u8 = 0x00;
25const BYTES: u8 = 0x01;
26const STRING: u8 = 0x02;
27const NESTED: u8 = 0x05;
28const NEGINTSTART: u8 = 0x0b;
29const INTZERO: u8 = 0x14;
30const POSINTEND: u8 = 0x1d;
31const FLOAT: u8 = 0x20;
32const DOUBLE: u8 = 0x21;
33const FALSE: u8 = 0x26;
34const TRUE: u8 = 0x27;
35#[cfg(feature = "uuid")]
36const UUID: u8 = 0x30;
37// Not a single official binding is implementing 80 Bit versionstamp...
38// const VERSIONSTAMP_88: u8 = 0x32;
39const VERSIONSTAMP: u8 = 0x33;
40
41const ESCAPE: u8 = 0xff;
42
43/// Tracks the depth of a Tuple decoding chain
44#[derive(Copy, Clone)]
45pub struct TupleDepth(usize);
46
47impl TupleDepth {
48    fn new() -> Self {
49        TupleDepth(0)
50    }
51
52    /// Increment the depth by one, this be called when calling into `Tuple::{encode, decode}` of tuple-like datastructures
53    pub fn increment(self) -> Self {
54        TupleDepth(self.0 + 1)
55    }
56
57    /// Returns the current depth in any recursive tuple processing, 0 representing there having been no recursion
58    pub fn depth(self) -> usize {
59        self.0
60    }
61}
62
63/// A packing/unpacking error
64#[derive(Debug)]
65pub enum PackError {
66    Message(Box<str>),
67    IoError(io::Error),
68    TrailingBytes,
69    MissingBytes,
70    BadStringFormat,
71    BadCode {
72        found: u8,
73        expected: Option<u8>,
74    },
75    BadPrefix,
76    #[cfg(feature = "uuid")]
77    BadUuid,
78    UnsupportedIntLength,
79}
80
81impl From<io::Error> for PackError {
82    fn from(err: io::Error) -> Self {
83        PackError::IoError(err)
84    }
85}
86
87impl Display for PackError {
88    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89        match self {
90            PackError::Message(s) => s.fmt(f),
91            PackError::IoError(err) => err.fmt(f),
92            PackError::TrailingBytes => write!(f, "trailing bytes"),
93            PackError::MissingBytes => write!(f, "missing bytes"),
94            PackError::BadStringFormat => write!(f, "not an utf8 string"),
95            PackError::BadCode { found, .. } => write!(f, "bad code, found {}", found),
96            PackError::BadPrefix => write!(f, "bad prefix"),
97            #[cfg(feature = "uuid")]
98            PackError::BadUuid => write!(f, "bad uuid"),
99            PackError::UnsupportedIntLength => write!(f, "integer length was to large"),
100        }
101    }
102}
103
104impl std::error::Error for PackError {}
105
106/// Alias for `Result<..., tuple::Error>`
107pub type PackResult<T> = result::Result<T, PackError>;
108
109/// Represent a sequence of bytes (i.e. &[u8])
110///
111/// This sequence can be either owned or borrowed.
112#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
113pub struct Bytes<'a>(pub Cow<'a, [u8]>);
114
115impl fmt::Debug for Bytes<'_> {
116    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117        fmt::Display::fmt(self, f)
118    }
119}
120
121impl fmt::Display for Bytes<'_> {
122    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
123        write!(fmt, "b\"")?;
124        for &byte in self.0.iter() {
125            if byte == b'\\' {
126                write!(fmt, r"\\")?;
127            } else if byte.is_ascii_alphanumeric() {
128                write!(fmt, "{}", byte as char)?;
129            } else {
130                write!(fmt, "\\x{:02x}", byte)?;
131            }
132        }
133        write!(fmt, "\"")
134    }
135}
136
137impl Bytes<'_> {
138    pub fn into_owned(self) -> Vec<u8> {
139        self.0.into_owned()
140    }
141}
142
143impl Deref for Bytes<'_> {
144    type Target = [u8];
145    fn deref(&self) -> &Self::Target {
146        &self.0
147    }
148}
149impl AsRef<[u8]> for Bytes<'_> {
150    fn as_ref(&self) -> &[u8] {
151        &self.0
152    }
153}
154
155impl<'a> From<&'a [u8]> for Bytes<'a> {
156    fn from(bytes: &'a [u8]) -> Self {
157        Self(Cow::Borrowed(bytes))
158    }
159}
160impl From<Vec<u8>> for Bytes<'static> {
161    fn from(vec: Vec<u8>) -> Self {
162        Self(Cow::Owned(vec))
163    }
164}
165
166impl<'a> From<&'a str> for Bytes<'a> {
167    fn from(s: &'a str) -> Self {
168        s.as_bytes().into()
169    }
170}
171impl From<String> for Bytes<'static> {
172    fn from(vec: String) -> Self {
173        vec.into_bytes().into()
174    }
175}
176
177/// Pack value and returns the packed buffer
178///
179/// # Panics
180///
181/// Panics if the encoded data size doesn't fit in `u32`.
182pub fn pack<T: TuplePack>(v: &T) -> Vec<u8> {
183    v.pack_to_vec()
184}
185
186/// Pack value and returns the packed buffer
187///
188/// # Panics
189///
190/// Panics if there is multiple versionstamp present or if the encoded data size doesn't fit in `u32`.
191pub fn pack_with_versionstamp<T: TuplePack>(v: &T) -> Vec<u8> {
192    v.pack_to_vec_with_versionstamp()
193}
194
195/// Pack value into the given buffer
196///
197/// # Panics
198///
199/// Panics if the encoded data size doesn't fit in `u32`.
200pub fn pack_into<T: TuplePack>(v: &T, output: &mut Vec<u8>) -> VersionstampOffset {
201    v.pack_into_vec(output)
202}
203
204/// Pack value into the given buffer
205///
206/// # Panics
207///
208/// Panics if there is multiple versionstamp present or if the encoded data size doesn't fit in `u32`.
209pub fn pack_into_with_versionstamp<T: TuplePack>(v: &T, output: &mut Vec<u8>) {
210    let offset = v.pack_into_vec_with_versionstamp(output);
211    if let VersionstampOffset::MultipleIncomplete = offset {
212        panic!("pack_into_with_versionstamp does not allow multiple versionstamps");
213    }
214}
215
216/// Unpack input
217pub fn unpack<'de, T: TupleUnpack<'de>>(input: &'de [u8]) -> PackResult<T> {
218    T::unpack_root(input)
219}
220
221#[cfg(test)]
222mod tests {
223    use super::*;
224
225    const NIL_VAL: Option<()> = None;
226
227    fn test_serde<'de, T>(val: T, buf: &'de [u8])
228    where
229        T: TuplePack + TupleUnpack<'de> + fmt::Debug + PartialEq,
230    {
231        assert_eq!(Bytes::from(pack(&val)), Bytes::from(buf));
232        assert_eq!(unpack::<'de, T>(buf).unwrap(), val);
233    }
234
235    #[test]
236    fn test_spec() {
237        test_serde(NIL_VAL, &[NIL]);
238        test_serde((NIL_VAL,), &[NIL]);
239        test_serde(((NIL_VAL,),), &[NESTED, NIL, ESCAPE, NIL]);
240        // assert_eq!(to_bytes(b"foo\x00bar").unwrap(), b"\x01foo\x00\xffbar\x00");
241        test_serde("FÔO\x00bar".to_owned(), b"\x02F\xc3\x94O\x00\xffbar\x00");
242        test_serde(
243            (("foo\x00bar".to_owned(), NIL_VAL, ()),),
244            b"\x05\x02foo\x00\xffbar\x00\x00\xff\x05\x00\x00",
245        );
246        test_serde(-1, b"\x13\xfe");
247        test_serde(-5551212, b"\x11\xabK\x93");
248        test_serde(-42f32, b"\x20\x3d\xd7\xff\xff");
249    }
250
251    #[test]
252    fn test_simple() {
253        // bool
254        test_serde(false, &[FALSE]);
255        test_serde(true, &[TRUE]);
256
257        // int
258        test_serde(0i64, &[INTZERO]);
259        test_serde(1i64, &[0x15, 1]);
260        test_serde(-1i64, &[0x13, 254]);
261        test_serde(100i64, &[21, 100]);
262
263        test_serde(10000i32, &[22, 39, 16]);
264        test_serde(-100i16, &[19, 155]);
265        test_serde(-10000i64, &[18, 216, 239]);
266        test_serde(-1000000i64, &[17, 240, 189, 191]);
267
268        // boundary condition
269        test_serde(255u16, &[0x15, 255]);
270        test_serde(256i32, &[0x16, 1, 0]);
271        test_serde(-255i16, &[0x13, 0]);
272        test_serde(-256i64, &[0x12, 254, 255]);
273
274        // versionstamp
275        test_serde(
276            Versionstamp::complete(*b"\xaa\xbb\xcc\xdd\xee\xff\x00\x01\x02\x03", 0),
277            b"\x33\xaa\xbb\xcc\xdd\xee\xff\x00\x01\x02\x03\x00\x00",
278        );
279        test_serde(
280            Versionstamp::complete(*b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a", 657),
281            b"\x33\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x02\x91",
282        );
283
284        test_serde(0, b"\x14");
285        test_serde(1, b"\x15\x01");
286        test_serde(-1, b"\x13\xfe");
287        test_serde(255, b"\x15\xff");
288        test_serde(-255, b"\x13\x00");
289        test_serde(256, b"\x16\x01\x00");
290        test_serde(-256, b"\x12\xfe\xff");
291        test_serde(65536, b"\x17\x01\x00\x00");
292        test_serde(-65536, b"\x11\xfe\xff\xff");
293        test_serde(i64::MAX, b"\x1C\x7f\xff\xff\xff\xff\xff\xff\xff");
294        test_serde(i64::MAX as u64 + 1, b"\x1C\x80\x00\x00\x00\x00\x00\x00\x00");
295        test_serde(u64::MAX, b"\x1C\xff\xff\xff\xff\xff\xff\xff\xff");
296        test_serde(
297            u128::MAX,
298            b"\x1D\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
299        );
300        test_serde(
301            u64::MAX as u128 + 1,
302            b"\x1D\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00",
303        );
304        test_serde(
305            u64::MAX as i128 + 1,
306            b"\x1D\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00",
307        );
308        test_serde(
309            i64::MIN as i128 + 1,
310            b"\x0C\x80\x00\x00\x00\x00\x00\x00\x00",
311        );
312        test_serde(
313            i64::MIN as i128 - 1,
314            b"\x0C\x7f\xff\xff\xff\xff\xff\xff\xfe",
315        );
316        test_serde(-(u64::MAX as i128), b"\x0C\x00\x00\x00\x00\x00\x00\x00\x00");
317        test_serde(
318            -(u64::MAX as i128) - 1,
319            b"\x0b\xf6\xfe\xff\xff\xff\xff\xff\xff\xff\xff",
320        );
321        test_serde(
322            -(u64::MAX as i128) - 2,
323            b"\x0b\xf6\xfe\xff\xff\xff\xff\xff\xff\xff\xfe",
324        );
325        test_serde(
326            (u64::MAX as i128) * -2,
327            b"\x0b\xf6\xfe\x00\x00\x00\x00\x00\x00\x00\x01",
328        );
329        test_serde(
330            (u64::MAX as i128) * 2,
331            b"\x1d\x09\x01\xff\xff\xff\xff\xff\xff\xff\xfe",
332        );
333        test_serde(-4294967295i64, b"\x10\x00\x00\x00\x00");
334        test_serde(i64::MIN + 2, b"\x0C\x80\x00\x00\x00\x00\x00\x00\x01");
335        test_serde(i64::MIN + 1, b"\x0C\x80\x00\x00\x00\x00\x00\x00\x00");
336        test_serde(i64::MIN, b"\x0C\x7f\xff\xff\xff\xff\xff\xff\xff");
337
338        test_serde(9252427359321063944i128, b"\x1c\x80g9\xa9np\x02\x08");
339        assert!(matches!(
340            unpack::<i64>(b"\x1c\x80g9\xa9np\x02\x08").unwrap_err(),
341            PackError::UnsupportedIntLength
342        ));
343
344        test_serde(
345            -9252427359321063944i128,
346            b"\x0c\x7f\x98\xc6V\x91\x8f\xfd\xf7",
347        );
348        assert!(matches!(
349            unpack::<i64>(b"\x0c\x7f\x98\xc6V\x91\x8f\xfd\xf7").unwrap_err(),
350            PackError::UnsupportedIntLength
351        ));
352
353        test_serde(u64::MAX as i128, b"\x1c\xff\xff\xff\xff\xff\xff\xff\xff");
354        assert!(matches!(
355            unpack::<i64>(b"\x1c\xff\xff\xff\xff\xff\xff\xff\xff").unwrap_err(),
356            PackError::UnsupportedIntLength
357        ));
358
359        test_serde(-(u64::MAX as i128), b"\x0c\x00\x00\x00\x00\x00\x00\x00\x00");
360        assert!(matches!(
361            unpack::<i64>(b"\x0c\x00\x00\x00\x00\x00\x00\x00\x00").unwrap_err(),
362            PackError::UnsupportedIntLength
363        ));
364
365        test_serde(
366            (i64::MAX as i128) + 1,
367            b"\x1c\x80\x00\x00\x00\x00\x00\x00\x00",
368        );
369        assert!(matches!(
370            unpack::<i64>(b"\x1c\x80\x00\x00\x00\x00\x00\x00\x00").unwrap_err(),
371            PackError::UnsupportedIntLength
372        ));
373
374        test_serde(
375            (i64::MIN as i128) - 1,
376            b"\x0c\x7f\xff\xff\xff\xff\xff\xff\xfe",
377        );
378        assert!(matches!(
379            unpack::<i64>(b"\x0c\x7f\xff\xff\xff\xff\xff\xff\xfe").unwrap_err(),
380            PackError::UnsupportedIntLength
381        ));
382    }
383
384    #[cfg(feature = "num-bigint")]
385    #[test]
386    fn test_bigint() {
387        use num_bigint::{BigInt, BigUint};
388        // int
389        test_serde(BigInt::from(0i64), &[INTZERO]);
390        test_serde(BigUint::from(0u64), &[INTZERO]);
391        test_serde(BigInt::from(1i64), &[0x15, 1]);
392        test_serde(BigUint::from(1u64), &[0x15, 1]);
393        test_serde(BigInt::from(-1i64), &[0x13, 254]);
394        test_serde(BigInt::from(100i64), &[0x15, 100]);
395        test_serde(BigUint::from(100u64), &[0x15, 100]);
396
397        test_serde(BigInt::from(10000i32), &[0x16, 39, 16]);
398        test_serde(BigUint::from(10000u32), &[0x16, 39, 16]);
399        test_serde(BigInt::from(-100i16), &[19, 155]);
400        test_serde(BigInt::from(-10000i64), &[18, 216, 239]);
401        test_serde(BigInt::from(-1000000i64), &[17, 240, 189, 191]);
402
403        // boundary condition
404        test_serde(BigInt::from(255u16), &[0x15, 255]);
405        test_serde(BigUint::from(255u16), &[0x15, 255]);
406        test_serde(BigInt::from(256i32), &[0x16, 1, 0]);
407        test_serde(BigInt::from(-255i16), &[0x13, 0]);
408        test_serde(BigInt::from(-256i64), &[0x12, 254, 255]);
409
410        test_serde(BigInt::from(0), b"\x14");
411        test_serde(BigUint::from(0u64), b"\x14");
412        test_serde(BigInt::from(1), b"\x15\x01");
413        test_serde(BigUint::from(1u64), b"\x15\x01");
414        test_serde(BigInt::from(-1), b"\x13\xfe");
415        test_serde(BigInt::from(255), b"\x15\xff");
416        test_serde(BigUint::from(255u64), b"\x15\xff");
417        test_serde(BigInt::from(-255), b"\x13\x00");
418        test_serde(BigInt::from(256), b"\x16\x01\x00");
419        test_serde(BigUint::from(256u64), b"\x16\x01\x00");
420        test_serde(BigInt::from(-256), b"\x12\xfe\xff");
421        test_serde(BigInt::from(65536), b"\x17\x01\x00\x00");
422        test_serde(BigUint::from(65536u64), b"\x17\x01\x00\x00");
423        test_serde(BigInt::from(-65536), b"\x11\xfe\xff\xff");
424        test_serde(
425            BigInt::from(i64::MAX),
426            b"\x1C\x7f\xff\xff\xff\xff\xff\xff\xff",
427        );
428        test_serde(
429            BigUint::from(i64::MAX as u64),
430            b"\x1C\x7f\xff\xff\xff\xff\xff\xff\xff",
431        );
432        test_serde(
433            BigInt::from(i64::MAX as u64 + 1),
434            b"\x1C\x80\x00\x00\x00\x00\x00\x00\x00",
435        );
436        test_serde(
437            BigUint::from(i64::MAX as u64 + 1),
438            b"\x1C\x80\x00\x00\x00\x00\x00\x00\x00",
439        );
440        test_serde(
441            BigInt::from(u64::MAX),
442            b"\x1C\xff\xff\xff\xff\xff\xff\xff\xff",
443        );
444        test_serde(
445            BigUint::from(u64::MAX),
446            b"\x1C\xff\xff\xff\xff\xff\xff\xff\xff",
447        );
448        test_serde(
449            BigInt::from(u128::MAX),
450            b"\x1D\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
451        );
452        test_serde(
453            BigUint::from(u128::MAX),
454            b"\x1D\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
455        );
456        test_serde(
457            BigInt::from(u64::MAX as u128 + 1),
458            b"\x1D\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00",
459        );
460        test_serde(
461            BigUint::from(u64::MAX as u128 + 1),
462            b"\x1D\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00",
463        );
464        test_serde(
465            BigInt::from(u64::MAX as i128 + 1),
466            b"\x1D\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00",
467        );
468        test_serde(
469            BigUint::from(u64::MAX as u128 + 1),
470            b"\x1D\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00",
471        );
472        test_serde(
473            BigInt::from(i64::MIN as i128 + 1),
474            b"\x0C\x80\x00\x00\x00\x00\x00\x00\x00",
475        );
476        test_serde(
477            BigInt::from(i64::MIN as i128 - 1),
478            b"\x0C\x7f\xff\xff\xff\xff\xff\xff\xfe",
479        );
480        test_serde(
481            BigInt::from(-(u64::MAX as i128)),
482            b"\x0C\x00\x00\x00\x00\x00\x00\x00\x00",
483        );
484        test_serde(
485            BigInt::from(-(u64::MAX as i128) - 1),
486            b"\x0b\xf6\xfe\xff\xff\xff\xff\xff\xff\xff\xff",
487        );
488        test_serde(
489            BigInt::from(-(u64::MAX as i128) - 2),
490            b"\x0b\xf6\xfe\xff\xff\xff\xff\xff\xff\xff\xfe",
491        );
492        test_serde(
493            BigInt::from((u64::MAX as i128) * -2),
494            b"\x0b\xf6\xfe\x00\x00\x00\x00\x00\x00\x00\x01",
495        );
496        test_serde(
497            BigInt::from((u64::MAX as i128) * 2),
498            b"\x1d\x09\x01\xff\xff\xff\xff\xff\xff\xff\xfe",
499        );
500        test_serde(BigInt::from(-4294967295i64), b"\x10\x00\x00\x00\x00");
501        test_serde(
502            BigInt::from(i64::MIN + 2),
503            b"\x0C\x80\x00\x00\x00\x00\x00\x00\x01",
504        );
505        test_serde(
506            BigInt::from(i64::MIN + 1),
507            b"\x0C\x80\x00\x00\x00\x00\x00\x00\x00",
508        );
509        test_serde(
510            BigInt::from(i64::MIN),
511            b"\x0C\x7f\xff\xff\xff\xff\xff\xff\xff",
512        );
513
514        test_serde(
515            Element::BigInt(9252427359321063944i128.into()),
516            b"\x1c\x80g9\xa9np\x02\x08",
517        );
518        test_serde(
519            Element::BigInt((-9252427359321063944i128).into()),
520            b"\x0c\x7f\x98\xc6V\x91\x8f\xfd\xf7",
521        );
522    }
523
524    #[cfg(feature = "uuid")]
525    #[test]
526    fn test_uuid() {
527        use uuid::Uuid;
528
529        test_serde(
530            Element::Uuid(
531                Uuid::from_slice(
532                    b"\xba\xff\xff\xff\xff\x5e\xba\x11\x00\x00\x00\x00\x5c\xa1\xab\x1e",
533                )
534                .unwrap(),
535            ),
536            b"\x30\xba\xff\xff\xff\xff\x5e\xba\x11\x00\x00\x00\x00\x5c\xa1\xab\x1e",
537        );
538    }
539
540    #[test]
541    fn test_bindingtester() {
542        test_serde("NEW_TRANSACTION".to_string(), b"\x02NEW_TRANSACTION\x00");
543        test_serde(
544            vec!["NEW_TRANSACTION".to_string()],
545            b"\x02NEW_TRANSACTION\x00",
546        );
547        test_serde(
548            vec![
549                Element::String(Cow::Borrowed("PUSH")),
550                Element::Bytes(Bytes::from(
551                    b"\x01tester_output\x00\x01results\x00\x14".as_ref(),
552                )),
553            ],
554            b"\x02PUSH\x00\x01\x01tester_output\x00\xff\x01results\x00\xff\x14\x00",
555        );
556        test_serde(
557            vec![Element::String(Cow::Borrowed("PUSH")), Element::Nil],
558            b"\x02PUSH\x00\x00",
559        );
560        test_serde(
561            vec![
562                Element::String(Cow::Borrowed("PUSH")),
563                Element::Tuple(vec![
564                    Element::Nil,
565                    Element::Float(3299069000000.0),
566                    Element::Float(-0.000000000000000000000000000000000000011883096),
567                ]),
568            ],
569            b"\x02PUSH\x00\x05\x00\xff \xd4@\x07\xf5 \x7f~\x9a\xc2\x00",
570        );
571        test_serde(
572            vec![
573                Element::String(Cow::Borrowed("PUSH")),
574                Element::Int(-133525682914243904),
575            ],
576            b"\x02PUSH\x00\x0c\xfe%\x9f\x19M\x81J\xbf",
577        );
578
579        test_serde(
580            Element::Tuple(vec![Element::Nil, Element::Nil]),
581            b"\x00\x00",
582        );
583        test_serde(
584            Element::Tuple(vec![
585                Element::String(Cow::Borrowed("PUSH")),
586                Element::Tuple(vec![Element::Double(-8.251343508909708e-15)]),
587            ]),
588            b"\x02PUSH\x00\x05!B\xfdkl\x9f\xcc\x8eK\x00",
589        );
590    }
591
592    #[test]
593    fn test_element() {
594        test_serde(Element::Bool(true), &[TRUE]);
595        test_serde(Element::Bool(false), &[FALSE]);
596        test_serde(Element::Int(-1), &[0x13, 254]);
597        test_serde(
598            Element::Versionstamp(Versionstamp::complete(
599                *b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a",
600                657,
601            )),
602            b"\x33\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x02\x91",
603        );
604        test_serde(
605            (Element::Versionstamp(Versionstamp::complete(
606                *b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a",
607                657,
608            )),),
609            b"\x33\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x02\x91",
610        );
611        test_serde(
612            (Element::Versionstamp(Versionstamp::complete(
613                *b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a",
614                657,
615            )),),
616            b"\x33\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x02\x91",
617        );
618        test_serde(
619            vec![Element::Bool(true), Element::Bool(false)],
620            &[TRUE, FALSE],
621        );
622        test_serde(
623            vec![Element::Tuple(vec![
624                Element::Bool(true),
625                Element::Bool(false),
626            ])],
627            &[NESTED, TRUE, FALSE, NIL],
628        );
629        test_serde(Vec::<Element>::new(), &[]);
630        test_serde(Element::Tuple(vec![]), &[]);
631    }
632
633    #[test]
634    fn test_verstionstamp() {
635        assert_eq!(
636            Bytes::from(pack(&("foo", Versionstamp::incomplete(0)))),
637            Bytes::from(&b"\x02foo\x00\x33\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00"[..])
638        );
639        assert_eq!(
640            Bytes::from(pack_with_versionstamp(&(
641                "foo",
642                Versionstamp::incomplete(0)
643            ))),
644            Bytes::from(
645                &b"\x02foo\x00\x33\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x06\x00\x00\x00"
646                    [..]
647            )
648        );
649    }
650}