parquet_variant/
builder.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17use crate::decoder::{VariantBasicType, VariantPrimitiveType};
18use crate::{ShortString, Variant, VariantDecimal16, VariantDecimal4, VariantDecimal8};
19use arrow_schema::ArrowError;
20use indexmap::{IndexMap, IndexSet};
21use std::collections::HashSet;
22
23const BASIC_TYPE_BITS: u8 = 2;
24const UNIX_EPOCH_DATE: chrono::NaiveDate = chrono::NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
25
26fn primitive_header(primitive_type: VariantPrimitiveType) -> u8 {
27    (primitive_type as u8) << 2 | VariantBasicType::Primitive as u8
28}
29
30fn short_string_header(len: usize) -> u8 {
31    (len as u8) << 2 | VariantBasicType::ShortString as u8
32}
33
34fn array_header(large: bool, offset_size: u8) -> u8 {
35    let large_bit = if large { 1 } else { 0 };
36    (large_bit << (BASIC_TYPE_BITS + 2))
37        | ((offset_size - 1) << BASIC_TYPE_BITS)
38        | VariantBasicType::Array as u8
39}
40
41fn object_header(large: bool, id_size: u8, offset_size: u8) -> u8 {
42    let large_bit = if large { 1 } else { 0 };
43    (large_bit << (BASIC_TYPE_BITS + 4))
44        | ((id_size - 1) << (BASIC_TYPE_BITS + 2))
45        | ((offset_size - 1) << BASIC_TYPE_BITS)
46        | VariantBasicType::Object as u8
47}
48
49fn int_size(v: usize) -> u8 {
50    match v {
51        0..=0xFF => 1,
52        0x100..=0xFFFF => 2,
53        0x10000..=0xFFFFFF => 3,
54        _ => 4,
55    }
56}
57
58/// Write little-endian integer to buffer
59fn write_offset(buf: &mut Vec<u8>, value: usize, nbytes: u8) {
60    let bytes = value.to_le_bytes();
61    buf.extend_from_slice(&bytes[..nbytes as usize]);
62}
63
64/// Wrapper around a `Vec<u8>` that provides methods for appending
65/// primitive values, variant types, and metadata.
66///
67/// This is used internally by the builders to construct the
68/// the `value` field for [`Variant`] values.
69///
70/// You can reuse an existing `Vec<u8>` by using the `from` impl
71#[derive(Debug, Default)]
72struct ValueBuffer(Vec<u8>);
73
74impl ValueBuffer {
75    /// Construct a ValueBuffer that will write to a new underlying `Vec`
76    fn new() -> Self {
77        Default::default()
78    }
79}
80
81impl From<Vec<u8>> for ValueBuffer {
82    fn from(value: Vec<u8>) -> Self {
83        Self(value)
84    }
85}
86
87impl From<ValueBuffer> for Vec<u8> {
88    fn from(value_buffer: ValueBuffer) -> Self {
89        value_buffer.0
90    }
91}
92
93impl ValueBuffer {
94    fn append_u8(&mut self, term: u8) {
95        self.0.push(term);
96    }
97
98    fn append_slice(&mut self, other: &[u8]) {
99        self.0.extend_from_slice(other);
100    }
101
102    fn append_primitive_header(&mut self, primitive_type: VariantPrimitiveType) {
103        self.0.push(primitive_header(primitive_type));
104    }
105
106    fn inner(&self) -> &[u8] {
107        &self.0
108    }
109
110    fn into_inner(self) -> Vec<u8> {
111        self.into()
112    }
113
114    fn inner_mut(&mut self) -> &mut Vec<u8> {
115        &mut self.0
116    }
117
118    // Variant types below
119
120    fn append_null(&mut self) {
121        self.append_primitive_header(VariantPrimitiveType::Null);
122    }
123
124    fn append_bool(&mut self, value: bool) {
125        let primitive_type = if value {
126            VariantPrimitiveType::BooleanTrue
127        } else {
128            VariantPrimitiveType::BooleanFalse
129        };
130        self.append_primitive_header(primitive_type);
131    }
132
133    fn append_int8(&mut self, value: i8) {
134        self.append_primitive_header(VariantPrimitiveType::Int8);
135        self.append_u8(value as u8);
136    }
137
138    fn append_int16(&mut self, value: i16) {
139        self.append_primitive_header(VariantPrimitiveType::Int16);
140        self.append_slice(&value.to_le_bytes());
141    }
142
143    fn append_int32(&mut self, value: i32) {
144        self.append_primitive_header(VariantPrimitiveType::Int32);
145        self.append_slice(&value.to_le_bytes());
146    }
147
148    fn append_int64(&mut self, value: i64) {
149        self.append_primitive_header(VariantPrimitiveType::Int64);
150        self.append_slice(&value.to_le_bytes());
151    }
152
153    fn append_float(&mut self, value: f32) {
154        self.append_primitive_header(VariantPrimitiveType::Float);
155        self.append_slice(&value.to_le_bytes());
156    }
157
158    fn append_double(&mut self, value: f64) {
159        self.append_primitive_header(VariantPrimitiveType::Double);
160        self.append_slice(&value.to_le_bytes());
161    }
162
163    fn append_date(&mut self, value: chrono::NaiveDate) {
164        self.append_primitive_header(VariantPrimitiveType::Date);
165        let days_since_epoch = value.signed_duration_since(UNIX_EPOCH_DATE).num_days() as i32;
166        self.append_slice(&days_since_epoch.to_le_bytes());
167    }
168
169    fn append_timestamp_micros(&mut self, value: chrono::DateTime<chrono::Utc>) {
170        self.append_primitive_header(VariantPrimitiveType::TimestampMicros);
171        let micros = value.timestamp_micros();
172        self.append_slice(&micros.to_le_bytes());
173    }
174
175    fn append_timestamp_ntz_micros(&mut self, value: chrono::NaiveDateTime) {
176        self.append_primitive_header(VariantPrimitiveType::TimestampNtzMicros);
177        let micros = value.and_utc().timestamp_micros();
178        self.append_slice(&micros.to_le_bytes());
179    }
180
181    fn append_decimal4(&mut self, decimal4: VariantDecimal4) {
182        self.append_primitive_header(VariantPrimitiveType::Decimal4);
183        self.append_u8(decimal4.scale());
184        self.append_slice(&decimal4.integer().to_le_bytes());
185    }
186
187    fn append_decimal8(&mut self, decimal8: VariantDecimal8) {
188        self.append_primitive_header(VariantPrimitiveType::Decimal8);
189        self.append_u8(decimal8.scale());
190        self.append_slice(&decimal8.integer().to_le_bytes());
191    }
192
193    fn append_decimal16(&mut self, decimal16: VariantDecimal16) {
194        self.append_primitive_header(VariantPrimitiveType::Decimal16);
195        self.append_u8(decimal16.scale());
196        self.append_slice(&decimal16.integer().to_le_bytes());
197    }
198
199    fn append_binary(&mut self, value: &[u8]) {
200        self.append_primitive_header(VariantPrimitiveType::Binary);
201        self.append_slice(&(value.len() as u32).to_le_bytes());
202        self.append_slice(value);
203    }
204
205    fn append_short_string(&mut self, value: ShortString) {
206        let inner = value.0;
207        self.append_u8(short_string_header(inner.len()));
208        self.append_slice(inner.as_bytes());
209    }
210
211    fn append_string(&mut self, value: &str) {
212        self.append_primitive_header(VariantPrimitiveType::String);
213        self.append_slice(&(value.len() as u32).to_le_bytes());
214        self.append_slice(value.as_bytes());
215    }
216
217    fn offset(&self) -> usize {
218        self.0.len()
219    }
220
221    fn append_non_nested_value<'m, 'd, T: Into<Variant<'m, 'd>>>(&mut self, value: T) {
222        let variant = value.into();
223        match variant {
224            Variant::Null => self.append_null(),
225            Variant::BooleanTrue => self.append_bool(true),
226            Variant::BooleanFalse => self.append_bool(false),
227            Variant::Int8(v) => self.append_int8(v),
228            Variant::Int16(v) => self.append_int16(v),
229            Variant::Int32(v) => self.append_int32(v),
230            Variant::Int64(v) => self.append_int64(v),
231            Variant::Date(v) => self.append_date(v),
232            Variant::TimestampMicros(v) => self.append_timestamp_micros(v),
233            Variant::TimestampNtzMicros(v) => self.append_timestamp_ntz_micros(v),
234            Variant::Decimal4(decimal4) => self.append_decimal4(decimal4),
235            Variant::Decimal8(decimal8) => self.append_decimal8(decimal8),
236            Variant::Decimal16(decimal16) => self.append_decimal16(decimal16),
237            Variant::Float(v) => self.append_float(v),
238            Variant::Double(v) => self.append_double(v),
239            Variant::Binary(v) => self.append_binary(v),
240            Variant::String(s) => self.append_string(s),
241            Variant::ShortString(s) => self.append_short_string(s),
242            Variant::Object(_) | Variant::List(_) => {
243                unreachable!(
244                    "Nested values are handled specially by ObjectBuilder and ListBuilder"
245                );
246            }
247        }
248    }
249
250    /// Writes out the header byte for a variant object or list
251    fn append_header(&mut self, header_byte: u8, is_large: bool, num_items: usize) {
252        let buf = self.inner_mut();
253        buf.push(header_byte);
254
255        if is_large {
256            let num_items = num_items as u32;
257            buf.extend_from_slice(&num_items.to_le_bytes());
258        } else {
259            let num_items = num_items as u8;
260            buf.push(num_items);
261        };
262    }
263
264    /// Writes out the offsets for an array of offsets, including the final offset (data size).
265    fn append_offset_array(
266        &mut self,
267        offsets: impl IntoIterator<Item = usize>,
268        data_size: Option<usize>,
269        nbytes: u8,
270    ) {
271        let buf = self.inner_mut();
272        for offset in offsets {
273            write_offset(buf, offset, nbytes);
274        }
275        if let Some(data_size) = data_size {
276            write_offset(buf, data_size, nbytes);
277        }
278    }
279}
280
281/// Builder for constructing metadata for [`Variant`] values.
282///
283/// This is used internally by the [`VariantBuilder`] to construct the metadata
284///
285/// You can use an existing `Vec<u8>` as the metadata buffer by using the `from` impl.
286#[derive(Default, Debug)]
287struct MetadataBuilder {
288    // Field names -- field_ids are assigned in insert order
289    field_names: IndexSet<String>,
290
291    // flag that checks if field names by insertion order are also lexicographically sorted
292    is_sorted: bool,
293
294    /// Output buffer. Metadata is written to the end of this buffer
295    metadata_buffer: Vec<u8>,
296}
297
298/// Create a new MetadataBuilder that will write to the specified metadata buffer
299impl From<Vec<u8>> for MetadataBuilder {
300    fn from(metadata_buffer: Vec<u8>) -> Self {
301        Self {
302            metadata_buffer,
303            ..Default::default()
304        }
305    }
306}
307
308impl MetadataBuilder {
309    /// Upsert field name to dictionary, return its ID
310    fn upsert_field_name(&mut self, field_name: &str) -> u32 {
311        let (id, new_entry) = self.field_names.insert_full(field_name.to_string());
312
313        if new_entry {
314            let n = self.num_field_names();
315
316            // Dictionary sort order tracking:
317            // - An empty dictionary is unsorted (ambiguous in spec but required by interop tests)
318            // - A single-entry dictionary is trivially sorted
319            // - Otherwise, an already-sorted dictionary becomes unsorted if the new entry breaks order
320            self.is_sorted =
321                n == 1 || self.is_sorted && (self.field_names[n - 2] < self.field_names[n - 1]);
322        }
323
324        id as u32
325    }
326
327    /// Returns the number of field names stored in the metadata builder.
328    /// Note: this method should be the only place to call `self.field_names.len()`
329    ///
330    /// # Panics
331    ///
332    /// If the number of field names exceeds the maximum allowed value for `u32`.
333    fn num_field_names(&self) -> usize {
334        let n = self.field_names.len();
335        assert!(n <= u32::MAX as usize);
336
337        n
338    }
339
340    fn field_name(&self, i: usize) -> &str {
341        &self.field_names[i]
342    }
343
344    fn metadata_size(&self) -> usize {
345        self.field_names.iter().map(|k| k.len()).sum()
346    }
347
348    fn finish(self) -> Vec<u8> {
349        let nkeys = self.num_field_names();
350
351        // Calculate metadata size
352        let total_dict_size: usize = self.metadata_size();
353
354        let Self {
355            field_names,
356            is_sorted,
357            mut metadata_buffer,
358        } = self;
359
360        // Determine appropriate offset size based on the larger of dict size or total string size
361        let max_offset = std::cmp::max(total_dict_size, nkeys);
362        let offset_size = int_size(max_offset);
363
364        let offset_start = 1 + offset_size as usize;
365        let string_start = offset_start + (nkeys + 1) * offset_size as usize;
366        let metadata_size = string_start + total_dict_size;
367
368        metadata_buffer.reserve(metadata_size);
369
370        // Write header: version=1, field names are sorted, with calculated offset_size
371        metadata_buffer.push(0x01 | (is_sorted as u8) << 4 | ((offset_size - 1) << 6));
372
373        // Write dictionary size
374        write_offset(&mut metadata_buffer, nkeys, offset_size);
375
376        // Write offsets
377        let mut cur_offset = 0;
378        for key in field_names.iter() {
379            write_offset(&mut metadata_buffer, cur_offset, offset_size);
380            cur_offset += key.len();
381        }
382        // Write final offset
383        write_offset(&mut metadata_buffer, cur_offset, offset_size);
384
385        // Write string data
386        for key in field_names {
387            metadata_buffer.extend_from_slice(key.as_bytes());
388        }
389
390        metadata_buffer
391    }
392}
393
394impl<S: AsRef<str>> FromIterator<S> for MetadataBuilder {
395    fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
396        let mut this = Self::default();
397        this.extend(iter);
398
399        this
400    }
401}
402
403impl<S: AsRef<str>> Extend<S> for MetadataBuilder {
404    fn extend<T: IntoIterator<Item = S>>(&mut self, iter: T) {
405        for field_name in iter {
406            self.upsert_field_name(field_name.as_ref());
407        }
408    }
409}
410
411/// Tracks information needed to correctly finalize a nested builder, for each parent builder type.
412///
413/// A child builder has no effect on its parent unless/until its `finalize` method is called, at
414/// which point the child appends the new value to the parent. As a (desirable) side effect,
415/// creating a parent state instance captures mutable references to a subset of the parent's fields,
416/// rendering the parent object completely unusable until the parent state goes out of scope. This
417/// ensures that at most one child builder can exist at a time.
418///
419/// The redundancy in buffer and metadata_builder is because all the references come from the
420/// parent, and we cannot "split" a mutable reference across two objects (parent state and the child
421/// builder that uses it). So everything has to be here. Rust layout optimizations should treat the
422/// variants as a union, so that accessing a `buffer` or `metadata_builder` is branch-free.
423enum ParentState<'a> {
424    Variant {
425        buffer: &'a mut ValueBuffer,
426        metadata_builder: &'a mut MetadataBuilder,
427    },
428    List {
429        buffer: &'a mut ValueBuffer,
430        metadata_builder: &'a mut MetadataBuilder,
431        offsets: &'a mut Vec<usize>,
432    },
433    Object {
434        buffer: &'a mut ValueBuffer,
435        metadata_builder: &'a mut MetadataBuilder,
436        fields: &'a mut IndexMap<u32, usize>,
437        field_name: &'a str,
438    },
439}
440
441impl ParentState<'_> {
442    fn buffer(&mut self) -> &mut ValueBuffer {
443        match self {
444            ParentState::Variant { buffer, .. } => buffer,
445            ParentState::List { buffer, .. } => buffer,
446            ParentState::Object { buffer, .. } => buffer,
447        }
448    }
449
450    fn metadata_builder(&mut self) -> &mut MetadataBuilder {
451        match self {
452            ParentState::Variant {
453                metadata_builder, ..
454            } => metadata_builder,
455            ParentState::List {
456                metadata_builder, ..
457            } => metadata_builder,
458            ParentState::Object {
459                metadata_builder, ..
460            } => metadata_builder,
461        }
462    }
463
464    // Performs any parent-specific aspects of finishing, after the child has appended all necessary
465    // bytes to the parent's value buffer. ListBuilder records the new value's starting offset;
466    // ObjectBuilder associates the new value's starting offset with its field id; VariantBuilder
467    // doesn't need anything special.
468    fn finish(&mut self, starting_offset: usize) {
469        match self {
470            ParentState::Variant { .. } => (),
471            ParentState::List { offsets, .. } => offsets.push(starting_offset),
472            ParentState::Object {
473                metadata_builder,
474                fields,
475                field_name,
476                ..
477            } => {
478                let field_id = metadata_builder.upsert_field_name(field_name);
479                fields.insert(field_id, starting_offset);
480            }
481        }
482    }
483}
484
485/// Top level builder for [`Variant`] values
486///
487/// # Example: create a Primitive Int8
488/// ```
489/// # use parquet_variant::{Variant, VariantBuilder};
490/// let mut builder = VariantBuilder::new();
491/// builder.append_value(Variant::Int8(42));
492/// // Finish the builder to get the metadata and value
493/// let (metadata, value) = builder.finish();
494/// // use the Variant API to verify the result
495/// let variant = Variant::try_new(&metadata, &value).unwrap();
496/// assert_eq!(variant, Variant::Int8(42));
497/// ```
498///
499/// # Example: Create a [`Variant::Object`]
500///
501/// This example shows how to create an object with two fields:
502/// ```json
503/// {
504///  "first_name": "Jiaying",
505///  "last_name": "Li"
506/// }
507/// ```
508///
509/// ```
510/// # use parquet_variant::{Variant, VariantBuilder};
511/// let mut builder = VariantBuilder::new();
512/// // Create an object builder that will write fields to the object
513/// let mut object_builder = builder.new_object();
514/// object_builder.insert("first_name", "Jiaying");
515/// object_builder.insert("last_name", "Li");
516/// object_builder.finish();
517/// // Finish the builder to get the metadata and value
518/// let (metadata, value) = builder.finish();
519/// // use the Variant API to verify the result
520/// let variant = Variant::try_new(&metadata, &value).unwrap();
521/// let variant_object = variant.as_object().unwrap();
522/// assert_eq!(
523///   variant_object.get("first_name"),
524///   Some(Variant::from("Jiaying"))
525/// );
526/// assert_eq!(
527///   variant_object.get("last_name"),
528///   Some(Variant::from("Li"))
529/// );
530/// ```
531///
532/// # Example: Create a [`Variant::List`] (an Array)
533///
534/// This example shows how to create an array of integers: `[1, 2, 3]`.
535/// ```
536///  # use parquet_variant::{Variant, VariantBuilder};
537///  let mut builder = VariantBuilder::new();
538///  // Create a builder that will write elements to the list
539///  let mut list_builder = builder.new_list();
540///  list_builder.append_value(1i8);
541///  list_builder.append_value(2i8);
542///  list_builder.append_value(3i8);
543///  list_builder.finish();
544/// // Finish the builder to get the metadata and value
545/// let (metadata, value) = builder.finish();
546/// // use the Variant API to verify the result
547/// let variant = Variant::try_new(&metadata, &value).unwrap();
548/// let variant_list = variant.as_list().unwrap();
549/// // Verify the list contents
550/// assert_eq!(variant_list.get(0).unwrap(), Variant::Int8(1));
551/// assert_eq!(variant_list.get(1).unwrap(), Variant::Int8(2));
552/// assert_eq!(variant_list.get(2).unwrap(), Variant::Int8(3));
553/// ```
554///
555/// # Example: [`Variant::List`] of  [`Variant::Object`]s
556///
557/// This example shows how to create an list of objects:
558/// ```json
559/// [
560///   {
561///      "id": 1,
562///      "type": "Cauliflower"
563///   },
564///   {
565///      "id": 2,
566///      "type": "Beets"
567///   }
568/// ]
569/// ```
570/// ```
571/// use parquet_variant::{Variant, VariantBuilder};
572/// let mut builder = VariantBuilder::new();
573///
574/// // Create a builder that will write elements to the list
575/// let mut list_builder = builder.new_list();
576///
577/// {
578///     let mut object_builder = list_builder.new_object();
579///     object_builder.insert("id", 1);
580///     object_builder.insert("type", "Cauliflower");
581///     object_builder.finish();
582/// }
583///
584/// {
585///     let mut object_builder = list_builder.new_object();
586///     object_builder.insert("id", 2);
587///     object_builder.insert("type", "Beets");
588///     object_builder.finish();
589/// }
590///
591/// list_builder.finish();
592/// // Finish the builder to get the metadata and value
593/// let (metadata, value) = builder.finish();
594/// // use the Variant API to verify the result
595/// let variant = Variant::try_new(&metadata, &value).unwrap();
596/// let variant_list = variant.as_list().unwrap();
597///
598///
599/// let obj1_variant = variant_list.get(0).unwrap();
600/// let obj1 = obj1_variant.as_object().unwrap();
601/// assert_eq!(
602///     obj1.get("id"),
603///     Some(Variant::from(1))
604/// );
605/// assert_eq!(
606///     obj1.get("type"),
607///     Some(Variant::from("Cauliflower"))
608/// );
609///
610/// let obj2_variant = variant_list.get(1).unwrap();
611/// let obj2 = obj2_variant.as_object().unwrap();
612///
613/// assert_eq!(
614///     obj2.get("id"),
615///     Some(Variant::from(2))
616/// );
617/// assert_eq!(
618///     obj2.get("type"),
619///     Some(Variant::from("Beets"))
620/// );
621///
622/// ```
623/// # Example: Reusing Buffers
624///
625/// You can use the [`VariantBuilder`] to write into existing buffers (for
626/// example to write multiple variants back to back in the same buffer)
627///
628/// ```
629/// // we will write two variants back to back
630/// use parquet_variant::{Variant, VariantBuilder};
631/// // Append 12345
632/// let mut builder = VariantBuilder::new();
633/// builder.append_value(12345);
634/// let (metadata, value) = builder.finish();
635/// // remember where the first variant ends
636/// let (first_meta_offset, first_meta_len) = (0, metadata.len());
637/// let (first_value_offset, first_value_len) = (0, value.len());
638///
639/// // now, append a second variant to the same buffers
640/// let mut builder = VariantBuilder::new_with_buffers(metadata, value);
641/// builder.append_value("Foo");
642/// let (metadata, value) = builder.finish();
643///
644/// // The variants can be referenced in their appropriate location
645/// let variant1 = Variant::new(
646///   &metadata[first_meta_offset..first_meta_len],
647///   &value[first_value_offset..first_value_len]
648///  );
649/// assert_eq!(variant1, Variant::Int32(12345));
650///
651/// let variant2 = Variant::new(
652///   &metadata[first_meta_len..],
653///   &value[first_value_len..]
654///  );
655/// assert_eq!(variant2, Variant::from("Foo"));
656/// ```
657///
658/// # Example: Unique Field Validation
659///
660/// This example shows how enabling unique field validation will cause an error
661/// if the same field is inserted more than once.
662/// ```
663/// use parquet_variant::VariantBuilder;
664///
665/// let mut builder = VariantBuilder::new().with_validate_unique_fields(true);
666/// let mut obj = builder.new_object();
667///
668/// obj.insert("a", 1);
669/// obj.insert("a", 2); // duplicate field
670///
671/// // When validation is enabled, finish will return an error
672/// let result = obj.finish(); // returns Err
673/// assert!(result.is_err());
674/// ```
675///
676/// # Example: Sorted dictionaries
677///
678/// This example shows how to create a [`VariantBuilder`] with a pre-sorted field dictionary
679/// to improve field access performance when reading [`Variant`] objects.
680///
681/// You can use [`VariantBuilder::with_field_names`] to add multiple field names at once:
682/// ```
683/// use parquet_variant::{Variant, VariantBuilder};
684/// let mut builder = VariantBuilder::new()
685///     .with_field_names(["age", "name", "score"].into_iter());
686///
687/// let mut obj = builder.new_object();
688/// obj.insert("name", "Alice");
689/// obj.insert("age", 30);
690/// obj.insert("score", 95.5);
691/// obj.finish().unwrap();
692///
693/// let (metadata, value) = builder.finish();
694/// let variant = Variant::try_new(&metadata, &value).unwrap();
695/// ```
696///
697/// Alternatively, you can use [`VariantBuilder::add_field_name`] to add field names one by one:
698/// ```
699/// use parquet_variant::{Variant, VariantBuilder};
700/// let mut builder = VariantBuilder::new();
701/// builder.add_field_name("age"); // field id = 0
702/// builder.add_field_name("name"); // field id = 1
703/// builder.add_field_name("score"); // field id = 2
704///
705/// let mut obj = builder.new_object();
706/// obj.insert("name", "Bob"); // field id = 3
707/// obj.insert("age", 25);
708/// obj.insert("score", 88.0);
709/// obj.finish().unwrap();
710///
711/// let (metadata, value) = builder.finish();
712/// let variant = Variant::try_new(&metadata, &value).unwrap();
713/// ```
714#[derive(Default, Debug)]
715pub struct VariantBuilder {
716    buffer: ValueBuffer,
717    metadata_builder: MetadataBuilder,
718    validate_unique_fields: bool,
719}
720
721impl VariantBuilder {
722    /// Create a new VariantBuilder with new underlying buffer
723    pub fn new() -> Self {
724        Self {
725            buffer: ValueBuffer::new(),
726            metadata_builder: MetadataBuilder::default(),
727            validate_unique_fields: false,
728        }
729    }
730
731    /// Create a new VariantBuilder that will write the metadata and values to
732    /// the specified buffers.
733    pub fn new_with_buffers(metadata_buffer: Vec<u8>, value_buffer: Vec<u8>) -> Self {
734        Self {
735            buffer: ValueBuffer::from(value_buffer),
736            metadata_builder: MetadataBuilder::from(metadata_buffer),
737            validate_unique_fields: false,
738        }
739    }
740
741    /// Enables validation of unique field keys in nested objects.
742    ///
743    /// This setting is propagated to all [`ObjectBuilder`]s created through this [`VariantBuilder`]
744    /// (including via any [`ListBuilder`]), and causes [`ObjectBuilder::finish()`] to return
745    /// an error if duplicate keys were inserted.
746    pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self {
747        self.validate_unique_fields = validate_unique_fields;
748        self
749    }
750
751    /// This method pre-populates the field name directory in the Variant metadata with
752    /// the specific field names, in order.
753    ///
754    /// You can use this to pre-populate a [`VariantBuilder`] with a sorted dictionary if you
755    /// know the field names beforehand. Sorted dictionaries can accelerate field access when
756    /// reading [`Variant`]s.
757    pub fn with_field_names<'a>(mut self, field_names: impl Iterator<Item = &'a str>) -> Self {
758        self.metadata_builder.extend(field_names);
759
760        self
761    }
762
763    /// Adds a single field name to the field name directory in the Variant metadata.
764    ///
765    /// This method does the same thing as [`VariantBuilder::with_field_names`] but adds one field name at a time.
766    pub fn add_field_name(&mut self, field_name: &str) {
767        self.metadata_builder.upsert_field_name(field_name);
768    }
769
770    // Returns validate_unique_fields because we can no longer reference self once this method returns.
771    fn parent_state(&mut self) -> (ParentState, bool) {
772        let state = ParentState::Variant {
773            buffer: &mut self.buffer,
774            metadata_builder: &mut self.metadata_builder,
775        };
776        (state, self.validate_unique_fields)
777    }
778
779    /// Create an [`ListBuilder`] for creating [`Variant::List`] values.
780    ///
781    /// See the examples on [`VariantBuilder`] for usage.
782    pub fn new_list(&mut self) -> ListBuilder {
783        let (parent_state, validate_unique_fields) = self.parent_state();
784        ListBuilder::new(parent_state, validate_unique_fields)
785    }
786
787    /// Create an [`ObjectBuilder`] for creating [`Variant::Object`] values.
788    ///
789    /// See the examples on [`VariantBuilder`] for usage.
790    pub fn new_object(&mut self) -> ObjectBuilder {
791        let (parent_state, validate_unique_fields) = self.parent_state();
792        ObjectBuilder::new(parent_state, validate_unique_fields)
793    }
794
795    /// Append a non-nested value to the builder.
796    ///
797    /// # Example
798    /// ```
799    /// # use parquet_variant::{Variant, VariantBuilder};
800    /// let mut builder = VariantBuilder::new();
801    /// // most primitive types can be appended directly as they implement `Into<Variant>`
802    /// builder.append_value(42i8);
803    /// ```
804    pub fn append_value<'m, 'd, T: Into<Variant<'m, 'd>>>(&mut self, value: T) {
805        self.buffer.append_non_nested_value(value);
806    }
807
808    /// Finish the builder and return the metadata and value buffers.
809    pub fn finish(self) -> (Vec<u8>, Vec<u8>) {
810        (self.metadata_builder.finish(), self.buffer.into_inner())
811    }
812}
813
814/// A builder for creating [`Variant::List`] values.
815///
816/// See the examples on [`VariantBuilder`] for usage.
817pub struct ListBuilder<'a> {
818    parent_state: ParentState<'a>,
819    offsets: Vec<usize>,
820    buffer: ValueBuffer,
821    validate_unique_fields: bool,
822}
823
824impl<'a> ListBuilder<'a> {
825    fn new(parent_state: ParentState<'a>, validate_unique_fields: bool) -> Self {
826        Self {
827            parent_state,
828            offsets: vec![],
829            buffer: ValueBuffer::default(),
830            validate_unique_fields,
831        }
832    }
833
834    /// Enables unique field key validation for objects created within this list.
835    ///
836    /// Propagates the validation flag to any [`ObjectBuilder`]s created using
837    /// [`ListBuilder::new_object`].
838    pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self {
839        self.validate_unique_fields = validate_unique_fields;
840        self
841    }
842
843    // Returns validate_unique_fields because we can no longer reference self once this method returns.
844    fn parent_state(&mut self) -> (ParentState, bool) {
845        let state = ParentState::List {
846            buffer: &mut self.buffer,
847            metadata_builder: self.parent_state.metadata_builder(),
848            offsets: &mut self.offsets,
849        };
850        (state, self.validate_unique_fields)
851    }
852
853    /// Returns an object builder that can be used to append a new (nested) object to this list.
854    ///
855    /// WARNING: The builder will have no effect unless/until [`ObjectBuilder::finish`] is called.
856    pub fn new_object(&mut self) -> ObjectBuilder {
857        let (parent_state, validate_unique_fields) = self.parent_state();
858        ObjectBuilder::new(parent_state, validate_unique_fields)
859    }
860
861    /// Returns a list builder that can be used to append a new (nested) list to this list.
862    ///
863    /// WARNING: The builder will have no effect unless/until [`ListBuilder::finish`] is called.
864    pub fn new_list(&mut self) -> ListBuilder {
865        let (parent_state, validate_unique_fields) = self.parent_state();
866        ListBuilder::new(parent_state, validate_unique_fields)
867    }
868
869    /// Appends a new primitive value to this list
870    pub fn append_value<'m, 'd, T: Into<Variant<'m, 'd>>>(&mut self, value: T) {
871        self.offsets.push(self.buffer.offset());
872        self.buffer.append_non_nested_value(value);
873    }
874
875    /// Finalizes this list and appends it to its parent, which otherwise remains unmodified.
876    pub fn finish(mut self) {
877        let data_size = self.buffer.offset();
878        let num_elements = self.offsets.len();
879        let is_large = num_elements > u8::MAX as usize;
880        let offset_size = int_size(data_size);
881
882        // Get parent's buffer
883        let parent_buffer = self.parent_state.buffer();
884        let starting_offset = parent_buffer.offset();
885
886        // Write header
887        let header = array_header(is_large, offset_size);
888        parent_buffer.append_header(header, is_large, num_elements);
889
890        // Write out the offset array followed by the value bytes
891        let offsets = std::mem::take(&mut self.offsets);
892        parent_buffer.append_offset_array(offsets, Some(data_size), offset_size);
893        parent_buffer.append_slice(self.buffer.inner());
894        self.parent_state.finish(starting_offset);
895    }
896}
897
898/// Drop implementation for ListBuilder does nothing
899/// as the `finish` method must be called to finalize the list.
900/// This is to ensure that the list is always finalized before its parent builder
901/// is finalized.
902impl Drop for ListBuilder<'_> {
903    fn drop(&mut self) {}
904}
905
906/// A builder for creating [`Variant::Object`] values.
907///
908/// See the examples on [`VariantBuilder`] for usage.
909pub struct ObjectBuilder<'a> {
910    parent_state: ParentState<'a>,
911    fields: IndexMap<u32, usize>, // (field_id, offset)
912    buffer: ValueBuffer,
913    validate_unique_fields: bool,
914    /// Set of duplicate fields to report for errors
915    duplicate_fields: HashSet<u32>,
916}
917
918impl<'a> ObjectBuilder<'a> {
919    fn new(parent_state: ParentState<'a>, validate_unique_fields: bool) -> Self {
920        Self {
921            parent_state,
922            fields: IndexMap::new(),
923            buffer: ValueBuffer::default(),
924            validate_unique_fields,
925            duplicate_fields: HashSet::new(),
926        }
927    }
928
929    /// Add a field with key and value to the object
930    ///
931    /// Note: when inserting duplicate keys, the new value overwrites the previous mapping,
932    /// but the old value remains in the buffer, resulting in a larger variant
933    pub fn insert<'m, 'd, T: Into<Variant<'m, 'd>>>(&mut self, key: &str, value: T) {
934        // Get metadata_builder from parent state
935        let metadata_builder = self.parent_state.metadata_builder();
936
937        let field_id = metadata_builder.upsert_field_name(key);
938        let field_start = self.buffer.offset();
939
940        if self.fields.insert(field_id, field_start).is_some() && self.validate_unique_fields {
941            self.duplicate_fields.insert(field_id);
942        }
943
944        self.buffer.append_non_nested_value(value);
945    }
946
947    /// Enables validation for unique field keys when inserting into this object.
948    ///
949    /// When this is enabled, calling [`ObjectBuilder::finish`] will return an error
950    /// if any duplicate field keys were added using [`ObjectBuilder::insert`].
951    pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self {
952        self.validate_unique_fields = validate_unique_fields;
953        self
954    }
955
956    // Returns validate_unique_fields because we can no longer reference self once this method returns.
957    fn parent_state<'b>(&'b mut self, key: &'b str) -> (ParentState<'b>, bool) {
958        let state = ParentState::Object {
959            buffer: &mut self.buffer,
960            metadata_builder: self.parent_state.metadata_builder(),
961            fields: &mut self.fields,
962            field_name: key,
963        };
964        (state, self.validate_unique_fields)
965    }
966
967    /// Returns an object builder that can be used to append a new (nested) object to this object.
968    ///
969    /// WARNING: The builder will have no effect unless/until [`ObjectBuilder::finish`] is called.
970    pub fn new_object<'b>(&'b mut self, key: &'b str) -> ObjectBuilder<'b> {
971        let (parent_state, validate_unique_fields) = self.parent_state(key);
972        ObjectBuilder::new(parent_state, validate_unique_fields)
973    }
974
975    /// Returns a list builder that can be used to append a new (nested) list to this object.
976    ///
977    /// WARNING: The builder will have no effect unless/until [`ListBuilder::finish`] is called.
978    pub fn new_list<'b>(&'b mut self, key: &'b str) -> ListBuilder<'b> {
979        let (parent_state, validate_unique_fields) = self.parent_state(key);
980        ListBuilder::new(parent_state, validate_unique_fields)
981    }
982
983    /// Finalizes this object and appends it to its parent, which otherwise remains unmodified.
984    pub fn finish(mut self) -> Result<(), ArrowError> {
985        let metadata_builder = self.parent_state.metadata_builder();
986        if self.validate_unique_fields && !self.duplicate_fields.is_empty() {
987            let mut names = self
988                .duplicate_fields
989                .iter()
990                .map(|id| metadata_builder.field_name(*id as usize))
991                .collect::<Vec<_>>();
992
993            names.sort_unstable();
994
995            let joined = names.join(", ");
996            return Err(ArrowError::InvalidArgumentError(format!(
997                "Duplicate field keys detected: [{joined}]",
998            )));
999        }
1000
1001        let data_size = self.buffer.offset();
1002        let num_fields = self.fields.len();
1003        let is_large = num_fields > u8::MAX as usize;
1004
1005        self.fields.sort_by(|&field_a_id, _, &field_b_id, _| {
1006            let key_a = &metadata_builder.field_name(field_a_id as usize);
1007            let key_b = &metadata_builder.field_name(field_b_id as usize);
1008            key_a.cmp(key_b)
1009        });
1010
1011        let max_id = self.fields.iter().map(|(i, _)| *i).max().unwrap_or(0);
1012
1013        let id_size = int_size(max_id as usize);
1014        let offset_size = int_size(data_size);
1015
1016        // Get parent's buffer
1017        let parent_buffer = self.parent_state.buffer();
1018        let starting_offset = parent_buffer.offset();
1019
1020        // Write header
1021        let header = object_header(is_large, id_size, offset_size);
1022        parent_buffer.append_header(header, is_large, num_fields);
1023
1024        // Write field IDs (sorted order)
1025        let ids = self.fields.keys().map(|id| *id as usize);
1026        parent_buffer.append_offset_array(ids, None, id_size);
1027
1028        // Write the field offset array, followed by the value bytes
1029        let offsets = std::mem::take(&mut self.fields).into_values();
1030        parent_buffer.append_offset_array(offsets, Some(data_size), offset_size);
1031        parent_buffer.append_slice(self.buffer.inner());
1032        self.parent_state.finish(starting_offset);
1033
1034        Ok(())
1035    }
1036}
1037
1038/// Drop implementation for ObjectBuilder does nothing
1039/// as the `finish` method must be called to finalize the object.
1040/// This is to ensure that the object is always finalized before its parent builder
1041/// is finalized.
1042impl Drop for ObjectBuilder<'_> {
1043    fn drop(&mut self) {}
1044}
1045
1046/// Extends [`VariantBuilder`] to help building nested [`Variant`]s
1047///
1048/// Allows users to append values to a [`VariantBuilder`], [`ListBuilder`] or
1049/// [`ObjectBuilder`]. using the same interface.
1050pub trait VariantBuilderExt<'m, 'v> {
1051    fn append_value(&mut self, value: impl Into<Variant<'m, 'v>>);
1052
1053    fn new_list(&mut self) -> ListBuilder;
1054
1055    fn new_object(&mut self) -> ObjectBuilder;
1056}
1057
1058impl<'m, 'v> VariantBuilderExt<'m, 'v> for ListBuilder<'_> {
1059    fn append_value(&mut self, value: impl Into<Variant<'m, 'v>>) {
1060        self.append_value(value);
1061    }
1062
1063    fn new_list(&mut self) -> ListBuilder {
1064        self.new_list()
1065    }
1066
1067    fn new_object(&mut self) -> ObjectBuilder {
1068        self.new_object()
1069    }
1070}
1071
1072impl<'m, 'v> VariantBuilderExt<'m, 'v> for VariantBuilder {
1073    fn append_value(&mut self, value: impl Into<Variant<'m, 'v>>) {
1074        self.append_value(value);
1075    }
1076
1077    fn new_list(&mut self) -> ListBuilder {
1078        self.new_list()
1079    }
1080
1081    fn new_object(&mut self) -> ObjectBuilder {
1082        self.new_object()
1083    }
1084}
1085
1086#[cfg(test)]
1087mod tests {
1088    use crate::VariantMetadata;
1089
1090    use super::*;
1091
1092    #[test]
1093    fn test_simple_usage() {
1094        {
1095            let mut builder = VariantBuilder::new();
1096            builder.append_value(());
1097            let (metadata, value) = builder.finish();
1098            let variant = Variant::try_new(&metadata, &value).unwrap();
1099            assert_eq!(variant, Variant::Null);
1100        }
1101
1102        {
1103            let mut builder = VariantBuilder::new();
1104            builder.append_value(true);
1105            let (metadata, value) = builder.finish();
1106            let variant = Variant::try_new(&metadata, &value).unwrap();
1107            assert_eq!(variant, Variant::BooleanTrue);
1108        }
1109
1110        {
1111            let mut builder = VariantBuilder::new();
1112            builder.append_value(false);
1113            let (metadata, value) = builder.finish();
1114            let variant = Variant::try_new(&metadata, &value).unwrap();
1115            assert_eq!(variant, Variant::BooleanFalse);
1116        }
1117
1118        {
1119            let mut builder = VariantBuilder::new();
1120            builder.append_value(42i8);
1121            let (metadata, value) = builder.finish();
1122            let variant = Variant::try_new(&metadata, &value).unwrap();
1123            assert_eq!(variant, Variant::Int8(42));
1124        }
1125
1126        {
1127            let mut builder = VariantBuilder::new();
1128            builder.append_value(1234i16);
1129            let (metadata, value) = builder.finish();
1130            let variant = Variant::try_new(&metadata, &value).unwrap();
1131            assert_eq!(variant, Variant::Int16(1234));
1132        }
1133
1134        {
1135            let mut builder = VariantBuilder::new();
1136            builder.append_value(123456i32);
1137            let (metadata, value) = builder.finish();
1138            let variant = Variant::try_new(&metadata, &value).unwrap();
1139            assert_eq!(variant, Variant::Int32(123456));
1140        }
1141
1142        {
1143            let mut builder = VariantBuilder::new();
1144            builder.append_value(123456789i64);
1145            let (metadata, value) = builder.finish();
1146            let variant = Variant::try_new(&metadata, &value).unwrap();
1147            assert_eq!(variant, Variant::Int64(123456789));
1148        }
1149
1150        {
1151            let mut builder = VariantBuilder::new();
1152            builder.append_value(1.5f32);
1153            let (metadata, value) = builder.finish();
1154            let variant = Variant::try_new(&metadata, &value).unwrap();
1155            assert_eq!(variant, Variant::Float(1.5));
1156        }
1157
1158        {
1159            let mut builder = VariantBuilder::new();
1160            builder.append_value(2.5f64);
1161            let (metadata, value) = builder.finish();
1162            let variant = Variant::try_new(&metadata, &value).unwrap();
1163            assert_eq!(variant, Variant::Double(2.5));
1164        }
1165
1166        {
1167            let mut builder = VariantBuilder::new();
1168            builder.append_value("hello");
1169            let (metadata, value) = builder.finish();
1170            let variant = Variant::try_new(&metadata, &value).unwrap();
1171            assert_eq!(variant, Variant::ShortString(ShortString("hello")));
1172        }
1173
1174        {
1175            let mut builder = VariantBuilder::new();
1176            let long_string = "This is a very long string that exceeds the short string limit of 63 bytes and should be encoded as a regular string type instead of a short string";
1177            builder.append_value(long_string);
1178            let (metadata, value) = builder.finish();
1179            let variant = Variant::try_new(&metadata, &value).unwrap();
1180            assert_eq!(variant, Variant::String(long_string));
1181        }
1182
1183        {
1184            let mut builder = VariantBuilder::new();
1185            let binary_data = b"binary data";
1186            builder.append_value(binary_data.as_slice());
1187            let (metadata, value) = builder.finish();
1188            let variant = Variant::try_new(&metadata, &value).unwrap();
1189            assert_eq!(variant, Variant::Binary(binary_data.as_slice()));
1190        }
1191    }
1192
1193    #[test]
1194    fn test_list() {
1195        let mut builder = VariantBuilder::new();
1196
1197        {
1198            let mut list = builder.new_list();
1199            list.append_value(1i8);
1200            list.append_value(2i8);
1201            list.append_value("test");
1202            list.finish();
1203        }
1204
1205        let (metadata, value) = builder.finish();
1206        assert!(!metadata.is_empty());
1207        assert!(!value.is_empty());
1208
1209        let variant = Variant::try_new(&metadata, &value).unwrap();
1210
1211        match variant {
1212            Variant::List(list) => {
1213                let val0 = list.get(0).unwrap();
1214                assert_eq!(val0, Variant::Int8(1));
1215
1216                let val1 = list.get(1).unwrap();
1217                assert_eq!(val1, Variant::Int8(2));
1218
1219                let val2 = list.get(2).unwrap();
1220                assert_eq!(val2, Variant::ShortString(ShortString("test")));
1221            }
1222            _ => panic!("Expected an array variant, got: {variant:?}"),
1223        }
1224    }
1225
1226    #[test]
1227    fn test_object() {
1228        let mut builder = VariantBuilder::new();
1229
1230        {
1231            let mut obj = builder.new_object();
1232            obj.insert("name", "John");
1233            obj.insert("age", 42i8);
1234            let _ = obj.finish();
1235        }
1236
1237        let (metadata, value) = builder.finish();
1238        assert!(!metadata.is_empty());
1239        assert!(!value.is_empty());
1240    }
1241
1242    #[test]
1243    fn test_object_field_ordering() {
1244        let mut builder = VariantBuilder::new();
1245
1246        {
1247            let mut obj = builder.new_object();
1248            obj.insert("zebra", "stripes"); // ID = 0
1249            obj.insert("apple", "red"); // ID = 1
1250            obj.insert("banana", "yellow"); // ID = 2
1251            let _ = obj.finish();
1252        }
1253
1254        let (_, value) = builder.finish();
1255
1256        let header = value[0];
1257        assert_eq!(header & 0x03, VariantBasicType::Object as u8);
1258
1259        let field_count = value[1] as usize;
1260        assert_eq!(field_count, 3);
1261
1262        // Get field IDs from the object header
1263        let field_ids: Vec<u8> = value[2..5].to_vec();
1264
1265        // apple(1), banana(2), zebra(0)
1266        assert_eq!(field_ids, vec![1, 2, 0]);
1267    }
1268
1269    #[test]
1270    fn test_duplicate_fields_in_object() {
1271        let mut builder = VariantBuilder::new();
1272        let mut object_builder = builder.new_object();
1273        object_builder.insert("name", "Ron Artest");
1274        object_builder.insert("name", "Metta World Peace");
1275        let _ = object_builder.finish();
1276
1277        let (metadata, value) = builder.finish();
1278        let variant = Variant::try_new(&metadata, &value).unwrap();
1279
1280        let obj = variant.as_object().unwrap();
1281        assert_eq!(obj.len(), 1);
1282        assert_eq!(obj.field(0).unwrap(), Variant::from("Metta World Peace"));
1283
1284        assert_eq!(
1285            vec![("name", Variant::from("Metta World Peace"))],
1286            obj.iter().collect::<Vec<_>>()
1287        );
1288    }
1289
1290    #[test]
1291    fn test_nested_list() {
1292        let mut builder = VariantBuilder::new();
1293
1294        let mut outer_list_builder = builder.new_list();
1295
1296        {
1297            let mut inner_list_builder = outer_list_builder.new_list();
1298
1299            inner_list_builder.append_value("a");
1300            inner_list_builder.append_value("b");
1301            inner_list_builder.append_value("c");
1302            inner_list_builder.append_value("d");
1303
1304            inner_list_builder.finish();
1305        }
1306
1307        outer_list_builder.finish();
1308
1309        let (metadata, value) = builder.finish();
1310
1311        let variant = Variant::try_new(&metadata, &value).unwrap();
1312        let outer_list = variant.as_list().unwrap();
1313
1314        assert_eq!(outer_list.len(), 1);
1315
1316        let inner_variant = outer_list.get(0).unwrap();
1317        let inner_list = inner_variant.as_list().unwrap();
1318
1319        assert_eq!(
1320            vec![
1321                Variant::from("a"),
1322                Variant::from("b"),
1323                Variant::from("c"),
1324                Variant::from("d"),
1325            ],
1326            inner_list.iter().collect::<Vec<_>>()
1327        );
1328    }
1329
1330    #[test]
1331    fn test_super_nested_list() {
1332        /*
1333        [[[[[1]]]]]
1334        */
1335
1336        let mut builder = VariantBuilder::new();
1337        {
1338            let mut list_builder1 = builder.new_list();
1339            {
1340                let mut list_builder2 = list_builder1.new_list();
1341                {
1342                    let mut list_builder3 = list_builder2.new_list();
1343                    {
1344                        let mut list_builder4 = list_builder3.new_list();
1345                        {
1346                            let mut list_builder5 = list_builder4.new_list();
1347                            list_builder5.append_value(1);
1348                            list_builder5.finish();
1349                        }
1350                        list_builder4.finish();
1351                    }
1352                    list_builder3.finish();
1353                }
1354                list_builder2.finish();
1355            }
1356            list_builder1.finish();
1357        }
1358
1359        let (metadata, value) = builder.finish();
1360
1361        let variant = Variant::try_new(&metadata, &value).unwrap();
1362        let list1 = variant.as_list().unwrap();
1363        assert_eq!(list1.len(), 1);
1364
1365        let list2_variant = list1.get(0).unwrap();
1366        let list2 = list2_variant.as_list().unwrap();
1367        assert_eq!(list2.len(), 1);
1368
1369        let list3_variant = list2.get(0).unwrap();
1370        let list3 = list3_variant.as_list().unwrap();
1371        assert_eq!(list3.len(), 1);
1372
1373        let list4_variant = list3.get(0).unwrap();
1374        let list4 = list4_variant.as_list().unwrap();
1375        assert_eq!(list4.len(), 1);
1376
1377        let list5_variant = list4.get(0).unwrap();
1378        let list5 = list5_variant.as_list().unwrap();
1379        assert_eq!(list5.len(), 1);
1380
1381        assert_eq!(list5.len(), 1);
1382
1383        assert_eq!(list5.get(0).unwrap(), Variant::from(1));
1384    }
1385
1386    #[test]
1387    fn test_object_list() {
1388        let mut builder = VariantBuilder::new();
1389
1390        let mut list_builder = builder.new_list();
1391
1392        {
1393            let mut object_builder = list_builder.new_object();
1394            object_builder.insert("id", 1);
1395            object_builder.insert("type", "Cauliflower");
1396            let _ = object_builder.finish();
1397        }
1398
1399        {
1400            let mut object_builder = list_builder.new_object();
1401            object_builder.insert("id", 2);
1402            object_builder.insert("type", "Beets");
1403            let _ = object_builder.finish();
1404        }
1405
1406        list_builder.finish();
1407
1408        let (metadata, value) = builder.finish();
1409
1410        let variant = Variant::try_new(&metadata, &value).unwrap();
1411        let list = variant.as_list().unwrap();
1412
1413        assert_eq!(list.len(), 2);
1414
1415        let obj1_variant = list.get(0).unwrap();
1416        let obj1 = obj1_variant.as_object().unwrap();
1417
1418        assert_eq!(
1419            vec![
1420                ("id", Variant::from(1)),
1421                ("type", Variant::from("Cauliflower")),
1422            ],
1423            obj1.iter().collect::<Vec<_>>()
1424        );
1425
1426        let obj2_variant = list.get(1).unwrap();
1427        let obj2 = obj2_variant.as_object().unwrap();
1428
1429        assert_eq!(
1430            vec![("id", Variant::from(2)), ("type", Variant::from("Beets")),],
1431            obj2.iter().collect::<Vec<_>>()
1432        );
1433    }
1434
1435    #[test]
1436    fn test_object_list2() {
1437        let mut builder = VariantBuilder::new();
1438
1439        let mut list_builder = builder.new_list();
1440
1441        {
1442            let mut object_builder = list_builder.new_object();
1443            object_builder.insert("a", 1);
1444            let _ = object_builder.finish();
1445        }
1446
1447        {
1448            let mut object_builder = list_builder.new_object();
1449            object_builder.insert("b", 2);
1450            let _ = object_builder.finish();
1451        }
1452
1453        list_builder.finish();
1454
1455        let (metadata, value) = builder.finish();
1456
1457        let variant = Variant::try_new(&metadata, &value).unwrap();
1458        let list = variant.as_list().unwrap();
1459        assert_eq!(list.len(), 2);
1460
1461        let obj1_variant = list.get(0).unwrap();
1462        let obj1 = obj1_variant.as_object().unwrap();
1463        assert_eq!(
1464            vec![("a", Variant::from(1)),],
1465            obj1.iter().collect::<Vec<_>>()
1466        );
1467
1468        let obj2_variant = list.get(1).unwrap();
1469        let obj2 = obj2_variant.as_object().unwrap();
1470        assert_eq!(
1471            vec![("b", Variant::from(2)),],
1472            obj2.iter().collect::<Vec<_>>()
1473        );
1474    }
1475
1476    #[test]
1477    fn test_hetergenous_list() {
1478        /*
1479        [
1480            1,
1481            { "a": 1 },
1482            2,
1483            { "b": 2},
1484            3
1485        ]
1486        */
1487
1488        let mut builder = VariantBuilder::new();
1489
1490        let mut list_builder = builder.new_list();
1491
1492        list_builder.append_value(1);
1493
1494        {
1495            let mut object_builder = list_builder.new_object();
1496            object_builder.insert("a", 1);
1497            let _ = object_builder.finish();
1498        }
1499
1500        list_builder.append_value(2);
1501
1502        {
1503            let mut object_builder = list_builder.new_object();
1504            object_builder.insert("b", 2);
1505            let _ = object_builder.finish();
1506        }
1507
1508        list_builder.append_value(3);
1509
1510        list_builder.finish();
1511
1512        let (metadata, value) = builder.finish();
1513
1514        let variant = Variant::try_new(&metadata, &value).unwrap();
1515        let list = variant.as_list().unwrap();
1516        assert_eq!(list.len(), 5);
1517        assert_eq!(list.get(0).unwrap(), Variant::from(1));
1518
1519        let obj1_variant = list.get(1).unwrap();
1520        let obj1 = obj1_variant.as_object().unwrap();
1521        assert_eq!(
1522            vec![("a", Variant::from(1)),],
1523            obj1.iter().collect::<Vec<_>>()
1524        );
1525
1526        assert_eq!(list.get(2).unwrap(), Variant::from(2));
1527
1528        let obj2_variant = list.get(3).unwrap();
1529        let obj2 = obj2_variant.as_object().unwrap();
1530        assert_eq!(
1531            vec![("b", Variant::from(2)),],
1532            obj2.iter().collect::<Vec<_>>()
1533        );
1534
1535        assert_eq!(list.get(4).unwrap(), Variant::from(3));
1536    }
1537
1538    #[test]
1539    fn test_nested_object() {
1540        /*
1541        {
1542            "c": {
1543                "b": "a"
1544            }
1545        }
1546
1547        */
1548
1549        let mut builder = VariantBuilder::new();
1550        {
1551            let mut outer_object_builder = builder.new_object();
1552            {
1553                let mut inner_object_builder = outer_object_builder.new_object("c");
1554                inner_object_builder.insert("b", "a");
1555                let _ = inner_object_builder.finish();
1556            }
1557
1558            let _ = outer_object_builder.finish();
1559        }
1560
1561        let (metadata, value) = builder.finish();
1562        let variant = Variant::try_new(&metadata, &value).unwrap();
1563        let outer_object = variant.as_object().unwrap();
1564
1565        assert_eq!(outer_object.len(), 1);
1566        assert_eq!(outer_object.field_name(0).unwrap(), "c");
1567
1568        let inner_object_variant = outer_object.field(0).unwrap();
1569        let inner_object = inner_object_variant.as_object().unwrap();
1570
1571        assert_eq!(inner_object.len(), 1);
1572        assert_eq!(inner_object.field_name(0).unwrap(), "b");
1573        assert_eq!(inner_object.field(0).unwrap(), Variant::from("a"));
1574    }
1575
1576    #[test]
1577    fn test_nested_object_with_duplicate_field_names_per_object() {
1578        /*
1579        {
1580            "c": {
1581                "b": false,
1582                "c": "a"
1583            },
1584            "b": false,
1585        }
1586
1587        */
1588
1589        let mut builder = VariantBuilder::new();
1590        {
1591            let mut outer_object_builder = builder.new_object();
1592            {
1593                let mut inner_object_builder = outer_object_builder.new_object("c");
1594                inner_object_builder.insert("b", false);
1595                inner_object_builder.insert("c", "a");
1596
1597                let _ = inner_object_builder.finish();
1598            }
1599
1600            outer_object_builder.insert("b", false);
1601            let _ = outer_object_builder.finish();
1602        }
1603
1604        let (metadata, value) = builder.finish();
1605        let variant = Variant::try_new(&metadata, &value).unwrap();
1606        let outer_object = variant.as_object().unwrap();
1607
1608        assert_eq!(outer_object.len(), 2);
1609        assert_eq!(outer_object.field_name(0).unwrap(), "b");
1610
1611        let inner_object_variant = outer_object.field(1).unwrap();
1612        let inner_object = inner_object_variant.as_object().unwrap();
1613
1614        assert_eq!(inner_object.len(), 2);
1615        assert_eq!(inner_object.field_name(0).unwrap(), "b");
1616        assert_eq!(inner_object.field(0).unwrap(), Variant::from(false));
1617        assert_eq!(inner_object.field_name(1).unwrap(), "c");
1618        assert_eq!(inner_object.field(1).unwrap(), Variant::from("a"));
1619    }
1620
1621    #[test]
1622    fn test_nested_object_with_lists() {
1623        /*
1624        {
1625            "door 1": {
1626                "items": ["apple", false ]
1627            }
1628        }
1629
1630        */
1631
1632        let mut builder = VariantBuilder::new();
1633        {
1634            let mut outer_object_builder = builder.new_object();
1635            {
1636                let mut inner_object_builder = outer_object_builder.new_object("door 1");
1637
1638                {
1639                    let mut inner_object_list_builder = inner_object_builder.new_list("items");
1640                    inner_object_list_builder.append_value("apple");
1641                    inner_object_list_builder.append_value(false);
1642                    inner_object_list_builder.finish();
1643                }
1644
1645                let _ = inner_object_builder.finish();
1646            }
1647
1648            let _ = outer_object_builder.finish();
1649        }
1650
1651        let (metadata, value) = builder.finish();
1652        let variant = Variant::try_new(&metadata, &value).unwrap();
1653        let outer_object = variant.as_object().unwrap();
1654
1655        assert_eq!(outer_object.len(), 1);
1656        assert_eq!(outer_object.field_name(0).unwrap(), "door 1");
1657
1658        let inner_object_variant = outer_object.field(0).unwrap();
1659        let inner_object = inner_object_variant.as_object().unwrap();
1660
1661        assert_eq!(inner_object.len(), 1);
1662        assert_eq!(inner_object.field_name(0).unwrap(), "items");
1663
1664        let items_variant = inner_object.field(0).unwrap();
1665        let items_list = items_variant.as_list().unwrap();
1666
1667        assert_eq!(items_list.len(), 2);
1668        assert_eq!(items_list.get(0).unwrap(), Variant::from("apple"));
1669        assert_eq!(items_list.get(1).unwrap(), Variant::from(false));
1670    }
1671
1672    #[test]
1673    fn test_nested_object_with_heterogeneous_fields() {
1674        /*
1675        {
1676            "a": false,
1677            "c": {
1678                "b": "a"
1679            }
1680            "b": true,
1681        }
1682        */
1683
1684        let mut builder = VariantBuilder::new();
1685        {
1686            let mut outer_object_builder = builder.new_object();
1687
1688            outer_object_builder.insert("a", false);
1689
1690            {
1691                let mut inner_object_builder = outer_object_builder.new_object("c");
1692                inner_object_builder.insert("b", "a");
1693                let _ = inner_object_builder.finish();
1694            }
1695
1696            outer_object_builder.insert("b", true);
1697
1698            let _ = outer_object_builder.finish();
1699        }
1700
1701        let (metadata, value) = builder.finish();
1702
1703        // note, object fields are now sorted lexigraphically by field name
1704        /*
1705         {
1706            "a": false,
1707            "b": true,
1708            "c": {
1709                "b": "a"
1710            }
1711        }
1712        */
1713
1714        let variant = Variant::try_new(&metadata, &value).unwrap();
1715        let outer_object = variant.as_object().unwrap();
1716
1717        assert_eq!(outer_object.len(), 3);
1718
1719        assert_eq!(outer_object.field_name(0).unwrap(), "a");
1720        assert_eq!(outer_object.field(0).unwrap(), Variant::from(false));
1721
1722        assert_eq!(outer_object.field_name(2).unwrap(), "c");
1723
1724        let inner_object_variant = outer_object.field(2).unwrap();
1725        let inner_object = inner_object_variant.as_object().unwrap();
1726
1727        assert_eq!(inner_object.len(), 1);
1728        assert_eq!(inner_object.field_name(0).unwrap(), "b");
1729        assert_eq!(inner_object.field(0).unwrap(), Variant::from("a"));
1730
1731        assert_eq!(outer_object.field_name(1).unwrap(), "b");
1732        assert_eq!(outer_object.field(1).unwrap(), Variant::from(true));
1733    }
1734
1735    #[test]
1736    fn test_object_without_unique_field_validation() {
1737        let mut builder = VariantBuilder::new();
1738
1739        // Root object with duplicates
1740        let mut obj = builder.new_object();
1741        obj.insert("a", 1);
1742        obj.insert("a", 2);
1743        assert!(obj.finish().is_ok());
1744
1745        // Deeply nested list structure with duplicates
1746        let mut outer_list = builder.new_list();
1747        let mut inner_list = outer_list.new_list();
1748        let mut nested_obj = inner_list.new_object();
1749        nested_obj.insert("x", 1);
1750        nested_obj.insert("x", 2);
1751        assert!(nested_obj.finish().is_ok());
1752    }
1753
1754    #[test]
1755    fn test_object_with_unique_field_validation() {
1756        let mut builder = VariantBuilder::new().with_validate_unique_fields(true);
1757
1758        // Root-level object with duplicates
1759        let mut root_obj = builder.new_object();
1760        root_obj.insert("a", 1);
1761        root_obj.insert("b", 2);
1762        root_obj.insert("a", 3);
1763        root_obj.insert("b", 4);
1764
1765        let result = root_obj.finish();
1766        assert_eq!(
1767            result.unwrap_err().to_string(),
1768            "Invalid argument error: Duplicate field keys detected: [a, b]"
1769        );
1770
1771        // Deeply nested list -> list -> object with duplicate
1772        let mut outer_list = builder.new_list();
1773        let mut inner_list = outer_list.new_list();
1774        let mut nested_obj = inner_list.new_object();
1775        nested_obj.insert("x", 1);
1776        nested_obj.insert("x", 2);
1777
1778        let nested_result = nested_obj.finish();
1779        assert_eq!(
1780            nested_result.unwrap_err().to_string(),
1781            "Invalid argument error: Duplicate field keys detected: [x]"
1782        );
1783
1784        inner_list.finish();
1785        outer_list.finish();
1786
1787        // Valid object should succeed
1788        let mut list = builder.new_list();
1789        let mut valid_obj = list.new_object();
1790        valid_obj.insert("m", 1);
1791        valid_obj.insert("n", 2);
1792
1793        let valid_result = valid_obj.finish();
1794        assert!(valid_result.is_ok());
1795    }
1796
1797    #[test]
1798    fn test_sorted_dictionary() {
1799        // check if variant metadatabuilders are equivalent from different ways of constructing them
1800        let mut variant1 = VariantBuilder::new().with_field_names(["b", "c", "d"].into_iter());
1801
1802        let mut variant2 = {
1803            let mut builder = VariantBuilder::new();
1804
1805            builder.add_field_name("b");
1806            builder.add_field_name("c");
1807            builder.add_field_name("d");
1808
1809            builder
1810        };
1811
1812        assert_eq!(
1813            variant1.metadata_builder.field_names,
1814            variant2.metadata_builder.field_names
1815        );
1816
1817        // check metadata builders say it's sorted
1818        assert!(variant1.metadata_builder.is_sorted);
1819        assert!(variant2.metadata_builder.is_sorted);
1820
1821        {
1822            // test the bad case and break the sort order
1823            variant2.add_field_name("a");
1824            assert!(!variant2.metadata_builder.is_sorted);
1825
1826            // per the spec, make sure the variant will fail to build if only metadata is provided
1827            let (m, v) = variant2.finish();
1828            let res = Variant::try_new(&m, &v);
1829            assert!(res.is_err());
1830
1831            // since it is not sorted, make sure the metadata says so
1832            let header = VariantMetadata::try_new(&m).unwrap();
1833            assert!(!header.is_sorted());
1834        }
1835
1836        // write out variant1 and make sure the sorted flag is properly encoded
1837        variant1.append_value(false);
1838
1839        let (m, v) = variant1.finish();
1840        let res = Variant::try_new(&m, &v);
1841        assert!(res.is_ok());
1842
1843        let header = VariantMetadata::try_new(&m).unwrap();
1844        assert!(header.is_sorted());
1845    }
1846
1847    #[test]
1848    fn test_object_sorted_dictionary() {
1849        // predefine the list of field names
1850        let mut variant1 = VariantBuilder::new().with_field_names(["a", "b", "c"].into_iter());
1851        let mut obj = variant1.new_object();
1852
1853        obj.insert("c", true);
1854        obj.insert("a", false);
1855        obj.insert("b", ());
1856
1857        // verify the field ids are correctly
1858        let field_ids_by_insert_order = obj.fields.iter().map(|(&id, _)| id).collect::<Vec<_>>();
1859        assert_eq!(field_ids_by_insert_order, vec![2, 0, 1]);
1860
1861        // add a field name that wasn't pre-defined but doesn't break the sort order
1862        obj.insert("d", 2);
1863        obj.finish().unwrap();
1864
1865        let (metadata, value) = variant1.finish();
1866        let variant = Variant::try_new(&metadata, &value).unwrap();
1867
1868        let metadata = VariantMetadata::try_new(&metadata).unwrap();
1869        assert!(metadata.is_sorted());
1870
1871        // verify object is sorted by field name order
1872        let object = variant.as_object().unwrap();
1873        let field_names = object
1874            .iter()
1875            .map(|(field_name, _)| field_name)
1876            .collect::<Vec<_>>();
1877
1878        assert_eq!(field_names, vec!["a", "b", "c", "d"]);
1879    }
1880
1881    #[test]
1882    fn test_object_not_sorted_dictionary() {
1883        // predefine the list of field names
1884        let mut variant1 = VariantBuilder::new().with_field_names(["b", "c", "d"].into_iter());
1885        let mut obj = variant1.new_object();
1886
1887        obj.insert("c", true);
1888        obj.insert("d", false);
1889        obj.insert("b", ());
1890
1891        // verify the field ids are correctly
1892        let field_ids_by_insert_order = obj.fields.iter().map(|(&id, _)| id).collect::<Vec<_>>();
1893        assert_eq!(field_ids_by_insert_order, vec![1, 2, 0]);
1894
1895        // add a field name that wasn't pre-defined but breaks the sort order
1896        obj.insert("a", 2);
1897        obj.finish().unwrap();
1898
1899        let (metadata, value) = variant1.finish();
1900        let variant = Variant::try_new(&metadata, &value).unwrap();
1901
1902        let metadata = VariantMetadata::try_new(&metadata).unwrap();
1903        assert!(!metadata.is_sorted());
1904
1905        // verify object field names are sorted by field name order
1906        let object = variant.as_object().unwrap();
1907        let field_names = object
1908            .iter()
1909            .map(|(field_name, _)| field_name)
1910            .collect::<Vec<_>>();
1911
1912        assert_eq!(field_names, vec!["a", "b", "c", "d"]);
1913    }
1914
1915    #[test]
1916    fn test_building_sorted_dictionary() {
1917        let mut builder = VariantBuilder::new();
1918        assert!(!builder.metadata_builder.is_sorted);
1919        assert_eq!(builder.metadata_builder.num_field_names(), 0);
1920
1921        builder.add_field_name("a");
1922
1923        assert!(builder.metadata_builder.is_sorted);
1924        assert_eq!(builder.metadata_builder.num_field_names(), 1);
1925
1926        let builder = builder.with_field_names(["b", "c", "d"].into_iter());
1927
1928        assert!(builder.metadata_builder.is_sorted);
1929        assert_eq!(builder.metadata_builder.num_field_names(), 4);
1930
1931        let builder = builder.with_field_names(["z", "y"].into_iter());
1932        assert!(!builder.metadata_builder.is_sorted);
1933        assert_eq!(builder.metadata_builder.num_field_names(), 6);
1934    }
1935
1936    #[test]
1937    fn test_metadata_builder_from_iter() {
1938        let metadata = MetadataBuilder::from_iter(vec!["apple", "banana", "cherry"]);
1939        assert_eq!(metadata.num_field_names(), 3);
1940        assert_eq!(metadata.field_name(0), "apple");
1941        assert_eq!(metadata.field_name(1), "banana");
1942        assert_eq!(metadata.field_name(2), "cherry");
1943        assert!(metadata.is_sorted);
1944
1945        let metadata = MetadataBuilder::from_iter(["zebra", "apple", "banana"]);
1946        assert_eq!(metadata.num_field_names(), 3);
1947        assert_eq!(metadata.field_name(0), "zebra");
1948        assert_eq!(metadata.field_name(1), "apple");
1949        assert_eq!(metadata.field_name(2), "banana");
1950        assert!(!metadata.is_sorted);
1951
1952        let metadata = MetadataBuilder::from_iter(Vec::<&str>::new());
1953        assert_eq!(metadata.num_field_names(), 0);
1954        assert!(!metadata.is_sorted);
1955    }
1956
1957    #[test]
1958    fn test_metadata_builder_extend() {
1959        let mut metadata = MetadataBuilder::default();
1960        assert_eq!(metadata.num_field_names(), 0);
1961        assert!(!metadata.is_sorted);
1962
1963        metadata.extend(["apple", "cherry"]);
1964        assert_eq!(metadata.num_field_names(), 2);
1965        assert_eq!(metadata.field_name(0), "apple");
1966        assert_eq!(metadata.field_name(1), "cherry");
1967        assert!(metadata.is_sorted);
1968
1969        // extend with more field names that maintain sort order
1970        metadata.extend(vec!["dinosaur", "monkey"]);
1971        assert_eq!(metadata.num_field_names(), 4);
1972        assert_eq!(metadata.field_name(2), "dinosaur");
1973        assert_eq!(metadata.field_name(3), "monkey");
1974        assert!(metadata.is_sorted);
1975
1976        // test extending with duplicate field names
1977        let initial_count = metadata.num_field_names();
1978        metadata.extend(["apple", "monkey"]);
1979        assert_eq!(metadata.num_field_names(), initial_count); // No new fields added
1980    }
1981
1982    #[test]
1983    fn test_metadata_builder_extend_sort_order() {
1984        let mut metadata = MetadataBuilder::default();
1985
1986        metadata.extend(["middle"]);
1987        assert!(metadata.is_sorted);
1988
1989        metadata.extend(["zebra"]);
1990        assert!(metadata.is_sorted);
1991
1992        // add field that breaks sort order
1993        metadata.extend(["apple"]);
1994        assert!(!metadata.is_sorted);
1995    }
1996
1997    #[test]
1998    fn test_metadata_builder_from_iter_with_string_types() {
1999        // &str
2000        let metadata = MetadataBuilder::from_iter(["a", "b", "c"]);
2001        assert_eq!(metadata.num_field_names(), 3);
2002
2003        // string
2004        let metadata =
2005            MetadataBuilder::from_iter(vec!["a".to_string(), "b".to_string(), "c".to_string()]);
2006        assert_eq!(metadata.num_field_names(), 3);
2007
2008        // mixed types (anything that implements AsRef<str>)
2009        let field_names: Vec<Box<str>> = vec!["a".into(), "b".into(), "c".into()];
2010        let metadata = MetadataBuilder::from_iter(field_names);
2011        assert_eq!(metadata.num_field_names(), 3);
2012    }
2013
2014    /// Test reusing buffers with nested objects
2015    #[test]
2016    fn test_with_existing_buffers_nested() {
2017        let mut builder = VariantBuilder::new();
2018        append_test_list(&mut builder);
2019        let (m1, v1) = builder.finish();
2020        let variant1 = Variant::new(&m1, &v1);
2021
2022        let mut builder = VariantBuilder::new();
2023        append_test_object(&mut builder);
2024        let (m2, v2) = builder.finish();
2025        let variant2 = Variant::new(&m2, &v2);
2026
2027        let mut builder = VariantBuilder::new();
2028        builder.append_value("This is a string");
2029        let (m3, v3) = builder.finish();
2030        let variant3 = Variant::new(&m3, &v3);
2031
2032        // Now, append those three variants to the a new buffer that is reused
2033        let mut builder = VariantBuilder::new();
2034        append_test_list(&mut builder);
2035        let (metadata, value) = builder.finish();
2036        let (meta1_offset, meta1_end) = (0, metadata.len());
2037        let (value1_offset, value1_end) = (0, value.len());
2038
2039        // reuse same buffer
2040        let mut builder = VariantBuilder::new_with_buffers(metadata, value);
2041        append_test_object(&mut builder);
2042        let (metadata, value) = builder.finish();
2043        let (meta2_offset, meta2_end) = (meta1_end, metadata.len());
2044        let (value2_offset, value2_end) = (value1_end, value.len());
2045
2046        // Append a string
2047        let mut builder = VariantBuilder::new_with_buffers(metadata, value);
2048        builder.append_value("This is a string");
2049        let (metadata, value) = builder.finish();
2050        let (meta3_offset, meta3_end) = (meta2_end, metadata.len());
2051        let (value3_offset, value3_end) = (value2_end, value.len());
2052
2053        // verify we can read the variants back correctly
2054        let roundtrip1 = Variant::new(
2055            &metadata[meta1_offset..meta1_end],
2056            &value[value1_offset..value1_end],
2057        );
2058        assert_eq!(roundtrip1, variant1,);
2059
2060        let roundtrip2 = Variant::new(
2061            &metadata[meta2_offset..meta2_end],
2062            &value[value2_offset..value2_end],
2063        );
2064        assert_eq!(roundtrip2, variant2,);
2065
2066        let roundtrip3 = Variant::new(
2067            &metadata[meta3_offset..meta3_end],
2068            &value[value3_offset..value3_end],
2069        );
2070        assert_eq!(roundtrip3, variant3);
2071    }
2072
2073    /// append a simple List variant
2074    fn append_test_list(builder: &mut VariantBuilder) {
2075        let mut list = builder.new_list();
2076        list.append_value(1234);
2077        list.append_value("a string value");
2078        list.finish();
2079    }
2080
2081    /// append an object variant
2082    fn append_test_object(builder: &mut VariantBuilder) {
2083        let mut obj = builder.new_object();
2084        obj.insert("a", true);
2085        obj.finish().unwrap();
2086    }
2087
2088    #[test]
2089    fn test_variant_builder_to_list_builder_no_finish() {
2090        // Create a list builder but never finish it
2091        let mut builder = VariantBuilder::new();
2092        let mut list_builder = builder.new_list();
2093        list_builder.append_value("hi");
2094        drop(list_builder);
2095
2096        builder.append_value(42i8);
2097
2098        // The original builder should be unchanged
2099        let (metadata, value) = builder.finish();
2100        let metadata = VariantMetadata::try_new(&metadata).unwrap();
2101        assert!(metadata.is_empty());
2102
2103        let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
2104        assert_eq!(variant, Variant::Int8(42));
2105    }
2106
2107    #[test]
2108    fn test_variant_builder_to_object_builder_no_finish() {
2109        // Create an object builder but never finish it
2110        let mut builder = VariantBuilder::new();
2111        let mut object_builder = builder.new_object();
2112        object_builder.insert("name", "unknown");
2113        drop(object_builder);
2114
2115        builder.append_value(42i8);
2116
2117        // The original builder should be unchanged
2118        let (metadata, value) = builder.finish();
2119        let metadata = VariantMetadata::try_new(&metadata).unwrap();
2120        assert_eq!(metadata.len(), 1);
2121        assert_eq!(&metadata[0], "name"); // not rolled back
2122
2123        let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
2124        assert_eq!(variant, Variant::Int8(42));
2125    }
2126
2127    #[test]
2128    fn test_list_builder_to_list_builder_inner_no_finish() {
2129        let mut builder = VariantBuilder::new();
2130        let mut list_builder = builder.new_list();
2131        list_builder.append_value(1i8);
2132
2133        // Create a nested list builder but never finish it
2134        let mut nested_list_builder = list_builder.new_list();
2135        nested_list_builder.append_value("hi");
2136        drop(nested_list_builder);
2137
2138        list_builder.append_value(2i8);
2139
2140        // The parent list should only contain the original values
2141        list_builder.finish();
2142        let (metadata, value) = builder.finish();
2143        let metadata = VariantMetadata::try_new(&metadata).unwrap();
2144        assert!(metadata.is_empty());
2145
2146        let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
2147        let list = variant.as_list().unwrap();
2148        assert_eq!(list.len(), 2);
2149        assert_eq!(list.get(0).unwrap(), Variant::Int8(1));
2150        assert_eq!(list.get(1).unwrap(), Variant::Int8(2));
2151    }
2152
2153    #[test]
2154    fn test_list_builder_to_list_builder_outer_no_finish() {
2155        let mut builder = VariantBuilder::new();
2156        let mut list_builder = builder.new_list();
2157        list_builder.append_value(1i8);
2158
2159        // Create a nested list builder and finish it
2160        let mut nested_list_builder = list_builder.new_list();
2161        nested_list_builder.append_value("hi");
2162        nested_list_builder.finish();
2163
2164        // Drop the outer list builder without finishing it
2165        drop(list_builder);
2166
2167        builder.append_value(2i8);
2168
2169        // Only the second attempt should appear in the final variant
2170        let (metadata, value) = builder.finish();
2171        let metadata = VariantMetadata::try_new(&metadata).unwrap();
2172        assert!(metadata.is_empty());
2173
2174        let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
2175        assert_eq!(variant, Variant::Int8(2));
2176    }
2177
2178    #[test]
2179    fn test_list_builder_to_object_builder_inner_no_finish() {
2180        let mut builder = VariantBuilder::new();
2181        let mut list_builder = builder.new_list();
2182        list_builder.append_value(1i8);
2183
2184        // Create a nested object builder but never finish it
2185        let mut nested_object_builder = list_builder.new_object();
2186        nested_object_builder.insert("name", "unknown");
2187        drop(nested_object_builder);
2188
2189        list_builder.append_value(2i8);
2190
2191        // The parent list should only contain the original values
2192        list_builder.finish();
2193        let (metadata, value) = builder.finish();
2194        let metadata = VariantMetadata::try_new(&metadata).unwrap();
2195        assert_eq!(metadata.len(), 1);
2196        assert_eq!(&metadata[0], "name"); // not rolled back
2197
2198        let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
2199        let list = variant.as_list().unwrap();
2200        assert_eq!(list.len(), 2);
2201        assert_eq!(list.get(0).unwrap(), Variant::Int8(1));
2202        assert_eq!(list.get(1).unwrap(), Variant::Int8(2));
2203    }
2204
2205    #[test]
2206    fn test_list_builder_to_object_builder_outer_no_finish() {
2207        let mut builder = VariantBuilder::new();
2208        let mut list_builder = builder.new_list();
2209        list_builder.append_value(1i8);
2210
2211        // Create a nested object builder and finish it
2212        let mut nested_object_builder = list_builder.new_object();
2213        nested_object_builder.insert("name", "unknown");
2214        nested_object_builder.finish().unwrap();
2215
2216        // Drop the outer list builder without finishing it
2217        drop(list_builder);
2218
2219        builder.append_value(2i8);
2220
2221        // Only the second attempt should appear in the final variant
2222        let (metadata, value) = builder.finish();
2223        let metadata = VariantMetadata::try_new(&metadata).unwrap();
2224        assert_eq!(metadata.len(), 1);
2225        assert_eq!(&metadata[0], "name"); // not rolled back
2226
2227        let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
2228        assert_eq!(variant, Variant::Int8(2));
2229    }
2230
2231    #[test]
2232    fn test_object_builder_to_list_builder_inner_no_finish() {
2233        let mut builder = VariantBuilder::new();
2234        let mut object_builder = builder.new_object();
2235        object_builder.insert("first", 1i8);
2236
2237        // Create a nested list builder but never finish it
2238        let mut nested_list_builder = object_builder.new_list("nested");
2239        nested_list_builder.append_value("hi");
2240        drop(nested_list_builder);
2241
2242        object_builder.insert("second", 2i8);
2243
2244        // The parent object should only contain the original fields
2245        object_builder.finish().unwrap();
2246        let (metadata, value) = builder.finish();
2247        let metadata = VariantMetadata::try_new(&metadata).unwrap();
2248        assert_eq!(metadata.len(), 2);
2249        assert_eq!(&metadata[0], "first");
2250        assert_eq!(&metadata[1], "second");
2251
2252        let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
2253        let obj = variant.as_object().unwrap();
2254        assert_eq!(obj.len(), 2);
2255        assert_eq!(obj.get("first"), Some(Variant::Int8(1)));
2256        assert_eq!(obj.get("second"), Some(Variant::Int8(2)));
2257    }
2258
2259    #[test]
2260    fn test_object_builder_to_list_builder_outer_no_finish() {
2261        let mut builder = VariantBuilder::new();
2262        let mut object_builder = builder.new_object();
2263        object_builder.insert("first", 1i8);
2264
2265        // Create a nested list builder and finish it
2266        let mut nested_list_builder = object_builder.new_list("nested");
2267        nested_list_builder.append_value("hi");
2268        nested_list_builder.finish();
2269
2270        // Drop the outer object builder without finishing it
2271        drop(object_builder);
2272
2273        builder.append_value(2i8);
2274
2275        // Only the second attempt should appear in the final variant
2276        let (metadata, value) = builder.finish();
2277        let metadata = VariantMetadata::try_new(&metadata).unwrap();
2278        assert_eq!(metadata.len(), 2);
2279        assert_eq!(&metadata[0], "first");
2280        assert_eq!(&metadata[1], "nested"); // not rolled back
2281
2282        let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
2283        assert_eq!(variant, Variant::Int8(2));
2284    }
2285
2286    #[test]
2287    fn test_object_builder_to_object_builder_inner_no_finish() {
2288        let mut builder = VariantBuilder::new();
2289        let mut object_builder = builder.new_object();
2290        object_builder.insert("first", 1i8);
2291
2292        // Create a nested object builder but never finish it
2293        let mut nested_object_builder = object_builder.new_object("nested");
2294        nested_object_builder.insert("name", "unknown");
2295        drop(nested_object_builder);
2296
2297        object_builder.insert("second", 2i8);
2298
2299        // The parent object should only contain the original fields
2300        object_builder.finish().unwrap();
2301        let (metadata, value) = builder.finish();
2302        let metadata = VariantMetadata::try_new(&metadata).unwrap();
2303        assert_eq!(metadata.len(), 3);
2304        assert_eq!(&metadata[0], "first");
2305        assert_eq!(&metadata[1], "name"); // not rolled back
2306        assert_eq!(&metadata[2], "second");
2307
2308        let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
2309        let obj = variant.as_object().unwrap();
2310        assert_eq!(obj.len(), 2);
2311        assert_eq!(obj.get("first"), Some(Variant::Int8(1)));
2312        assert_eq!(obj.get("second"), Some(Variant::Int8(2)));
2313    }
2314
2315    #[test]
2316    fn test_object_builder_to_object_builder_outer_no_finish() {
2317        let mut builder = VariantBuilder::new();
2318        let mut object_builder = builder.new_object();
2319        object_builder.insert("first", 1i8);
2320
2321        // Create a nested object builder and finish it
2322        let mut nested_object_builder = object_builder.new_object("nested");
2323        nested_object_builder.insert("name", "unknown");
2324        nested_object_builder.finish().unwrap();
2325
2326        // Drop the outer object builder without finishing it
2327        drop(object_builder);
2328
2329        builder.append_value(2i8);
2330
2331        // Only the second attempt should appear in the final variant
2332        let (metadata, value) = builder.finish();
2333        let metadata = VariantMetadata::try_new(&metadata).unwrap();
2334        assert_eq!(metadata.len(), 3);
2335        assert_eq!(&metadata[0], "first"); // not rolled back
2336        assert_eq!(&metadata[1], "name"); // not rolled back
2337        assert_eq!(&metadata[2], "nested"); // not rolled back
2338
2339        let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
2340        assert_eq!(variant, Variant::Int8(2));
2341    }
2342}