VariantBuilder

Struct VariantBuilder 

Source
pub struct VariantBuilder {
    value_builder: ValueBuilder,
    metadata_builder: WritableMetadataBuilder,
    validate_unique_fields: bool,
}
Expand description

Top level builder for Variant values

§Example: create a Primitive Int8

let mut builder = VariantBuilder::new();
builder.append_value(Variant::Int8(42));
// Finish the builder to get the metadata and value
let (metadata, value) = builder.finish();
// use the Variant API to verify the result
let variant = Variant::try_new(&metadata, &value).unwrap();
assert_eq!(variant, Variant::Int8(42));

§Example: Create a Variant::Object

This example shows how to create an object with two fields:

{
 "first_name": "Jiaying",
 "last_name": "Li"
}
let mut builder = VariantBuilder::new();
// Create an object builder that will write fields to the object
let mut object_builder = builder.new_object();
object_builder.insert("first_name", "Jiaying");
object_builder.insert("last_name", "Li");
object_builder.finish(); // call finish to finalize the object
// Finish the builder to get the metadata and value
let (metadata, value) = builder.finish();
// use the Variant API to verify the result
let variant = Variant::try_new(&metadata, &value).unwrap();
let variant_object = variant.as_object().unwrap();
assert_eq!(
  variant_object.get("first_name"),
  Some(Variant::from("Jiaying"))
);
assert_eq!(
  variant_object.get("last_name"),
  Some(Variant::from("Li"))
);

You can also use the ObjectBuilder::with_field to add fields to the object

// build the same object as above
let mut builder = VariantBuilder::new();
builder.new_object()
  .with_field("first_name", "Jiaying")
  .with_field("last_name", "Li")
  .finish();
let (metadata, value) = builder.finish();
let variant = Variant::try_new(&metadata, &value).unwrap();
let variant_object = variant.as_object().unwrap();
assert_eq!(
  variant_object.get("first_name"),
  Some(Variant::from("Jiaying"))
);
assert_eq!(
  variant_object.get("last_name"),
  Some(Variant::from("Li"))
);

§Example: Create a Variant::List (an Array)

This example shows how to create an array of integers: [1, 2, 3].

 let mut builder = VariantBuilder::new();
 // Create a builder that will write elements to the list
 let mut list_builder = builder.new_list();
 list_builder.append_value(1i8);
 list_builder.append_value(2i8);
 list_builder.append_value(3i8);
// call finish to finalize the list
 list_builder.finish();
// Finish the builder to get the metadata and value
let (metadata, value) = builder.finish();
// use the Variant API to verify the result
let variant = Variant::try_new(&metadata, &value).unwrap();
let variant_list = variant.as_list().unwrap();
// Verify the list contents
assert_eq!(variant_list.get(0).unwrap(), Variant::Int8(1));
assert_eq!(variant_list.get(1).unwrap(), Variant::Int8(2));
assert_eq!(variant_list.get(2).unwrap(), Variant::Int8(3));

You can also use the ListBuilder::with_value to append values to the list.

 let mut builder = VariantBuilder::new();
 builder.new_list()
     .with_value(1i8)
     .with_value(2i8)
     .with_value(3i8)
     .finish();
let (metadata, value) = builder.finish();
let variant = Variant::try_new(&metadata, &value).unwrap();
let variant_list = variant.as_list().unwrap();
assert_eq!(variant_list.get(0).unwrap(), Variant::Int8(1));
assert_eq!(variant_list.get(1).unwrap(), Variant::Int8(2));
assert_eq!(variant_list.get(2).unwrap(), Variant::Int8(3));

§Example: Variant::List of Variant::Objects

This example shows how to create an list of objects:

[
  {
     "id": 1,
     "type": "Cauliflower"
  },
  {
     "id": 2,
     "type": "Beets"
  }
]
use parquet_variant::{Variant, VariantBuilder};
let mut builder = VariantBuilder::new();

