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::Object
s
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
impl VariantBuilder
pub fn with_metadata(self, metadata: VariantMetadata<'_>) -> Self
Sourcepub fn new_with_buffers(metadata_buffer: Vec<u8>, value_buffer: Vec<u8>) -> Self
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.
Sourcepub fn with_validate_unique_fields(self, validate_unique_fields: bool) -> Self
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 ObjectBuilder
s created through this VariantBuilder
(including via any ListBuilder
), and causes ObjectBuilder::finish()
to return
an error if duplicate keys were inserted.
Sourcepub fn with_field_names<'a>(
self,
field_names: impl Iterator<Item = &'a str>,
) -> Self
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 Variant
s.
Sourcepub fn reserve(&mut self, capacity: usize)
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
.
Sourcepub fn add_field_name(&mut self, field_name: &str)
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.
fn parent_state(&mut self) -> (ParentState<'_>, bool)
Sourcepub fn new_list(&mut self) -> ListBuilder<'_>
pub fn new_list(&mut self) -> ListBuilder<'_>
Create an ListBuilder
for creating Variant::List
values.
See the examples on VariantBuilder
for usage.
Sourcepub fn new_object(&mut self) -> ObjectBuilder<'_>
pub fn new_object(&mut self) -> ObjectBuilder<'_>
Create an ObjectBuilder
for creating Variant::Object
values.
See the examples on VariantBuilder
for usage.
Sourcepub fn append_value<'m, 'd, T: Into<Variant<'m, 'd>>>(&mut self, value: T)
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);