This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 7c42a8378e [Variant] Define basic convenience methods for variant
pathing (#7894)
7c42a8378e is described below
commit 7c42a8378e1e6923d524c2962d788a4f39a2625d
Author: Ryan Johnson <[email protected]>
AuthorDate: Fri Jul 11 05:13:20 2025 -0700
[Variant] Define basic convenience methods for variant pathing (#7894)
# Which issue does this PR close?
Part of
* https://github.com/apache/arrow-rs/issues/6736
# Rationale for this change
An expected use case for variant pathing (e.g. a future `variant_get`)
would be to request a field from a variant value that is expected to be
an object, or an element from a variant value that is expected to be an
array. Those methods are currently missing.
# What changes are included in this PR?
Define `Variant::get_object_field` and `Variant::get_array_element`
methods that do what they say (returning `None` if anything mismatches).
# Are these changes tested?
New doc tests for the methods.
# Are there any user-facing changes?
New public methods on `Variant` enum.
---
parquet-variant/src/variant.rs | 56 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/parquet-variant/src/variant.rs b/parquet-variant/src/variant.rs
index 6bcf61c036..dd8287fd1c 100644
--- a/parquet-variant/src/variant.rs
+++ b/parquet-variant/src/variant.rs
@@ -962,6 +962,34 @@ impl<'m, 'v> Variant<'m, 'v> {
}
}
+ /// If this is an object and the requested field name exists, retrieves
the corresponding field
+ /// value. Otherwise, returns None.
+ ///
+ /// This is shorthand for [`Self::as_object`] followed by
[`VariantObject::get`].
+ ///
+ /// # Examples
+ /// ```
+ /// # use parquet_variant::{Variant, VariantBuilder, VariantObject};
+ /// # let mut builder = VariantBuilder::new();
+ /// # let mut obj = builder.new_object();
+ /// # obj.insert("name", "John");
+ /// # obj.finish();
+ /// # let (metadata, value) = builder.finish();
+ /// // object that is {"name": "John"}
+ /// let variant = Variant::new(&metadata, &value);
+ /// // use the `get_object_field` method to access the object
+ /// let obj = variant.get_object_field("name");
+ /// assert_eq!(obj, Some(Variant::from("John")));
+ /// let obj = variant.get_object_field("foo");
+ /// assert!(obj.is_none());
+ /// ```
+ pub fn get_object_field(&self, field_name: &str) -> Option<Self> {
+ match self {
+ Variant::Object(object) => object.get(field_name),
+ _ => None,
+ }
+ }
+
/// Converts this variant to a `List` if it is a [`VariantList`].
///
/// Returns `Some(&VariantList)` for list variants,
@@ -994,6 +1022,34 @@ impl<'m, 'v> Variant<'m, 'v> {
}
}
+ /// If this is a list and the requested index is in bounds, retrieves the
corresponding
+ /// element. Otherwise, returns None.
+ ///
+ /// This is shorthand for [`Self::as_list`] followed by
[`VariantList::get`].
+ ///
+ /// # Examples
+ /// ```
+ /// # use parquet_variant::{Variant, VariantBuilder, VariantList};
+ /// # let mut builder = VariantBuilder::new();
+ /// # let mut list = builder.new_list();
+ /// # list.append_value("John");
+ /// # list.append_value("Doe");
+ /// # list.finish();
+ /// # let (metadata, value) = builder.finish();
+ /// // list that is ["John", "Doe"]
+ /// let variant = Variant::new(&metadata, &value);
+ /// // use the `get_list_element` method to access the list
+ /// assert_eq!(variant.get_list_element(0), Some(Variant::from("John")));
+ /// assert_eq!(variant.get_list_element(1), Some(Variant::from("Doe")));
+ /// assert!(variant.get_list_element(2).is_none());
+ /// ```
+ pub fn get_list_element(&self, index: usize) -> Option<Self> {
+ match self {
+ Variant::List(list) => list.get(index),
+ _ => None,
+ }
+ }
+
/// Return the metadata associated with this variant, if any.
///
/// Returns `Some(&VariantMetadata)` for object and list variants,