// Create a builder that will write elements to the list
let mut list_builder = builder.new_list();

{
    let mut object_builder = list_builder.new_object();
    object_builder.insert("id", 1);
    object_builder.insert("type", "Cauliflower");
    object_builder.finish();
}

{
    let mut object_builder = list_builder.new_object();
    object_builder.insert("id", 2);
    object_builder.insert("type", "Beets");
    object_builder.finish();
}

list_builder.finish();
// Finish the builder to get the metadata and value
let (metadata, value) = builder.finish();
// use the Variant API to verify the result
let variant = Variant::try_new(&metadata, &value).unwrap();
let variant_list = variant.as_list().unwrap();


let obj1_variant = variant_list.get(0).unwrap();
let obj1 = obj1_variant.as_object().unwrap();
assert_eq!(
    obj1.get("id"),
    Some(Variant::from(1))
);
assert_eq!(
    obj1.get("type"),
    Some(Variant::from("Cauliflower"))
);

let obj2_variant = variant_list.get(1).unwrap();
let obj2 = obj2_variant.as_object().unwrap();

assert_eq!(
    obj2.get("id"),
    Some(Variant::from(2))
);
assert_eq!(
    obj2.get("type"),
    Some(Variant::from("Beets"))
);

§Example: Unique Field Validation

This example shows how enabling unique field validation will cause an error if the same field is inserted more than once.

let mut builder = VariantBuilder::new().with_validate_unique_fields(true);

// When validation is enabled, try_with_field will return an error
let result = builder
    .new_object()
    .with_field("a", 1)
    .try_with_field("a", 2);
assert!(result.is_err());

§Example: Sorted dictionaries

This example shows how to create a VariantBuilder with a pre-sorted field dictionary to improve field access performance when reading Variant objects.

You can use VariantBuilder::with_field_names to add multiple field names at once:

use parquet_variant::{Variant, VariantBuilder};
let mut builder = VariantBuilder::new()
    .with_field_names(["age", "name", "score"].into_iter());

let mut obj = builder.new_object();
obj.insert("name", "Alice");
obj.insert("age", 30);
obj.insert("score", 95.5);
obj.finish();

let (metadata, value) = builder.finish();
let variant = Variant::try_new(&metadata, &value).unwrap();

Alternatively, you can use VariantBuilder::add_field_name to add field names one by one:

use parquet_variant::{Variant, VariantBuilder};
let mut builder = VariantBuilder::new();
builder.add_field_name("age"); // field id = 0
builder.add_field_name("name"); // field id = 1
builder.add_field_name("score"); // field id = 2

let mut obj = builder.new_object();
obj.insert("name", "Bob"); // field id = 3
obj.insert("age", 25);
obj.insert("score", 88.0);
obj.finish();

let (metadata, value) = builder.finish();
let variant = Variant::try_new(&metadata, &value).unwrap();

Fields§

§value_builder: ValueBuilder§metadata_builder: WritableMetadataBuilder§validate_unique_fields: bool

Implementations§

Source§

impl VariantBuilder

Source

pub fn new() -> Self

Create a new VariantBuilder with new underlying buffers

Source

pub fn with_metadata(self, metadata: VariantMetadata<'_>) -> Self

Create a new VariantBuilder with pre-existing VariantMetadata.

Source

pub fn with_validate_unique_fields(self, validate_unique_fields: bool) -> Self

Enables validation of unique field keys in nested objects.

This setting is propagated to all ObjectBuilders created through this VariantBuilder (including via any ListBuilder), and causes ObjectBuilder::finish() to return an error if duplicate keys were inserted.

Source

pub fn with_field_names<'a>( self, field_names: impl IntoIterator<Item = &'a str>, ) -> Self

This method pre-populates the field name directory in the Variant metadata with the specific field names, in order.

You can use this to pre-populate a VariantBuilder with a sorted dictionary if you know the field names beforehand. Sorted dictionaries can accelerate field access when reading Variants.

Source

