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::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: 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
impl VariantBuilder
Sourcepub fn with_metadata(self, metadata: VariantMetadata<'_>) -> Self
pub fn with_metadata(self, metadata: VariantMetadata<'_>) -> Self
Create a new VariantBuilder with pre-existing VariantMetadata
.
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 IntoIterator<Item = &'a str>,
) -> Self
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 Variant
s.
Sourcepub fn with_value<'m, 'd, T: Into<Variant<'m, 'd>>>(self, value: T) -> Self
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
.
Sourcepub fn try_with_value<'m, 'd, T: Into<Variant<'m, 'd>>>(
self,
value: T,
) -> Result<Self, ArrowError>
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
.
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.
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);
Sourcepub fn try_append_value<'m, 'd, T: Into<Variant<'m, 'd>>>(
&mut self,
value: T,
) -> Result<(), ArrowError>
pub fn try_append_value<'m, 'd, T: Into<Variant<'m, 'd>>>( &mut self, value: T, ) -> Result<(), ArrowError>
Append a value to the builder.
Sourcepub fn append_value_bytes<'m, 'd>(&mut self, value: impl Into<Variant<'m, 'd>>)
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.
Trait Implementations§
Source§impl Debug for VariantBuilder
impl Debug for VariantBuilder
Source§impl Default for VariantBuilder
impl Default for VariantBuilder
Source§fn default() -> VariantBuilder
fn default() -> VariantBuilder
Source§impl VariantBuilderExt for VariantBuilder
impl VariantBuilderExt for VariantBuilder
Source§fn append_value<'m, 'v>(&mut self, value: impl Into<Variant<'m, 'v>>)
fn append_value<'m, 'v>(&mut self, value: impl Into<Variant<'m, 'v>>)
VariantBuilder::append_value
.Source§fn try_new_list(&mut self) -> Result<ListBuilder<'_>, ArrowError>
fn try_new_list(&mut self) -> Result<ListBuilder<'_>, ArrowError>
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>
fn try_new_object(&mut self) -> Result<ObjectBuilder<'_>, ArrowError>
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<'_>
fn new_list(&mut self) -> ListBuilder<'_>
VariantBuilder::new_list
. Panics if the nested
builder cannot be created, see e.g. ObjectBuilder::new_list
.Source§fn new_object(&mut self) -> ObjectBuilder<'_>
fn new_object(&mut self) -> ObjectBuilder<'_>
VariantBuilder::new_object
. Panics if the
nested builder cannot be created, see e.g. ObjectBuilder::new_object
.