Struct VariantBuilder

Source
pub struct VariantBuilder {
    buffer: ValueBuffer,
    metadata_builder: MetadataBuilder,
    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();
// 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"))
);

§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);
 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));

§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: Reusing Buffers

You can use the VariantBuilder to write into existing buffers (for example to write multiple variants back to back in the same buffer)

// we will write two variants back to back
use parquet_variant::{Variant, VariantBuilder};
// Append 12345
let mut builder = VariantBuilder::new();
builder.append_value(12345);
let (metadata, value) = builder.finish();
// remember where the first variant ends
let (first_meta_offset, first_meta_len) = (0, metadata.len());
let (first_value_offset, first_value_len) = (0, value.len());

// now, append a second variant to the same buffers
let mut builder = VariantBuilder::new_with_buffers(metadata, value);
builder.append_value("Foo");
let (metadata, value) = builder.finish();

// The variants can be referenced in their appropriate location
let variant1 = Variant::new(
  &metadata[first_meta_offset..first_meta_len],
  &value[first_value_offset..first_value_len]
 );
assert_eq!(variant1, Variant::Int32(12345));

let variant2 = Variant::new(
  &metadata[first_meta_len..],
  &value[first_value_len..]
 );
assert_eq!(variant2, Variant::from("Foo"));

§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.

use parquet_variant::VariantBuilder;

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

obj.insert("a", 1);
obj.insert("a", 2); // duplicate field

// When validation is enabled, finish will return an error
let result = obj.finish(); // returns Err
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().unwrap();

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().unwrap();

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

Fields§

§buffer: ValueBuffer§metadata_builder: MetadataBuilder§validate_unique_fields: bool

Implementations§

Source§

impl VariantBuilder

Source

pub fn new() -> Self

Create a new VariantBuilder with new underlying buffer

Source

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

Source

pub fn new_with_buffers(metadata_buffer: Vec<u8>, value_buffer: Vec<u8>) -> Self

Create a new VariantBuilder that will write the metadata and values to the specified buffers.

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 Iterator<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 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

fn parent_state(&mut self) -> (ParentState<'_>, bool)

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 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<'m, 'v> VariantBuilderExt<'m, 'v> for VariantBuilder

Source§

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

Source§

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

Source§

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

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.