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 <scov...@users.noreply.github.com> 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,