fdb/tuple/
tuple.rs

1use bytes::{BufMut, Bytes, BytesMut};
2use num_bigint::BigInt;
3use num_traits::sign::Signed;
4use uuid::Uuid;
5
6use std::cmp::Ordering;
7use std::convert::TryFrom;
8use std::convert::TryInto;
9
10use crate::error::{FdbError, FdbResult, TUPLE_GET, TUPLE_PACK_WITH_VERSIONSTAMP_NOT_FOUND};
11use crate::range::Range;
12use crate::tuple::{
13    element::{self, TupleValue},
14    Versionstamp,
15};
16
17/// Represents a set of elements that make up a sortable, typed key.
18///
19/// [`Tuple`] is comparable with other [`Tuple`]s and will sort in
20/// Rust in the same order in which they would sort in FDB. [`Tuple`]s
21/// sort first by the first element, then by the second, etc., This
22/// make tuple layer ideal for building a variety of higher-level data
23/// models.
24///
25/// For general guidance on tuple usage, see [this] link.
26///
27/// [`Tuple`] can contain [`null`], [`Bytes`], [`String`], another
28/// [`Tuple`], [`BigInt`], [`i64`], [`i32`], [`i16`], [`i8`], [`f32`],
29/// [`f64`], [`bool`], [`Uuid`], [`Versionstamp`] values.
30///
31/// [layer]: https://github.com/apple/foundationdb/blob/6.3.0/design/tuple.md
32/// [this]: https://apple.github.io/foundationdb/data-modeling.html#tuples
33/// [`null`]: https://github.com/apple/foundationdb/blob/release-6.3/design/tuple.md#null-value
34///
35// NOTE: Unlike the Java API, we do not implement `Iterator` trait, as
36//       that would mean we will have to expose `TupleValue` type to
37//       the client. Instead we provide `size()` method and let the
38//       client call appropriate `get_<type>(...)` methods.
39#[derive(Debug, Clone)]
40pub struct Tuple {
41    elements: Vec<TupleValue>,
42    // This is `true` *only* when `Tuple` contains a `Versionstamp`
43    // *and* it that `Versionstamp` is incomplete.
44    //
45    // This is `false` (default) when `Tuple` does not contain a
46    // `Versionstamp` or if it contains a `Versionstamp` that is
47    // complete.
48    //
49    // Basically adding complete `Versionstamp` won't change this
50    // value to `true`. It is only when incomplete `Versionstamp` is
51    // added, that this value changes to `true`.
52    has_incomplete_versionstamp: bool,
53}
54
55impl Tuple {
56    /// Create a new empty [`Tuple`].
57    pub fn new() -> Tuple {
58        Tuple {
59            elements: Vec::new(),
60            has_incomplete_versionstamp: false,
61        }
62    }
63
64    /// Construct a new [`Tuple`] with elements decoded from a supplied [`Bytes`].
65    pub fn from_bytes(b: impl Into<Bytes>) -> FdbResult<Tuple> {
66        element::from_bytes(b.into())
67    }
68
69    /// Append FDB Tuple [`null`] value to [`Tuple`].
70    ///
71    /// [`null`]: https://github.com/apple/foundationdb/blob/release-6.3/design/tuple.md#null-value
72    pub fn add_null(&mut self) {
73        self.elements.push(TupleValue::NullValue);
74    }
75
76    /// Append [`Bytes`] value to the [`Tuple`].
77    pub fn add_bytes(&mut self, b: Bytes) {
78        self.elements.push(TupleValue::ByteString(b));
79    }
80
81    /// Append [`String`] value to the [`Tuple`].
82    pub fn add_string(&mut self, s: String) {
83        self.elements.push(TupleValue::UnicodeString(s));
84    }
85
86    /// Append [`Tuple`] value to the [`Tuple`]
87    pub fn add_tuple(&mut self, t: Tuple) {
88        self.has_incomplete_versionstamp =
89            self.has_incomplete_versionstamp || t.has_incomplete_versionstamp();
90        self.elements.push(TupleValue::NestedTuple(t));
91    }
92
93    /// Append [`BigInt`] value to the [`Tuple`]
94    ///
95    /// # Panic
96    ///
97    /// Panics if the [`Bytes`] encoded length of the [`BigInt`] is
98    /// greater than 255.
99    pub fn add_bigint(&mut self, i: BigInt) {
100        let _ = i64::try_from(i.clone())
101            .map(|x| self.add_i64(x))
102            .map_err(|_| {
103                if i.is_negative() {
104		    // We are making the negative number positive for
105		    // storing it in
106		    // `TupleValue::NegativeArbitraryPrecisionInteger`.
107                    if ((BigInt::parse_bytes(b"-18446744073709551615", 10).unwrap())
108                        ..=(BigInt::parse_bytes(b"-9223372036854775809", 10).unwrap()))
109                        .contains(&i)
110                    {
111                        self.elements.push(TupleValue::NegInt8(
112                            // Safe to unwrap here because we are
113                            // checking the range above.
114                            u64::try_from(i * -1).unwrap(),
115                        ));
116                    } else {
117                        let b: BigInt = i * -1;
118                        let (_, bigint_vec_u8) = b.to_bytes_be();
119
120                        if Bytes::from(bigint_vec_u8).len() > 255 {
121			    panic!("Byte encoded length of BigInt *must* be less than or equal to 255.");
122                        }
123                        self.elements
124                            .push(TupleValue::NegativeArbitraryPrecisionInteger(b));
125                    }
126		}
127		else if ((BigInt::parse_bytes(b"9223372036854775808", 10).unwrap())
128                        ..=(BigInt::parse_bytes(b"18446744073709551615", 10).unwrap()))
129                        .contains(&i)
130                {
131                    self.elements.push(TupleValue::PosInt8(
132                        // Safe to unwrap here because we are
133                        // checking the range above.
134                        u64::try_from(i).unwrap(),
135                    ));
136                } else {
137                    let b: BigInt = i;
138                    let (_, bigint_vec_u8) = b.to_bytes_be();
139
140                    if Bytes::from(bigint_vec_u8).len() > 255 {
141			panic!("Byte encoded length of BigInt *must* be less than or equal to 255.");
142                    }
143                    self.elements
144                        .push(TupleValue::PositiveArbitraryPrecisionInteger(b));
145                }
146            });
147    }
148
149    /// Append [`i64`] value to the [`Tuple`]
150    pub fn add_i64(&mut self, i: i64) {
151        let _ = i32::try_from(i).map(|x| self.add_i32(x)).map_err(|_| {
152            if i.is_negative() {
153                match i {
154                    i64::MIN..=-72057594037927936 => {
155                        self.elements.push(TupleValue::NegInt8(i.unsigned_abs()))
156                    }
157                    -72057594037927935..=-281474976710656 => {
158                        self.elements.push(TupleValue::NegInt7(i.unsigned_abs()))
159                    }
160                    -281474976710655..=-1099511627776 => {
161                        self.elements.push(TupleValue::NegInt6(i.unsigned_abs()))
162                    }
163                    -1099511627775..=-4294967296 => {
164                        self.elements.push(TupleValue::NegInt5(i.unsigned_abs()))
165                    }
166                    _ => self.elements.push(TupleValue::NegInt4(
167                        // Safe to unwrap here because we are checking
168                        // the range in `try_from` and
169                        // `i64::MIN..=-72057594037927936`,
170                        // `-72057594037927935..=-281474976710656`,
171                        // `-281474976710655..=-1099511627776`,
172                        // `-1099511627775..=-4294967296`.
173                        i.unsigned_abs().try_into().unwrap(),
174                    )),
175                }
176            } else {
177                match i {
178                    2147483648..=4294967295 => self.elements.push(TupleValue::PosInt4(
179                        // Safe to unwrap here because we are checking
180                        // the range in `try_from` and
181                        // `4294967296..=1099511627775`,
182                        // `1099511627776..=281474976710655`,
183                        // `281474976710656..=72057594037927935`,
184                        // `>72057594037927935` using `_` below.
185                        i.unsigned_abs().try_into().unwrap(),
186                    )),
187                    4294967296..=1099511627775 => {
188                        self.elements.push(TupleValue::PosInt5(i.unsigned_abs()))
189                    }
190                    1099511627776..=281474976710655 => {
191                        self.elements.push(TupleValue::PosInt6(i.unsigned_abs()))
192                    }
193                    281474976710656..=72057594037927935 => {
194                        self.elements.push(TupleValue::PosInt7(i.unsigned_abs()))
195                    }
196                    _ => self.elements.push(TupleValue::PosInt8(i.unsigned_abs())),
197                }
198            }
199        });
200    }
201
202    /// Append [`i32`] value to the [`Tuple`]
203    pub fn add_i32(&mut self, i: i32) {
204        let _ = i16::try_from(i).map(|x| self.add_i16(x)).map_err(|_| {
205            if i.is_negative() {
206                match i {
207                    i32::MIN..=-16777216 => {
208                        self.elements.push(TupleValue::NegInt4(i.unsigned_abs()))
209                    }
210                    -16777215..=-65536 => self.elements.push(TupleValue::NegInt3(i.unsigned_abs())),
211                    _ => self.elements.push(TupleValue::NegInt2(
212                        // Safe to unwrap here because we are checking
213                        // the range in `try_from` and
214                        // `i32::MIN..=-16777216`,
215                        // `-16777215..=-65536`
216                        i.unsigned_abs().try_into().unwrap(),
217                    )),
218                }
219            } else {
220                match i {
221                    32768..=65535 => self.elements.push(TupleValue::PosInt2(
222                        // Safe to unwrap here because we are checking
223                        // the range in `try_from` and
224                        // `65536..=16777215`, `>16777215` using `_`
225                        // below.
226                        i.unsigned_abs().try_into().unwrap(),
227                    )),
228                    65536..=16777215 => self.elements.push(TupleValue::PosInt3(i.unsigned_abs())),
229                    _ => self.elements.push(TupleValue::PosInt4(i.unsigned_abs())),
230                }
231            }
232        });
233    }
234
235    /// Append [`i16`] value to the [`Tuple`].
236    pub fn add_i16(&mut self, i: i16) {
237        let _ = i8::try_from(i).map(|x| self.add_i8(x)).map_err(|_| {
238            if i.is_negative() {
239                match i {
240                    i16::MIN..=-256 => self.elements.push(TupleValue::NegInt2(i.unsigned_abs())),
241                    _ => self.elements.push(TupleValue::NegInt1(
242                        // Safe to unwrap here because we are
243                        // checking the range in `try_from` and
244                        // `i16::MIN..=-256`.
245                        i.unsigned_abs().try_into().unwrap(),
246                    )),
247                }
248            } else {
249                match i {
250                    128..=255 => self.elements.push(TupleValue::PosInt1(
251                        // Safe to unwrap here because we are checking
252                        // the range in `try_from` and `>255` using
253                        // `_` below.
254                        i.unsigned_abs().try_into().unwrap(),
255                    )),
256                    _ => self.elements.push(TupleValue::PosInt2(i.unsigned_abs())),
257                }
258            }
259        });
260    }
261
262    /// Append [`i8`] value to the [`Tuple`].
263    pub fn add_i8(&mut self, i: i8) {
264        match i {
265            i8::MIN..=-1 => self.elements.push(TupleValue::NegInt1(i.unsigned_abs())),
266            0 => self.elements.push(TupleValue::IntZero),
267            1..=i8::MAX => self.elements.push(TupleValue::PosInt1(i.unsigned_abs())),
268        }
269    }
270
271    /// Append [`f32`] value to the [`Tuple`].
272    ///
273    /// # Note
274    ///
275    /// The [`f32`] value is encoded using type code [`0x20`], without any conversion.
276    ///
277    /// [`0x20`]: https://github.com/apple/foundationdb/blob/release-6.3/design/tuple.md#ieee-binary-floating-point
278    pub fn add_f32(&mut self, f: f32) {
279        self.elements
280            .push(TupleValue::IeeeBinaryFloatingPointFloat(f));
281    }
282
283    /// Append [`f64`] value to the [`Tuple`].
284    ///
285    /// # Note
286    ///
287    /// The [`f64`] value is encoded using type code [`0x21`], without any conversion.
288    ///
289    /// [`0x21`]: https://github.com/apple/foundationdb/blob/release-6.3/design/tuple.md#ieee-binary-floating-point
290    pub fn add_f64(&mut self, f: f64) {
291        self.elements
292            .push(TupleValue::IeeeBinaryFloatingPointDouble(f));
293    }
294
295    /// Append [`bool`] value to the [`Tuple`].
296    pub fn add_bool(&mut self, b: bool) {
297        if b {
298            self.elements.push(TupleValue::TrueValue);
299        } else {
300            self.elements.push(TupleValue::FalseValue);
301        }
302    }
303
304    /// Append [`Uuid`] value to the [`Tuple`].
305    pub fn add_uuid(&mut self, u: Uuid) {
306        self.elements.push(TupleValue::Rfc4122Uuid(u));
307    }
308
309    /// Append [`Versionstamp`] value to the [`Tuple`]    
310    pub fn add_versionstamp(&mut self, v: Versionstamp) {
311        self.has_incomplete_versionstamp = self.has_incomplete_versionstamp || (!v.is_complete());
312        self.elements.push(TupleValue::Versionstamp96Bit(v));
313    }
314
315    /// Append elements of [`Tuple`] `t` to [`Tuple`] `Self`
316    pub fn append(&mut self, mut t: Tuple) {
317        self.has_incomplete_versionstamp =
318            self.has_incomplete_versionstamp || t.has_incomplete_versionstamp();
319
320        self.elements.append(&mut t.elements);
321    }
322
323    /// Determines if there is a [`Versionstamp`] included in this
324    /// [`Tuple`] that has not had its transaction version set.
325    pub fn has_incomplete_versionstamp(&self) -> bool {
326        self.has_incomplete_versionstamp
327    }
328
329    /// Gets an indexed item as FDB Tuple [`null`] value.
330    ///
331    /// [`null`]: https://github.com/apple/foundationdb/blob/release-6.3/design/tuple.md#null-value
332    pub fn get_null(&self, index: usize) -> FdbResult<()> {
333        self.elements
334            .get(index)
335            .and_then(|x| match x {
336                &TupleValue::NullValue => Some(()),
337                _ => None,
338            })
339            .ok_or_else(Tuple::tuple_get_error)
340    }
341
342    /// Gets an indexed item as [`Bytes`] ref.
343    pub fn get_bytes_ref(&self, index: usize) -> FdbResult<&Bytes> {
344        self.elements
345            .get(index)
346            .and_then(|x| match x {
347                &TupleValue::ByteString(ref b) => Some(b),
348                _ => None,
349            })
350            .ok_or_else(Tuple::tuple_get_error)
351    }
352
353    /// Gets an indexed item as [`String`] ref.
354    pub fn get_string_ref(&self, index: usize) -> FdbResult<&String> {
355        self.elements
356            .get(index)
357            .and_then(|x| match x {
358                &TupleValue::UnicodeString(ref s) => Some(s),
359                _ => None,
360            })
361            .ok_or_else(Tuple::tuple_get_error)
362    }
363
364    /// Gets an indexed item as [`Tuple`] ref.
365    pub fn get_tuple_ref(&self, index: usize) -> FdbResult<&Tuple> {
366        self.elements
367            .get(index)
368            .and_then(|x| match x {
369                &TupleValue::NestedTuple(ref t) => Some(t),
370                _ => None,
371            })
372            .ok_or_else(Tuple::tuple_get_error)
373    }
374
375    /// Gets an indexed item as [`BigInt`].
376    pub fn get_bigint(&self, index: usize) -> FdbResult<BigInt> {
377        self.get_i64(index).map(|x| x.into()).or_else(|_| {
378            self.elements
379                .get(index)
380                .and_then(|x| match *x {
381                    TupleValue::NegativeArbitraryPrecisionInteger(ref i) => Some(i.clone() * -1),
382                    TupleValue::NegInt8(ref i)
383                        if (9223372036854775809..=18446744073709551615).contains(i) =>
384                    {
385                        Some(Into::<BigInt>::into(*i) * -1)
386                    }
387                    TupleValue::PosInt8(ref i)
388                        if (9223372036854775808..=18446744073709551615).contains(i) =>
389                    {
390                        Some((*i).into())
391                    }
392                    TupleValue::PositiveArbitraryPrecisionInteger(ref i) => Some(i.clone()),
393                    _ => None,
394                })
395                .ok_or_else(Tuple::tuple_get_error)
396        })
397    }
398
399    /// Gets an indexed item as [`i64`].
400    pub fn get_i64(&self, index: usize) -> FdbResult<i64> {
401        self.get_i32(index).map(|x| x.into()).or_else(|_| {
402            self.elements
403                .get(index)
404                .and_then(|x| match *x {
405                    TupleValue::NegInt8(ref i)
406                        if (72057594037927936..=9223372036854775808).contains(i) =>
407                    {
408                        Some(
409                            // Safe to unwrap here because we are
410                            // checking for the range.
411                            i64::try_from(-Into::<i128>::into(*i)).unwrap(),
412                        )
413                    }
414                    TupleValue::NegInt7(ref i)
415                        if (281474976710656..=72057594037927935).contains(i) =>
416                    {
417                        Some(
418                            // Safe to unwrap here because we are
419                            // checking for the range.
420                            i64::try_from(-Into::<i128>::into(*i)).unwrap(),
421                        )
422                    }
423                    TupleValue::NegInt6(ref i) if (1099511627776..=281474976710655).contains(i) => {
424                        Some(
425                            // Safe to unwrap here because we are
426                            // checking for the range.
427                            i64::try_from(-Into::<i128>::into(*i)).unwrap(),
428                        )
429                    }
430                    TupleValue::NegInt5(ref i) if (4294967296..=1099511627775).contains(i) => {
431                        Some(
432                            // Safe to unwrap here because we are
433                            // checking for the range.
434                            i64::try_from(-Into::<i128>::into(*i)).unwrap(),
435                        )
436                    }
437
438                    TupleValue::NegInt4(ref i) if (2147483649..=4294967295).contains(i) => {
439                        Some(-Into::<i64>::into(*i))
440                    }
441                    TupleValue::PosInt4(ref i) if (2147483648..=4294967295).contains(i) => {
442                        Some((*i).into())
443                    }
444                    TupleValue::PosInt5(ref i) if (4294967296..=1099511627775).contains(i) => {
445                        Some(
446                            // Safe to unwrap here because we are
447                            // checking for the range.
448                            i64::try_from(*i).unwrap(),
449                        )
450                    }
451                    TupleValue::PosInt6(ref i) if (1099511627776..=281474976710655).contains(i) => {
452                        Some(
453                            // Safe to unwrap here because we are
454                            // checking for the range.
455                            i64::try_from(*i).unwrap(),
456                        )
457                    }
458                    TupleValue::PosInt7(ref i)
459                        if (281474976710656..=72057594037927935).contains(i) =>
460                    {
461                        Some(
462                            // Safe to unwrap here because we are
463                            // checking for the range.
464                            i64::try_from(*i).unwrap(),
465                        )
466                    }
467                    TupleValue::PosInt8(ref i)
468                        if (72057594037927936..=9223372036854775807).contains(i) =>
469                    {
470                        Some(
471                            // Safe to unwrap here because we are
472                            // checking for the range.
473                            i64::try_from(*i).unwrap(),
474                        )
475                    }
476                    _ => None,
477                })
478                .ok_or_else(Tuple::tuple_get_error)
479        })
480    }
481
482    /// Gets an indexed item as [`i32`].
483    pub fn get_i32(&self, index: usize) -> FdbResult<i32> {
484        self.get_i16(index).map(|x| x.into()).or_else(|_| {
485            self.elements
486                .get(index)
487                .and_then(|x| match *x {
488                    TupleValue::NegInt4(ref i) if (16777216..=2147483648).contains(i) => Some(
489                        // Safe to unwrap here because we are
490                        // checking for the range.
491                        i32::try_from(-Into::<i64>::into(*i)).unwrap(),
492                    ),
493                    TupleValue::NegInt3(ref i) if (65536..=16777215).contains(i) => Some(
494                        // Safe to unwrap here because we are
495                        // checking for the range.
496                        i32::try_from(-Into::<i64>::into(*i)).unwrap(),
497                    ),
498                    TupleValue::NegInt2(ref i) if (32769..=65535).contains(i) => {
499                        Some(-Into::<i32>::into(*i))
500                    }
501                    TupleValue::PosInt2(ref i) if (32768..=65535).contains(i) => Some((*i).into()),
502                    TupleValue::PosInt3(ref i) if (65536..=16777215).contains(i) => Some(
503                        // Safe to unwrap here because we are checking
504                        // for the range.
505                        i32::try_from(*i).unwrap(),
506                    ),
507                    TupleValue::PosInt4(ref i) if (16777216..=2147483647).contains(i) => Some(
508                        // Safe to unwrap here because we are checking
509                        // for the range.
510                        i32::try_from(*i).unwrap(),
511                    ),
512                    _ => None,
513                })
514                .ok_or_else(Tuple::tuple_get_error)
515        })
516    }
517
518    /// Gets an indexed item as [`i16`].
519    pub fn get_i16(&self, index: usize) -> FdbResult<i16> {
520        self.get_i8(index).map(|x| x.into()).or_else(|_| {
521            self.elements
522                .get(index)
523                .and_then(|x| match *x {
524                    TupleValue::NegInt2(ref i) if (256..=32768).contains(i) => Some(
525                        // Safe to unwrap here because we are
526                        // checking for the range.
527                        i16::try_from(-Into::<i32>::into(*i)).unwrap(),
528                    ),
529                    TupleValue::NegInt1(ref i) if (129..=255).contains(i) => {
530                        Some(-Into::<i16>::into(*i))
531                    }
532                    TupleValue::PosInt1(ref i) if (128..=255).contains(i) => Some((*i).into()),
533                    TupleValue::PosInt2(ref i) if (256..=32767).contains(i) => Some(
534                        // Safe to unwrap here because we are checking
535                        // for the range.
536                        i16::try_from(*i).unwrap(),
537                    ),
538                    _ => None,
539                })
540                .ok_or_else(Tuple::tuple_get_error)
541        })
542    }
543
544    /// Gets an indexed item as [`i8`].
545    pub fn get_i8(&self, index: usize) -> FdbResult<i8> {
546        self.elements
547            .get(index)
548            .and_then(|x| match *x {
549                TupleValue::NegInt1(i) if i <= 128 => {
550                    Some(
551                        // Safe to unwrap here because we are checking
552                        // for the range.
553                        i8::try_from(-Into::<i16>::into(i)).unwrap(),
554                    )
555                }
556                TupleValue::IntZero => Some(0),
557                TupleValue::PosInt1(i) if i <= 127 => Some(
558                    // Safe to unwrap here because we are checking for
559                    // the range.
560                    i8::try_from(i).unwrap(),
561                ),
562                _ => None,
563            })
564            .ok_or_else(Tuple::tuple_get_error)
565    }
566
567    /// Gets an indexed item as [`f32`].
568    pub fn get_f32(&self, index: usize) -> FdbResult<f32> {
569        self.elements
570            .get(index)
571            .and_then(|x| match x {
572                &TupleValue::IeeeBinaryFloatingPointFloat(f) => Some(f),
573                _ => None,
574            })
575            .ok_or_else(Tuple::tuple_get_error)
576    }
577
578    /// Gets an indexed item as [`f64`].
579    pub fn get_f64(&self, index: usize) -> FdbResult<f64> {
580        self.elements
581            .get(index)
582            .and_then(|x| match x {
583                &TupleValue::IeeeBinaryFloatingPointDouble(f) => Some(f),
584                _ => None,
585            })
586            .ok_or_else(Tuple::tuple_get_error)
587    }
588
589    /// Gets an indexed item as [`bool`].
590    pub fn get_bool(&self, index: usize) -> FdbResult<bool> {
591        self.elements
592            .get(index)
593            .and_then(|x| match *x {
594                TupleValue::FalseValue => Some(false),
595                TupleValue::TrueValue => Some(true),
596                _ => None,
597            })
598            .ok_or_else(Tuple::tuple_get_error)
599    }
600
601    /// Gets an indexed item as [`Uuid`] ref.
602    pub fn get_uuid_ref(&self, index: usize) -> FdbResult<&Uuid> {
603        self.elements
604            .get(index)
605            .and_then(|x| match x {
606                &TupleValue::Rfc4122Uuid(ref u) => Some(u),
607                _ => None,
608            })
609            .ok_or_else(Tuple::tuple_get_error)
610    }
611
612    /// Gets an indexed item as [`Versionstamp`] ref.
613    pub fn get_versionstamp_ref(&self, index: usize) -> FdbResult<&Versionstamp> {
614        self.elements
615            .get(index)
616            .and_then(|x| match x {
617                &TupleValue::Versionstamp96Bit(ref v) => Some(v),
618                _ => None,
619            })
620            .ok_or_else(Tuple::tuple_get_error)
621    }
622
623    /// Determine if this [`Tuple`] contains no elements.
624    pub fn is_empty(&self) -> bool {
625        self.elements.is_empty()
626    }
627
628    /// Gets the number of elements in this [`Tuple`].
629    pub fn size(&self) -> usize {
630        self.elements.len()
631    }
632
633    /// Get an encoded representation of this [`Tuple`].
634    pub fn pack(&self) -> Bytes {
635        element::to_bytes(self.clone())
636    }
637
638    /// Get an encoded representation of this [`Tuple`] for use with
639    /// [`SetVersionstampedKey`].
640    ///
641    /// # Panic
642    ///
643    /// The index where incomplete versionstamp is located is a 32-bit
644    /// little-endian integer. If the generated index overflows
645    /// [`u32`], then this function panics.
646    ///
647    /// [`SetVersionstampedKey`]: crate::transaction::MutationType::SetVersionstampedKey
648    pub fn pack_with_versionstamp(&self, prefix: Bytes) -> FdbResult<Bytes> {
649        if self.has_incomplete_versionstamp() {
650            element::find_incomplete_versionstamp(self.clone()).map(|x| {
651                let index = TryInto::<u32>::try_into(x + prefix.len()).unwrap();
652
653                let mut res = BytesMut::new();
654
655                res.put(prefix);
656                res.put(self.pack());
657                res.put_u32_le(index);
658
659                res.into()
660            })
661        } else {
662            Err(FdbError::new(TUPLE_PACK_WITH_VERSIONSTAMP_NOT_FOUND))
663        }
664    }
665
666    /// Returns a range representing all keys that encode [`Tuple`]s
667    /// strictly starting with this [`Tuple`].
668    ///
669    /// # Panic
670    ///
671    /// Panics if the tuple contains an incomplete [`Versionstamp`].
672    pub fn range(&self, prefix: Bytes) -> Range {
673        if self.has_incomplete_versionstamp() {
674            panic!("Cannot create Range value as tuple contains an incomplete versionstamp");
675        }
676
677        let begin = {
678            let mut x = BytesMut::new();
679            x.put(prefix.clone());
680            x.put(self.pack());
681            x.put_u8(0x00);
682            Into::<Bytes>::into(x)
683        };
684
685        let end = {
686            let mut x = BytesMut::new();
687            x.put(prefix);
688            x.put(self.pack());
689            x.put_u8(0xFF);
690            Into::<Bytes>::into(x)
691        };
692
693        Range::new(begin, end)
694    }
695
696    pub(crate) fn from_elements(elements: Vec<TupleValue>) -> Tuple {
697        let has_incomplete_versionstamp = (&elements).iter().fold(false, |acc, x| match *x {
698            TupleValue::NestedTuple(ref t) => acc || t.has_incomplete_versionstamp(),
699            TupleValue::Versionstamp96Bit(ref vs) => acc || (!vs.is_complete()),
700            _ => acc,
701        });
702
703        Tuple {
704            elements,
705            has_incomplete_versionstamp,
706        }
707    }
708
709    pub(crate) fn into_elements(self) -> Vec<TupleValue> {
710        self.elements
711    }
712
713    fn tuple_get_error() -> FdbError {
714        FdbError::new(TUPLE_GET)
715    }
716}
717
718impl Default for Tuple {
719    fn default() -> Tuple {
720        Tuple::new()
721    }
722}
723
724impl PartialEq for Tuple {
725    fn eq(&self, other: &Self) -> bool {
726        self.pack().eq(&other.pack())
727    }
728}
729
730impl Eq for Tuple {}
731
732impl PartialOrd for Tuple {
733    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
734        self.pack().partial_cmp(&other.pack())
735    }
736}
737
738impl Ord for Tuple {
739    fn cmp(&self, other: &Self) -> Ordering {
740        self.pack().cmp(&other.pack())
741    }
742}
743
744#[cfg(test)]
745mod tests {
746    use bytes::Bytes;
747    use impls::impls;
748    use num_bigint::BigInt;
749    use uuid::Uuid;
750
751    use crate::error::{
752        FdbError, TUPLE_FROM_BYTES, TUPLE_PACK_WITH_VERSIONSTAMP_MULTIPLE_FOUND,
753        TUPLE_PACK_WITH_VERSIONSTAMP_NOT_FOUND,
754    };
755    use crate::range::Range;
756    use crate::tuple::{element::TupleValue, Versionstamp};
757
758    use super::Tuple;
759
760    #[test]
761    fn impls() {
762        #[rustfmt::skip]
763	assert!(impls!(
764	    Tuple:
765	        PartialEq<Tuple> &
766                Eq &
767                PartialOrd<Tuple> &
768                Ord
769	));
770    }
771
772    #[test]
773    fn from_bytes() {
774        // For additonal tests, see the tests for `parsers::tuple`
775        // (`test_tuple`) in `element.rs`.
776        assert_eq!(
777            Tuple::from_bytes(Bytes::from_static(&b"\x00moredata"[..])),
778            Err(FdbError::new(TUPLE_FROM_BYTES)),
779        );
780        assert_eq!(
781            Tuple::from_bytes(Bytes::from_static(&b"no_tuple"[..])),
782            Err(FdbError::new(TUPLE_FROM_BYTES)),
783        );
784        assert_eq!(
785            Tuple::from_bytes(Bytes::from_static(&b"\x02hello\x00"[..])),
786            Ok({
787                let mut t = Tuple::new();
788                t.add_string("hello".to_string());
789                t
790            })
791        );
792    }
793
794    #[test]
795    fn add_null() {
796        let mut t = Tuple::new();
797
798        t.add_null();
799
800        assert_eq!(t.elements, vec![TupleValue::NullValue]);
801    }
802
803    #[test]
804    fn add_bytes() {
805        let mut t = Tuple::new();
806
807        t.add_bytes(Bytes::from_static(&b"hello_world"[..]));
808
809        assert_eq!(
810            t.elements,
811            vec![TupleValue::ByteString(Bytes::from_static(
812                &b"hello_world"[..]
813            ))]
814        );
815    }
816
817    #[test]
818    fn add_string() {
819        let mut t = Tuple::new();
820
821        t.add_string("hello world".to_string());
822
823        assert_eq!(
824            t.elements,
825            vec![TupleValue::UnicodeString("hello world".to_string())]
826        );
827    }
828
829    #[test]
830    fn add_tuple() {
831        let mut t = Tuple::new();
832
833        t.add_bigint(BigInt::parse_bytes(b"0", 10).unwrap());
834        t.add_tuple({
835            let mut t1 = Tuple::new();
836            t1.add_versionstamp(Versionstamp::incomplete(0));
837            t1
838        });
839
840        assert!(t.has_incomplete_versionstamp());
841
842        assert_eq!(
843            t.elements,
844            vec![
845                TupleValue::IntZero,
846                TupleValue::NestedTuple(Tuple::from_elements(vec![TupleValue::Versionstamp96Bit(
847                    Versionstamp::incomplete(0)
848                )])),
849            ]
850        );
851    }
852
853    #[test]
854    fn add_bigint() {
855        let mut t = Tuple::new();
856
857        t.add_bigint(BigInt::parse_bytes(b"-18446744073709551616", 10).unwrap());
858        t.add_bigint(BigInt::parse_bytes(b"-18446744073709551615", 10).unwrap());
859        t.add_bigint(BigInt::parse_bytes(b"-9223372036854775809", 10).unwrap());
860        t.add_bigint(BigInt::parse_bytes(b"-9223372036854775808", 10).unwrap()); // i64::MIN
861        t.add_bigint(BigInt::parse_bytes(b"9223372036854775807", 10).unwrap()); // i64::MAX
862        t.add_bigint(BigInt::parse_bytes(b"9223372036854775808", 10).unwrap());
863        t.add_bigint(BigInt::parse_bytes(b"18446744073709551615", 10).unwrap());
864        t.add_bigint(BigInt::parse_bytes(b"18446744073709551616", 10).unwrap());
865
866        assert_eq!(
867            t.elements,
868            vec![
869                TupleValue::NegativeArbitraryPrecisionInteger(
870                    BigInt::parse_bytes(b"18446744073709551616", 10).unwrap()
871                ),
872                TupleValue::NegInt8(18446744073709551615),
873                TupleValue::NegInt8(9223372036854775809),
874                TupleValue::NegInt8(9223372036854775808),
875                TupleValue::PosInt8(9223372036854775807),
876                TupleValue::PosInt8(9223372036854775808),
877                TupleValue::PosInt8(18446744073709551615),
878                TupleValue::PositiveArbitraryPrecisionInteger(
879                    BigInt::parse_bytes(b"18446744073709551616", 10).unwrap()
880                )
881            ]
882        );
883    }
884
885    #[test]
886    fn add_i64() {
887        let mut t = Tuple::new();
888
889        t.add_i64(i64::MIN);
890        t.add_i64(-72057594037927936);
891        t.add_i64(-72057594037927935);
892        t.add_i64(-281474976710656);
893        t.add_i64(-281474976710655);
894        t.add_i64(-1099511627776);
895        t.add_i64(-1099511627775);
896        t.add_i64(-4294967296);
897        t.add_i64(-4294967295);
898        t.add_i64(-2147483649);
899        t.add_i64(-2147483648); // i32::MIN
900        t.add_i64(2147483647); // i32::MAX
901        t.add_i64(2147483648);
902        t.add_i64(4294967295);
903        t.add_i64(4294967296);
904        t.add_i64(1099511627775);
905        t.add_i64(1099511627776);
906        t.add_i64(281474976710655);
907        t.add_i64(281474976710656);
908        t.add_i64(72057594037927935);
909        t.add_i64(72057594037927936);
910        t.add_i64(i64::MAX);
911
912        assert_eq!(
913            t.elements,
914            vec![
915                TupleValue::NegInt8(9223372036854775808),
916                TupleValue::NegInt8(72057594037927936),
917                TupleValue::NegInt7(72057594037927935),
918                TupleValue::NegInt7(281474976710656),
919                TupleValue::NegInt6(281474976710655),
920                TupleValue::NegInt6(1099511627776),
921                TupleValue::NegInt5(1099511627775),
922                TupleValue::NegInt5(4294967296),
923                TupleValue::NegInt4(4294967295),
924                TupleValue::NegInt4(2147483649),
925                TupleValue::NegInt4(2147483648),
926                TupleValue::PosInt4(2147483647),
927                TupleValue::PosInt4(2147483648),
928                TupleValue::PosInt4(4294967295),
929                TupleValue::PosInt5(4294967296),
930                TupleValue::PosInt5(1099511627775),
931                TupleValue::PosInt6(1099511627776),
932                TupleValue::PosInt6(281474976710655),
933                TupleValue::PosInt7(281474976710656),
934                TupleValue::PosInt7(72057594037927935),
935                TupleValue::PosInt8(72057594037927936),
936                TupleValue::PosInt8(9223372036854775807),
937            ]
938        );
939    }
940
941    #[test]
942    fn add_i32() {
943        let mut t = Tuple::new();
944
945        t.add_i32(i32::MIN);
946        t.add_i32(-16777216);
947        t.add_i32(-16777215);
948        t.add_i32(-65536);
949        t.add_i32(-65535);
950        t.add_i32(-32769);
951        t.add_i32(-32768); // i16::MIN
952        t.add_i32(32767); // i16::MAX
953        t.add_i32(32768);
954        t.add_i32(65535);
955        t.add_i32(65536);
956        t.add_i32(16777215);
957        t.add_i32(16777216);
958        t.add_i32(i32::MAX);
959
960        assert_eq!(
961            t.elements,
962            vec![
963                TupleValue::NegInt4(2147483648),
964                TupleValue::NegInt4(16777216),
965                TupleValue::NegInt3(16777215),
966                TupleValue::NegInt3(65536),
967                TupleValue::NegInt2(65535),
968                TupleValue::NegInt2(32769),
969                TupleValue::NegInt2(32768),
970                TupleValue::PosInt2(32767),
971                TupleValue::PosInt2(32768),
972                TupleValue::PosInt2(65535),
973                TupleValue::PosInt3(65536),
974                TupleValue::PosInt3(16777215),
975                TupleValue::PosInt4(16777216),
976                TupleValue::PosInt4(2147483647),
977            ]
978        );
979    }
980
981    #[test]
982    fn add_i16() {
983        let mut t = Tuple::new();
984
985        t.add_i16(i16::MIN);
986        t.add_i16(-256);
987        t.add_i16(-255);
988        t.add_i16(-129);
989        t.add_i16(-128); // i8::MIN
990        t.add_i16(127); // i8::MAX
991        t.add_i16(128);
992        t.add_i16(255);
993        t.add_i16(256);
994        t.add_i16(i16::MAX);
995
996        assert_eq!(
997            t.elements,
998            vec![
999                TupleValue::NegInt2(32768),
1000                TupleValue::NegInt2(256),
1001                TupleValue::NegInt1(255),
1002                TupleValue::NegInt1(129),
1003                TupleValue::NegInt1(128),
1004                TupleValue::PosInt1(127),
1005                TupleValue::PosInt1(128),
1006                TupleValue::PosInt1(255),
1007                TupleValue::PosInt2(256),
1008                TupleValue::PosInt2(32767),
1009            ]
1010        );
1011    }
1012
1013    #[test]
1014    fn add_i8() {
1015        let mut t = Tuple::new();
1016
1017        t.add_i8(i8::MIN);
1018        t.add_i8(0);
1019        t.add_i8(i8::MAX);
1020
1021        assert_eq!(
1022            t.elements,
1023            vec![
1024                TupleValue::NegInt1(128),
1025                TupleValue::IntZero,
1026                TupleValue::PosInt1(127),
1027            ]
1028        );
1029    }
1030
1031    // `3.14` is copied from Java binding tests
1032    #[allow(clippy::approx_constant)]
1033    #[test]
1034    fn add_f32() {
1035        let mut t = Tuple::new();
1036
1037        t.add_f32(3.14f32);
1038
1039        assert_eq!(
1040            t.elements,
1041            vec![TupleValue::IeeeBinaryFloatingPointFloat(3.14f32)]
1042        );
1043    }
1044
1045    // `3.14` is copied from Java binding tests
1046    #[allow(clippy::approx_constant)]
1047    #[test]
1048    fn add_f64() {
1049        let mut t = Tuple::new();
1050
1051        t.add_f64(-3.14f64);
1052
1053        assert_eq!(
1054            t.elements,
1055            vec![TupleValue::IeeeBinaryFloatingPointDouble(-3.14f64)]
1056        );
1057    }
1058
1059    #[test]
1060    fn add_bool() {
1061        let mut t = Tuple::new();
1062
1063        t.add_bool(true);
1064        assert_eq!(t.elements, vec![TupleValue::TrueValue]);
1065
1066        t.add_bool(false);
1067        assert_eq!(
1068            t.elements,
1069            vec![TupleValue::TrueValue, TupleValue::FalseValue]
1070        );
1071    }
1072
1073    #[test]
1074    fn add_uuid() {
1075        let mut t = Tuple::new();
1076
1077        t.add_uuid(Uuid::parse_str("ffffffff-ba5e-ba11-0000-00005ca1ab1e").unwrap());
1078
1079        assert_eq!(
1080            t.elements,
1081            vec![TupleValue::Rfc4122Uuid(
1082                Uuid::parse_str("ffffffff-ba5e-ba11-0000-00005ca1ab1e").unwrap()
1083            )]
1084        );
1085    }
1086
1087    #[test]
1088    fn add_versionstamp() {
1089        let mut t = Tuple::new();
1090
1091        t.add_versionstamp(Versionstamp::complete(
1092            Bytes::from_static(&b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A"[..]),
1093            657,
1094        ));
1095
1096        assert!(!t.has_incomplete_versionstamp());
1097
1098        t.add_versionstamp(Versionstamp::incomplete(0));
1099
1100        assert!(t.has_incomplete_versionstamp());
1101
1102        assert_eq!(
1103            t.elements,
1104            vec![
1105                TupleValue::Versionstamp96Bit(Versionstamp::complete(
1106                    Bytes::from_static(&b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A"[..]),
1107                    657,
1108                )),
1109                TupleValue::Versionstamp96Bit(Versionstamp::incomplete(0))
1110            ]
1111        );
1112    }
1113
1114    #[test]
1115    fn append() {
1116        let mut t = Tuple::new();
1117
1118        t.append({
1119            let mut t1 = Tuple::new();
1120            t1.add_null();
1121            t1
1122        });
1123
1124        t.append({
1125            let mut t1 = Tuple::new();
1126            t1.add_versionstamp(Versionstamp::incomplete(0));
1127            t1
1128        });
1129
1130        assert!(t.has_incomplete_versionstamp());
1131
1132        assert_eq!(
1133            t.elements,
1134            vec![
1135                TupleValue::NullValue,
1136                TupleValue::Versionstamp96Bit(Versionstamp::incomplete(0))
1137            ]
1138        );
1139    }
1140
1141    #[test]
1142    fn has_incomplete_versionstamp() {
1143        let mut t = Tuple::new();
1144
1145        assert!(!t.has_incomplete_versionstamp());
1146
1147        t.add_versionstamp(Versionstamp::incomplete(0));
1148
1149        assert!(t.has_incomplete_versionstamp());
1150    }
1151
1152    #[test]
1153    fn get_null() {
1154        let t = Tuple::new();
1155
1156        assert_eq!(t.get_null(0).unwrap_err(), Tuple::tuple_get_error());
1157
1158        let mut t = Tuple::new();
1159        t.add_bool(true);
1160        t.add_null();
1161
1162        assert_eq!(t.get_null(0).unwrap_err(), Tuple::tuple_get_error());
1163        assert_eq!(t.get_null(1), Ok(()));
1164    }
1165
1166    #[test]
1167    fn get_bytes_ref() {
1168        let t = Tuple::new();
1169
1170        assert_eq!(t.get_bytes_ref(0).unwrap_err(), Tuple::tuple_get_error());
1171
1172        let mut t = Tuple::new();
1173        t.add_null();
1174        t.add_bytes(Bytes::from_static(&b"hello_world"[..]));
1175
1176        assert_eq!(t.get_bytes_ref(0).unwrap_err(), Tuple::tuple_get_error());
1177        assert_eq!(
1178            t.get_bytes_ref(1).unwrap(),
1179            &Bytes::from_static(&b"hello_world"[..])
1180        );
1181    }
1182
1183    #[test]
1184    fn get_string_ref() {
1185        let t = Tuple::new();
1186
1187        assert_eq!(t.get_string_ref(0).unwrap_err(), Tuple::tuple_get_error());
1188
1189        let mut t = Tuple::new();
1190        t.add_null();
1191        t.add_string("hello world".to_string());
1192
1193        assert_eq!(t.get_string_ref(0).unwrap_err(), Tuple::tuple_get_error());
1194        assert_eq!(t.get_string_ref(1).unwrap(), &"hello world".to_string());
1195    }
1196
1197    #[test]
1198    fn get_tuple_ref() {
1199        let t = Tuple::new();
1200
1201        assert_eq!(t.get_tuple_ref(0).unwrap_err(), Tuple::tuple_get_error());
1202
1203        let mut t = Tuple::new();
1204        t.add_null();
1205        t.add_tuple({
1206            let mut t1 = Tuple::new();
1207            t1.add_versionstamp(Versionstamp::incomplete(0));
1208            t1
1209        });
1210
1211        assert_eq!(t.get_tuple_ref(0).unwrap_err(), Tuple::tuple_get_error());
1212        assert_eq!(t.get_tuple_ref(1).unwrap(), &{
1213            let mut t1 = Tuple::new();
1214            t1.add_versionstamp(Versionstamp::incomplete(0));
1215            t1
1216        });
1217    }
1218
1219    #[test]
1220    fn get_bigint() {
1221        let t = Tuple::new();
1222
1223        assert_eq!(t.get_bigint(0).unwrap_err(), Tuple::tuple_get_error());
1224
1225        let mut t = Tuple::new();
1226        t.add_null();
1227        t.add_bigint(BigInt::parse_bytes(b"-18446744073709551616", 10).unwrap());
1228        t.add_bigint(BigInt::parse_bytes(b"-18446744073709551615", 10).unwrap());
1229        t.add_bigint(BigInt::parse_bytes(b"-9223372036854775809", 10).unwrap());
1230        t.add_bigint(BigInt::parse_bytes(b"-9223372036854775808", 10).unwrap()); // i64::MIN
1231        t.add_bigint(BigInt::parse_bytes(b"9223372036854775807", 10).unwrap()); // i64::MAX
1232        t.add_bigint(BigInt::parse_bytes(b"9223372036854775808", 10).unwrap());
1233        t.add_bigint(BigInt::parse_bytes(b"18446744073709551615", 10).unwrap());
1234        t.add_bigint(BigInt::parse_bytes(b"18446744073709551616", 10).unwrap());
1235
1236        assert_eq!(t.get_bigint(0).unwrap_err(), Tuple::tuple_get_error());
1237        assert_eq!(
1238            t.get_bigint(1).unwrap(),
1239            BigInt::parse_bytes(b"-18446744073709551616", 10).unwrap()
1240        );
1241        assert_eq!(
1242            t.get_bigint(2).unwrap(),
1243            BigInt::parse_bytes(b"-18446744073709551615", 10).unwrap()
1244        );
1245        assert_eq!(
1246            t.get_bigint(3).unwrap(),
1247            BigInt::parse_bytes(b"-9223372036854775809", 10).unwrap()
1248        );
1249        assert_eq!(
1250            t.get_bigint(4).unwrap(),
1251            BigInt::parse_bytes(b"-9223372036854775808", 10).unwrap()
1252        );
1253        assert_eq!(
1254            t.get_bigint(5).unwrap(),
1255            BigInt::parse_bytes(b"9223372036854775807", 10).unwrap()
1256        );
1257        assert_eq!(
1258            t.get_bigint(6).unwrap(),
1259            BigInt::parse_bytes(b"9223372036854775808", 10).unwrap()
1260        );
1261        assert_eq!(
1262            t.get_bigint(7).unwrap(),
1263            BigInt::parse_bytes(b"18446744073709551615", 10).unwrap()
1264        );
1265        assert_eq!(
1266            t.get_bigint(8).unwrap(),
1267            BigInt::parse_bytes(b"18446744073709551616", 10).unwrap()
1268        );
1269    }
1270
1271    #[test]
1272    fn get_i64() {
1273        let t = Tuple::new();
1274
1275        assert_eq!(t.get_i64(0).unwrap_err(), Tuple::tuple_get_error());
1276
1277        let mut t = Tuple::new();
1278        t.add_null();
1279        t.add_bigint(BigInt::parse_bytes(b"-9223372036854775809", 10).unwrap());
1280        t.add_i64(i64::MIN);
1281        t.add_i64(-72057594037927936);
1282        t.add_i64(-72057594037927935);
1283        t.add_i64(-281474976710656);
1284        t.add_i64(-281474976710655);
1285        t.add_i64(-1099511627776);
1286        t.add_i64(-1099511627775);
1287        t.add_i64(-4294967296);
1288        t.add_i64(-4294967295);
1289        t.add_i64(-2147483649);
1290        t.add_i64(-2147483648); // i32::MIN
1291        t.add_i64(2147483647); // i32::MAX
1292        t.add_i64(2147483648);
1293        t.add_i64(4294967295);
1294        t.add_i64(4294967296);
1295        t.add_i64(1099511627775);
1296        t.add_i64(1099511627776);
1297        t.add_i64(281474976710655);
1298        t.add_i64(281474976710656);
1299        t.add_i64(72057594037927935);
1300        t.add_i64(72057594037927936);
1301        t.add_i64(i64::MAX);
1302        t.add_bigint(BigInt::parse_bytes(b"9223372036854775808", 10).unwrap());
1303
1304        assert_eq!(t.get_i64(0).unwrap_err(), Tuple::tuple_get_error());
1305        assert_eq!(t.get_i64(1).unwrap_err(), Tuple::tuple_get_error());
1306        assert_eq!(t.get_i64(2).unwrap(), i64::MIN);
1307        assert_eq!(t.get_i64(3).unwrap(), -72057594037927936);
1308        assert_eq!(t.get_i64(4).unwrap(), -72057594037927935);
1309        assert_eq!(t.get_i64(5).unwrap(), -281474976710656);
1310        assert_eq!(t.get_i64(6).unwrap(), -281474976710655);
1311        assert_eq!(t.get_i64(7).unwrap(), -1099511627776);
1312        assert_eq!(t.get_i64(8).unwrap(), -1099511627775);
1313        assert_eq!(t.get_i64(9).unwrap(), -4294967296);
1314        assert_eq!(t.get_i64(10).unwrap(), -4294967295);
1315        assert_eq!(t.get_i64(11).unwrap(), -2147483649);
1316        assert_eq!(t.get_i64(12).unwrap(), -2147483648);
1317        assert_eq!(t.get_i64(13).unwrap(), 2147483647);
1318        assert_eq!(t.get_i64(14).unwrap(), 2147483648);
1319        assert_eq!(t.get_i64(15).unwrap(), 4294967295);
1320        assert_eq!(t.get_i64(16).unwrap(), 4294967296);
1321        assert_eq!(t.get_i64(17).unwrap(), 1099511627775);
1322        assert_eq!(t.get_i64(18).unwrap(), 1099511627776);
1323        assert_eq!(t.get_i64(19).unwrap(), 281474976710655);
1324        assert_eq!(t.get_i64(20).unwrap(), 281474976710656);
1325        assert_eq!(t.get_i64(21).unwrap(), 72057594037927935);
1326        assert_eq!(t.get_i64(22).unwrap(), 72057594037927936);
1327        assert_eq!(t.get_i64(23).unwrap(), i64::MAX);
1328        assert_eq!(t.get_i64(24).unwrap_err(), Tuple::tuple_get_error());
1329    }
1330
1331    #[test]
1332    fn get_i32() {
1333        let t = Tuple::new();
1334
1335        assert_eq!(t.get_i32(0).unwrap_err(), Tuple::tuple_get_error());
1336
1337        let mut t = Tuple::new();
1338        t.add_null();
1339        t.add_i64(-2147483649);
1340        t.add_i32(i32::MIN);
1341        t.add_i32(-16777216);
1342        t.add_i32(-16777215);
1343        t.add_i32(-65536);
1344        t.add_i32(-65535);
1345        t.add_i32(-32769);
1346        t.add_i32(-32768); // i16::MIN
1347        t.add_i32(32767); // i16::MAX
1348        t.add_i32(32768);
1349        t.add_i32(65535);
1350        t.add_i32(65536);
1351        t.add_i32(16777215);
1352        t.add_i32(16777216);
1353        t.add_i32(i32::MAX);
1354        t.add_i64(2147483648);
1355
1356        assert_eq!(t.get_i32(0).unwrap_err(), Tuple::tuple_get_error());
1357        assert_eq!(t.get_i32(1).unwrap_err(), Tuple::tuple_get_error());
1358        assert_eq!(t.get_i32(2).unwrap(), i32::MIN);
1359        assert_eq!(t.get_i32(3).unwrap(), -16777216);
1360        assert_eq!(t.get_i32(4).unwrap(), -16777215);
1361        assert_eq!(t.get_i32(5).unwrap(), -65536);
1362        assert_eq!(t.get_i32(6).unwrap(), -65535);
1363        assert_eq!(t.get_i32(7).unwrap(), -32769);
1364        assert_eq!(t.get_i32(8).unwrap(), -32768);
1365        assert_eq!(t.get_i32(9).unwrap(), 32767);
1366        assert_eq!(t.get_i32(10).unwrap(), 32768);
1367        assert_eq!(t.get_i32(11).unwrap(), 65535);
1368        assert_eq!(t.get_i32(12).unwrap(), 65536);
1369        assert_eq!(t.get_i32(13).unwrap(), 16777215);
1370        assert_eq!(t.get_i32(14).unwrap(), 16777216);
1371        assert_eq!(t.get_i32(15).unwrap(), i32::MAX);
1372        assert_eq!(t.get_i32(16).unwrap_err(), Tuple::tuple_get_error());
1373    }
1374
1375    #[test]
1376    fn get_i16() {
1377        let t = Tuple::new();
1378
1379        assert_eq!(t.get_i16(0).unwrap_err(), Tuple::tuple_get_error());
1380
1381        let mut t = Tuple::new();
1382        t.add_null();
1383        t.add_i32(-32769);
1384        t.add_i16(i16::MIN);
1385        t.add_i16(-256);
1386        t.add_i16(-255);
1387        t.add_i16(-129);
1388        t.add_i16(-128); // i8::MIN
1389        t.add_i16(127); // i8::MAX
1390        t.add_i16(128);
1391        t.add_i16(255);
1392        t.add_i16(256);
1393        t.add_i16(i16::MAX);
1394        t.add_i32(32768);
1395
1396        assert_eq!(t.get_i16(0).unwrap_err(), Tuple::tuple_get_error());
1397        assert_eq!(t.get_i16(1).unwrap_err(), Tuple::tuple_get_error());
1398        assert_eq!(t.get_i16(2).unwrap(), i16::MIN);
1399        assert_eq!(t.get_i16(3).unwrap(), -256);
1400        assert_eq!(t.get_i16(4).unwrap(), -255);
1401        assert_eq!(t.get_i16(5).unwrap(), -129);
1402        assert_eq!(t.get_i16(6).unwrap(), -128);
1403        assert_eq!(t.get_i16(7).unwrap(), 127);
1404        assert_eq!(t.get_i16(8).unwrap(), 128);
1405        assert_eq!(t.get_i16(9).unwrap(), 255);
1406        assert_eq!(t.get_i16(10).unwrap(), 256);
1407        assert_eq!(t.get_i16(11).unwrap(), i16::MAX);
1408        assert_eq!(t.get_i16(12).unwrap_err(), Tuple::tuple_get_error());
1409    }
1410
1411    #[test]
1412    fn get_i8() {
1413        let t = Tuple::new();
1414
1415        assert_eq!(t.get_i8(0).unwrap_err(), Tuple::tuple_get_error());
1416
1417        let mut t = Tuple::new();
1418        t.add_null();
1419        t.add_i16(-129);
1420        t.add_i8(i8::MIN);
1421        t.add_i8(0);
1422        t.add_i8(i8::MAX);
1423        t.add_i16(128);
1424
1425        assert_eq!(t.get_i8(0).unwrap_err(), Tuple::tuple_get_error());
1426        assert_eq!(t.get_i8(1).unwrap_err(), Tuple::tuple_get_error());
1427        assert_eq!(t.get_i8(2).unwrap(), i8::MIN);
1428        assert_eq!(t.get_i8(3).unwrap(), 0);
1429        assert_eq!(t.get_i8(4).unwrap(), i8::MAX);
1430        assert_eq!(t.get_i8(5).unwrap_err(), Tuple::tuple_get_error());
1431    }
1432
1433    // `3.14` is copied from Java binding tests
1434    #[allow(clippy::approx_constant)]
1435    #[test]
1436    fn get_f32() {
1437        let t = Tuple::new();
1438
1439        assert_eq!(t.get_f32(0).unwrap_err(), Tuple::tuple_get_error());
1440
1441        let mut t = Tuple::new();
1442        t.add_null();
1443        t.add_f32(3.14f32);
1444
1445        assert_eq!(t.get_f32(0).unwrap_err(), Tuple::tuple_get_error());
1446        assert_eq!(t.get_f32(1).unwrap(), 3.14f32);
1447    }
1448
1449    // `3.14` is copied from Java binding tests
1450    #[allow(clippy::approx_constant)]
1451    #[test]
1452    fn get_f64() {
1453        let t = Tuple::new();
1454
1455        assert_eq!(t.get_f64(0).unwrap_err(), Tuple::tuple_get_error());
1456
1457        let mut t = Tuple::new();
1458        t.add_null();
1459        t.add_f64(3.14f64);
1460
1461        assert_eq!(t.get_f64(0).unwrap_err(), Tuple::tuple_get_error());
1462        assert_eq!(t.get_f64(1).unwrap(), 3.14f64);
1463    }
1464
1465    #[test]
1466    fn get_bool() {
1467        let t = Tuple::new();
1468
1469        assert_eq!(t.get_bool(0).unwrap_err(), Tuple::tuple_get_error());
1470
1471        let mut t = Tuple::new();
1472        t.add_null();
1473        t.add_bool(true);
1474        t.add_bool(false);
1475
1476        assert_eq!(t.get_bool(0).unwrap_err(), Tuple::tuple_get_error());
1477        assert_eq!(t.get_bool(1), Ok(true));
1478        assert_eq!(t.get_bool(2), Ok(false));
1479    }
1480
1481    #[test]
1482    fn get_uuid_ref() {
1483        let t = Tuple::new();
1484
1485        assert_eq!(t.get_uuid_ref(0).unwrap_err(), Tuple::tuple_get_error());
1486
1487        let mut t = Tuple::new();
1488        t.add_null();
1489        t.add_uuid(Uuid::parse_str("ffffffff-ba5e-ba11-0000-00005ca1ab1e").unwrap());
1490
1491        assert_eq!(t.get_uuid_ref(0).unwrap_err(), Tuple::tuple_get_error());
1492        assert_eq!(
1493            t.get_uuid_ref(1).unwrap(),
1494            &Uuid::parse_str("ffffffff-ba5e-ba11-0000-00005ca1ab1e").unwrap()
1495        );
1496    }
1497
1498    #[test]
1499    fn get_versionstamp_ref() {
1500        let t = Tuple::new();
1501
1502        assert_eq!(
1503            t.get_versionstamp_ref(0).unwrap_err(),
1504            Tuple::tuple_get_error()
1505        );
1506
1507        let mut t = Tuple::new();
1508        t.add_null();
1509        t.add_versionstamp(Versionstamp::complete(
1510            Bytes::from_static(&b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A"[..]),
1511            657,
1512        ));
1513
1514        assert_eq!(
1515            t.get_versionstamp_ref(0).unwrap_err(),
1516            Tuple::tuple_get_error()
1517        );
1518        assert_eq!(
1519            t.get_versionstamp_ref(1).unwrap(),
1520            &Versionstamp::complete(
1521                Bytes::from_static(&b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A"[..]),
1522                657,
1523            )
1524        );
1525    }
1526
1527    #[test]
1528    fn is_empty() {
1529        let mut t = Tuple::new();
1530
1531        assert!(t.is_empty());
1532
1533        t.add_null();
1534
1535        assert!(!t.is_empty());
1536    }
1537
1538    #[test]
1539    fn size() {
1540        let mut t = Tuple::new();
1541
1542        assert_eq!(t.size(), 0);
1543
1544        t.add_null();
1545
1546        assert_eq!(t.size(), 1);
1547    }
1548
1549    // `3.14` is copied from Java binding tests
1550    #[allow(clippy::approx_constant)]
1551    #[test]
1552    fn pack() {
1553        assert_eq!(
1554            {
1555                let mut t = Tuple::new();
1556                t.add_i64(0);
1557                t
1558            }
1559            .pack(),
1560            Bytes::from_static(&b"\x14"[..])
1561        );
1562        assert_eq!(
1563            {
1564                let mut t = Tuple::new();
1565                t.add_bigint(BigInt::parse_bytes(b"0", 10).unwrap());
1566                t
1567            }
1568            .pack(),
1569            Bytes::from_static(&b"\x14"[..])
1570        );
1571        assert_eq!(
1572            {
1573                let mut t = Tuple::new();
1574                t.add_i64(1);
1575                t
1576            }
1577            .pack(),
1578            Bytes::from_static(&b"\x15\x01"[..])
1579        );
1580        assert_eq!(
1581            {
1582                let mut t = Tuple::new();
1583                t.add_bigint(BigInt::parse_bytes(b"1", 10).unwrap());
1584                t
1585            }
1586            .pack(),
1587            Bytes::from_static(&b"\x15\x01"[..])
1588        );
1589        assert_eq!(
1590            {
1591                let mut t = Tuple::new();
1592                t.add_i64(-1);
1593                t
1594            }
1595            .pack(),
1596            Bytes::from_static(&b"\x13\xFE"[..])
1597        );
1598        assert_eq!(
1599            {
1600                let mut t = Tuple::new();
1601                t.add_bigint(BigInt::parse_bytes(b"-1", 10).unwrap());
1602                t
1603            }
1604            .pack(),
1605            Bytes::from_static(&b"\x13\xFE"[..])
1606        );
1607        assert_eq!(
1608            {
1609                let mut t = Tuple::new();
1610                t.add_i64(255);
1611                t
1612            }
1613            .pack(),
1614            Bytes::from_static(&b"\x15\xFF"[..])
1615        );
1616        assert_eq!(
1617            {
1618                let mut t = Tuple::new();
1619                t.add_bigint(BigInt::parse_bytes(b"255", 10).unwrap());
1620                t
1621            }
1622            .pack(),
1623            Bytes::from_static(&b"\x15\xFF"[..])
1624        );
1625        assert_eq!(
1626            {
1627                let mut t = Tuple::new();
1628                t.add_i64(-255);
1629                t
1630            }
1631            .pack(),
1632            Bytes::from_static(&b"\x13\x00"[..])
1633        );
1634        assert_eq!(
1635            {
1636                let mut t = Tuple::new();
1637                t.add_bigint(BigInt::parse_bytes(b"-255", 10).unwrap());
1638                t
1639            }
1640            .pack(),
1641            Bytes::from_static(&b"\x13\x00"[..])
1642        );
1643        assert_eq!(
1644            {
1645                let mut t = Tuple::new();
1646                t.add_i64(256);
1647                t
1648            }
1649            .pack(),
1650            Bytes::from_static(&b"\x16\x01\x00"[..])
1651        );
1652        assert_eq!(
1653            {
1654                let mut t = Tuple::new();
1655                t.add_bigint(BigInt::parse_bytes(b"256", 10).unwrap());
1656                t
1657            }
1658            .pack(),
1659            Bytes::from_static(&b"\x16\x01\x00"[..])
1660        );
1661        assert_eq!(
1662            {
1663                let mut t = Tuple::new();
1664                t.add_i32(65536);
1665                t
1666            }
1667            .pack(),
1668            Bytes::from_static(&b"\x17\x01\x00\x00"[..])
1669        );
1670        assert_eq!(
1671            {
1672                let mut t = Tuple::new();
1673                t.add_i32(-65536);
1674                t
1675            }
1676            .pack(),
1677            Bytes::from_static(&b"\x11\xFE\xFF\xFF"[..])
1678        );
1679        assert_eq!(
1680            {
1681                let mut t = Tuple::new();
1682                t.add_i64(i64::MAX);
1683                t
1684            }
1685            .pack(),
1686            Bytes::from_static(&b"\x1C\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF"[..]),
1687        );
1688        assert_eq!(
1689            {
1690                let mut t = Tuple::new();
1691                t.add_bigint(BigInt::parse_bytes(b"9223372036854775807", 10).unwrap());
1692                t
1693            }
1694            .pack(),
1695            Bytes::from_static(&b"\x1C\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF"[..])
1696        );
1697        assert_eq!(
1698            {
1699                let mut t = Tuple::new();
1700                t.add_bigint(BigInt::parse_bytes(b"9223372036854775808", 10).unwrap());
1701                t
1702            }
1703            .pack(),
1704            Bytes::from_static(&b"\x1C\x80\x00\x00\x00\x00\x00\x00\x00"[..])
1705        );
1706        assert_eq!(
1707            {
1708                let mut t = Tuple::new();
1709                t.add_bigint(BigInt::parse_bytes(b"18446744073709551615", 10).unwrap());
1710                t
1711            }
1712            .pack(),
1713            Bytes::from_static(&b"\x1C\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"[..])
1714        );
1715        assert_eq!(
1716            {
1717                let mut t = Tuple::new();
1718                t.add_bigint(BigInt::parse_bytes(b"18446744073709551616", 10).unwrap());
1719                t
1720            }
1721            .pack(),
1722            Bytes::from_static(&b"\x1D\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00"[..])
1723        );
1724        assert_eq!(
1725            {
1726                let mut t = Tuple::new();
1727                t.add_i64(-4294967295);
1728                t
1729            }
1730            .pack(),
1731            Bytes::from_static(&b"\x10\x00\x00\x00\x00"[..])
1732        );
1733        assert_eq!(
1734            {
1735                let mut t = Tuple::new();
1736                t.add_bigint(BigInt::parse_bytes(b"-4294967295", 10).unwrap());
1737                t
1738            }
1739            .pack(),
1740            Bytes::from_static(&b"\x10\x00\x00\x00\x00"[..]),
1741        );
1742        assert_eq!(
1743            {
1744                let mut t = Tuple::new();
1745                t.add_i64(i64::MIN + 2);
1746                t
1747            }
1748            .pack(),
1749            Bytes::from_static(&b"\x0C\x80\x00\x00\x00\x00\x00\x00\x01"[..]),
1750        );
1751        assert_eq!(
1752            {
1753                let mut t = Tuple::new();
1754                t.add_i64(i64::MIN + 1);
1755                t
1756            }
1757            .pack(),
1758            Bytes::from_static(&b"\x0C\x80\x00\x00\x00\x00\x00\x00\x00"[..])
1759        );
1760        assert_eq!(
1761            {
1762                let mut t = Tuple::new();
1763                t.add_bigint(
1764                    // i64::MIN + 1
1765                    BigInt::parse_bytes(b"-9223372036854775808", 10).unwrap() + 1,
1766                );
1767                t
1768            }
1769            .pack(),
1770            Bytes::from_static(&b"\x0C\x80\x00\x00\x00\x00\x00\x00\x00"[..]),
1771        );
1772        assert_eq!(
1773            {
1774                let mut t = Tuple::new();
1775                t.add_i64(i64::MIN);
1776                t
1777            }
1778            .pack(),
1779            Bytes::from_static(&b"\x0C\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF"[..])
1780        );
1781        assert_eq!(
1782            {
1783                let mut t = Tuple::new();
1784                t.add_bigint(
1785                    // i64::MIN
1786                    BigInt::parse_bytes(b"-9223372036854775808", 10).unwrap(),
1787                );
1788                t
1789            }
1790            .pack(),
1791            Bytes::from_static(&b"\x0C\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF"[..])
1792        );
1793        assert_eq!(
1794            {
1795                let mut t = Tuple::new();
1796                t.add_bigint(
1797                    // i64::MIN - 1
1798                    BigInt::parse_bytes(b"-9223372036854775808", 10).unwrap() - 1,
1799                );
1800                t
1801            }
1802            .pack(),
1803            Bytes::from_static(&b"\x0C\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFE"[..])
1804        );
1805        assert_eq!(
1806            {
1807                let mut t = Tuple::new();
1808                t.add_bigint(BigInt::parse_bytes(b"-18446744073709551615", 10).unwrap());
1809                t
1810            }
1811            .pack(),
1812            Bytes::from_static(&b"\x0C\x00\x00\x00\x00\x00\x00\x00\x00"[..])
1813        );
1814        assert_eq!(
1815            {
1816                let mut t = Tuple::new();
1817                t.add_f32(3.14f32);
1818                t
1819            }
1820            .pack(),
1821            Bytes::from_static(&b"\x20\xC0\x48\xF5\xC3"[..])
1822        );
1823        assert_eq!(
1824            {
1825                let mut t = Tuple::new();
1826                t.add_f32(-3.14f32);
1827                t
1828            }
1829            .pack(),
1830            Bytes::from_static(&b"\x20\x3F\xB7\x0A\x3C"[..])
1831        );
1832        assert_eq!(
1833            {
1834                let mut t = Tuple::new();
1835                t.add_f64(3.14f64);
1836                t
1837            }
1838            .pack(),
1839            Bytes::from_static(&b"\x21\xC0\x09\x1E\xB8\x51\xEB\x85\x1F"[..])
1840        );
1841        assert_eq!(
1842            {
1843                let mut t = Tuple::new();
1844                t.add_f64(-3.14f64);
1845                t
1846            }
1847            .pack(),
1848            Bytes::from_static(&b"\x21\x3F\xF6\xE1\x47\xAE\x14\x7A\xE0"[..])
1849        );
1850        assert_eq!(
1851            {
1852                let mut t = Tuple::new();
1853                t.add_f32(0.0f32);
1854                t
1855            }
1856            .pack(),
1857            Bytes::from_static(&b"\x20\x80\x00\x00\x00"[..])
1858        );
1859        assert_eq!(
1860            {
1861                let mut t = Tuple::new();
1862                t.add_f32(-0.0f32);
1863                t
1864            }
1865            .pack(),
1866            Bytes::from_static(&b"\x20\x7F\xFF\xFF\xFF"[..])
1867        );
1868        assert_eq!(
1869            {
1870                let mut t = Tuple::new();
1871                t.add_f64(0.0f64);
1872                t
1873            }
1874            .pack(),
1875            Bytes::from_static(&b"\x21\x80\x00\x00\x00\x00\x00\x00\x00"[..])
1876        );
1877        assert_eq!(
1878            {
1879                let mut t = Tuple::new();
1880                t.add_f64(-0.0f64);
1881                t
1882            }
1883            .pack(),
1884            Bytes::from_static(&b"\x21\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF"[..])
1885        );
1886        assert_eq!(
1887            {
1888                let mut t = Tuple::new();
1889                t.add_f32(f32::INFINITY);
1890                t
1891            }
1892            .pack(),
1893            Bytes::from_static(&b"\x20\xFF\x80\x00\x00"[..])
1894        );
1895        assert_eq!(
1896            {
1897                let mut t = Tuple::new();
1898                t.add_f32(f32::NEG_INFINITY);
1899                t
1900            }
1901            .pack(),
1902            Bytes::from_static(&b"\x20\x00\x7F\xFF\xFF"[..])
1903        );
1904        assert_eq!(
1905            {
1906                let mut t = Tuple::new();
1907                t.add_f64(f64::INFINITY);
1908                t
1909            }
1910            .pack(),
1911            Bytes::from_static(&b"\x21\xFF\xF0\x00\x00\x00\x00\x00\x00"[..])
1912        );
1913        assert_eq!(
1914            {
1915                let mut t = Tuple::new();
1916                t.add_f64(f64::NEG_INFINITY);
1917                t
1918            }
1919            .pack(),
1920            Bytes::from_static(&b"\x21\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF"[..])
1921        );
1922        assert_eq!(
1923            {
1924                let mut t = Tuple::new();
1925                t.add_bytes(Bytes::new());
1926                t
1927            }
1928            .pack(),
1929            Bytes::from_static(&b"\x01\x00"[..]),
1930        );
1931        assert_eq!(
1932            {
1933                let mut t = Tuple::new();
1934                t.add_bytes(Bytes::from_static(&b"\x01\x02\x03"[..]));
1935                t
1936            }
1937            .pack(),
1938            Bytes::from_static(&b"\x01\x01\x02\x03\x00"[..])
1939        );
1940        assert_eq!(
1941            {
1942                let mut t = Tuple::new();
1943                t.add_bytes(Bytes::from_static(&b"\x00\x00\x00\x04"[..]));
1944                t
1945            }
1946            .pack(),
1947            Bytes::from_static(&b"\x01\x00\xFF\x00\xFF\x00\xFF\x04\x00"[..])
1948        );
1949        assert_eq!(
1950            {
1951                let mut t = Tuple::new();
1952                t.add_string("".to_string());
1953                t
1954            }
1955            .pack(),
1956            Bytes::from_static(&b"\x02\x00"[..])
1957        );
1958        assert_eq!(
1959            {
1960                let mut t = Tuple::new();
1961                t.add_string("hello".to_string());
1962                t
1963            }
1964            .pack(),
1965            Bytes::from_static(&b"\x02hello\x00"[..]),
1966        );
1967        assert_eq!(
1968            {
1969                let mut t = Tuple::new();
1970                t.add_string("中文".to_string());
1971                t
1972            }
1973            .pack(),
1974            Bytes::from_static(&b"\x02\xE4\xB8\xAD\xE6\x96\x87\x00"[..]),
1975        );
1976        assert_eq!(
1977            {
1978                let mut t = Tuple::new();
1979                t.add_string("μάθημα".to_string());
1980                t
1981            }
1982            .pack(),
1983            Bytes::from_static(&b"\x02\xCE\xBC\xCE\xAC\xCE\xB8\xCE\xB7\xCE\xBC\xCE\xB1\x00"[..])
1984        );
1985        assert_eq!(
1986            {
1987                let mut t = Tuple::new();
1988                t.add_string("\u{10ffff}".to_string());
1989                t
1990            }
1991            .pack(),
1992            Bytes::from_static(&b"\x02\xF4\x8F\xBF\xBF\x00"[..])
1993        );
1994        assert_eq!(
1995            {
1996                let mut t = Tuple::new();
1997                t.add_tuple({
1998                    let mut t1 = Tuple::new();
1999                    t1.add_null();
2000                    t1
2001                });
2002                t
2003            }
2004            .pack(),
2005            Bytes::from_static(&b"\x05\x00\xFF\x00"[..])
2006        );
2007        assert_eq!(
2008            {
2009                let mut t = Tuple::new();
2010                t.add_tuple({
2011                    let mut t1 = Tuple::new();
2012                    t1.add_null();
2013                    t1.add_string("hello".to_string());
2014                    t1
2015                });
2016                t
2017            }
2018            .pack(),
2019            Bytes::from_static(&b"\x05\x00\xFF\x02hello\x00\x00"[..])
2020        );
2021        assert_eq!(
2022            {
2023                let mut t = Tuple::new();
2024                t.add_tuple({
2025                    let mut t1 = Tuple::new();
2026                    t1.add_null();
2027                    t1.add_string("hell\x00".to_string());
2028                    t1
2029                });
2030                t
2031            }
2032            .pack(),
2033            Bytes::from_static(&b"\x05\x00\xFF\x02hell\x00\xFF\x00\x00"[..])
2034        );
2035        assert_eq!(
2036            {
2037                let mut t = Tuple::new();
2038                t.add_tuple({
2039                    let mut t1 = Tuple::new();
2040                    t1.add_null();
2041                    t1
2042                });
2043                t.add_string("hello".to_string());
2044                t
2045            }
2046            .pack(),
2047            Bytes::from_static(&b"\x05\x00\xFF\x00\x02hello\x00"[..]),
2048        );
2049        assert_eq!(
2050            {
2051                let mut t = Tuple::new();
2052                t.add_tuple({
2053                    let mut t1 = Tuple::new();
2054                    t1.add_null();
2055                    t1
2056                });
2057                t.add_string("hello".to_string());
2058                t.add_bytes(Bytes::from_static(&b"\x01\x00"[..]));
2059                t.add_bytes(Bytes::new());
2060                t
2061            }
2062            .pack(),
2063            Bytes::from_static(&b"\x05\x00\xFF\x00\x02hello\x00\x01\x01\x00\xFF\x00\x01\x00"[..]),
2064        );
2065        assert_eq!(
2066            {
2067                let mut t = Tuple::new();
2068                t.add_uuid(Uuid::parse_str("ffffffff-ba5e-ba11-0000-00005ca1ab1e").unwrap());
2069                t
2070            }
2071            .pack(),
2072            Bytes::from_static(
2073                &b"\x30\xFF\xFF\xFF\xFF\xBA\x5E\xBA\x11\x00\x00\x00\x00\x5C\xA1\xAB\x1E"[..]
2074            )
2075        );
2076        assert_eq!(
2077            {
2078                let mut t = Tuple::new();
2079                t.add_bool(false);
2080                t
2081            }
2082            .pack(),
2083            Bytes::from_static(&b"\x26"[..])
2084        );
2085        assert_eq!(
2086            {
2087                let mut t = Tuple::new();
2088                t.add_bool(true);
2089                t
2090            }
2091            .pack(),
2092            Bytes::from_static(&b"\x27"[..]),
2093        );
2094        assert_eq!(
2095            {
2096                let mut t = Tuple::new();
2097                t.add_i8(3);
2098                t
2099            }
2100            .pack(),
2101            Bytes::from_static(&b"\x15\x03"[..])
2102        );
2103        assert_eq!(
2104            {
2105                let mut t = Tuple::new();
2106                t.add_versionstamp(Versionstamp::complete(
2107                    Bytes::from_static(&b"\xAA\xBB\xCC\xDD\xEE\xFF\x00\x01\x02\x03"[..]),
2108                    0,
2109                ));
2110                t
2111            }
2112            .pack(),
2113            Bytes::from_static(&b"\x33\xAA\xBB\xCC\xDD\xEE\xFF\x00\x01\x02\x03\x00\x00"[..])
2114        );
2115        assert_eq!(
2116            {
2117                let mut t = Tuple::new();
2118                t.add_versionstamp(Versionstamp::complete(
2119                    Bytes::from_static(&b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A"[..]),
2120                    657,
2121                ));
2122                t
2123            }
2124            .pack(),
2125            Bytes::from_static(&b"\x33\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x02\x91"[..])
2126        );
2127    }
2128
2129    #[test]
2130    fn pack_with_versionstamp() {
2131        assert_eq!(
2132            {
2133                let mut t = Tuple::new();
2134                t.add_string("foo".to_string());
2135                t.add_versionstamp(Versionstamp::incomplete(0));
2136                t
2137            }
2138            .pack_with_versionstamp(Bytes::new()),
2139            Ok(Bytes::from_static(
2140                &b"\x02foo\x00\x33\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x06\x00\x00\x00"
2141                    [..]
2142            ))
2143        );
2144        assert_eq!(
2145            Tuple::new().pack_with_versionstamp(Bytes::new()),
2146            Err(FdbError::new(TUPLE_PACK_WITH_VERSIONSTAMP_NOT_FOUND))
2147        );
2148        assert_eq!(
2149            {
2150                let mut t = Tuple::new();
2151                t.add_null();
2152                t.add_versionstamp(Versionstamp::incomplete(0));
2153                t.add_tuple({
2154                    let mut t1 = Tuple::new();
2155                    t1.add_string("foo".to_string());
2156                    t1.add_versionstamp(Versionstamp::incomplete(1));
2157                    t1
2158                });
2159                t
2160            }
2161            .pack_with_versionstamp(Bytes::new()),
2162            Err(FdbError::new(TUPLE_PACK_WITH_VERSIONSTAMP_MULTIPLE_FOUND))
2163        );
2164    }
2165
2166    #[test]
2167    fn range() {
2168        assert!(std::panic::catch_unwind(|| {
2169            {
2170                let mut t = Tuple::new();
2171                t.add_versionstamp(Versionstamp::incomplete(0));
2172                t
2173            }
2174            .range(Bytes::new());
2175        })
2176        .is_err());
2177        assert_eq!(
2178            {
2179                let mut t = Tuple::new();
2180                t.add_bytes(Bytes::from_static(&b"bar"[..]));
2181                t
2182            }
2183            .range(Bytes::from_static(&b"foo"[..])),
2184            Range::new(
2185                Bytes::from_static(&b"foo\x01bar\x00\x00"[..]),
2186                Bytes::from_static(&b"foo\x01bar\x00\xFF"[..])
2187            )
2188        );
2189    }
2190
2191    #[test]
2192    fn from_elements() {
2193        let mut t1 = Tuple::new();
2194        t1.add_null();
2195
2196        let t = Tuple::from_elements(t1.elements);
2197
2198        assert!(!t.has_incomplete_versionstamp());
2199        assert_eq!(t.elements, vec![TupleValue::NullValue]);
2200
2201        let mut t1 = Tuple::new();
2202        t1.add_null();
2203
2204        let mut t2 = Tuple::new();
2205        t2.add_versionstamp(Versionstamp::incomplete(0));
2206        t1.add_tuple(t2);
2207
2208        let t = Tuple::from_elements(t1.elements);
2209
2210        assert!(t.has_incomplete_versionstamp());
2211        assert_eq!(
2212            t.elements,
2213            vec![
2214                TupleValue::NullValue,
2215                // We don't want to use `Tuple::from_elements` here.
2216                TupleValue::NestedTuple({
2217                    let mut x = Tuple::new();
2218                    x.add_versionstamp(Versionstamp::incomplete(0));
2219                    x
2220                }),
2221            ]
2222        );
2223
2224        let mut t1 = Tuple::new();
2225        t1.add_null();
2226        t1.add_versionstamp(Versionstamp::incomplete(0));
2227
2228        let t = Tuple::from_elements(t1.elements);
2229
2230        assert!(t.has_incomplete_versionstamp());
2231        assert_eq!(
2232            t.elements,
2233            vec![
2234                TupleValue::NullValue,
2235                // We don't want to use `Tuple::from_elements` here.
2236                TupleValue::Versionstamp96Bit(Versionstamp::incomplete(0)),
2237            ]
2238        );
2239    }
2240}