pub fn with_value<'m, 'd, T: Into<Variant<'m, 'd>>>(self, value: T) -> Self

Builder-style API for appending a value to the list and returning self to enable method chaining.

§Panics

This method will panic if the variant contains duplicate field names in objects when validation is enabled. For a fallible version, use ListBuilder::try_with_value.

Source

pub fn try_with_value<'m, 'd, T: Into<Variant<'m, 'd>>>( self, value: T, ) -> Result<Self, ArrowError>

Builder-style API for appending a value to the list and returns self for method chaining.

This is the fallible version of ListBuilder::with_value.

Source

pub fn reserve(&mut self, capacity: usize)

This method reserves capacity for field names in the Variant metadata, which can improve performance when you know the approximate number of unique field names that will be used across all objects in the Variant.

Source

pub fn add_field_name(&mut self, field_name: &str)

Adds a single field name to the field name directory in the Variant metadata.

This method does the same thing as VariantBuilder::with_field_names but adds one field name at a time.

Source

pub fn new_list(&mut self) -> ListBuilder<'_>

Create an ListBuilder for creating Variant::List values.

See the examples on VariantBuilder for usage.

Source

pub fn new_object(&mut self) -> ObjectBuilder<'_>

Create an ObjectBuilder for creating Variant::Object values.

See the examples on VariantBuilder for usage.

Source

pub fn append_value<'m, 'd, T: Into<Variant<'m, 'd>>>(&mut self, value: T)

Append a value to the builder.

§Panics

This method will panic if the variant contains duplicate field names in objects when validation is enabled. For a fallible version, use VariantBuilder::try_append_value

§Example
let mut builder = VariantBuilder::new();
// most primitive types can be appended directly as they implement `Into<Variant>`
builder.append_value(42i8);
Source

pub fn try_append_value<'m, 'd, T: Into<Variant<'m, 'd>>>( &mut self, value: T, ) -> Result<(), ArrowError>

Append a value to the builder.

Source

pub fn append_value_bytes<'m, 'd>(&mut self, value: impl Into<Variant<'m, 'd>>)

Appends a variant value to the builder by copying raw bytes when possible.

For objects and lists, this directly copies their underlying byte representation instead of performing a logical copy and without touching the metadata builder. For other variant types, this falls back to the standard append behavior.

The caller must ensure that the metadata dictionary entries are already built and correct for any objects or lists being appended.

Source

pub fn finish(self) -> (Vec<u8>, Vec<u8>)

Finish the builder and return the metadata and value buffers.

Trait Implementations§

Source§

impl Debug for VariantBuilder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for VariantBuilder

Source§

fn default() -> VariantBuilder

Returns the “default value” for a type. Read more
Source§

impl VariantBuilderExt for VariantBuilder

Source§

fn append_value<'m, 'v>(&mut self, value: impl Into<Variant<'m, 'v>>)

Appends a new variant value to this builder. See e.g. VariantBuilder::append_value.
Source§

fn try_new_list(&mut self) -> Result<ListBuilder<'_>, ArrowError>

Creates a nested list builder. See e.g. VariantBuilder::new_list. Returns an error if the nested builder cannot be created, see e.g. ObjectBuilder::try_new_list.
Source§

fn try_new_object(&mut self) -> Result<ObjectBuilder<'_>, ArrowError>

Creates a nested object builder. See e.g. VariantBuilder::new_object. Returns an error if the nested builder cannot be created, see e.g. ObjectBuilder::try_new_object.
Source§

fn new_list(&mut self) -> ListBuilder<'_>

Creates a nested list builder. See e.g. VariantBuilder::new_list. Panics if the nested builder cannot be created, see e.g. ObjectBuilder::new_list.
Source§

fn new_object(&mut self) -> ObjectBuilder<'_>

Creates a nested object builder. See e.g. VariantBuilder::new_object. Panics if the nested builder cannot be created, see e.g. ObjectBuilder::new_object.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.