Skip to content

Commit 2b40d1d

Browse files
authored
[Variant] Add Variant::as_object and Variant::as_list (#7755)
# Which issue does this PR close? - part of #6736 # Rationale for this change - While reviewing @friendlymatthew 's PR #7740 I found that the code to get the Variant object was awkward I think that an accessor is similar to the existing `as_null`, `as_i32,` etc APIs. # What changes are included in this PR? 1. Add Variant::as_object and Variant::as_list # Are there any user-facing changes? New API (and docs with tests)
1 parent a795030 commit 2b40d1d

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

parquet-variant/src/variant.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,70 @@ impl<'m, 'v> Variant<'m, 'v> {
809809
}
810810
}
811811

812+
/// Converts this variant to an `Object` if it is an [`VariantObject`].
813+
///
814+
/// Returns `Some(&VariantObject)` for object variants,
815+
/// `None` for non-object variants.
816+
///
817+
/// # Examples
818+
/// ```
819+
/// # use parquet_variant::{Variant, VariantBuilder, VariantObject};
820+
/// # let (metadata, value) = {
821+
/// # let mut builder = VariantBuilder::new();
822+
/// # let mut obj = builder.new_object();
823+
/// # obj.append_value("name", "John");
824+
/// # obj.finish();
825+
/// # builder.finish()
826+
/// # };
827+
/// // object that is {"name": "John"}
828+
/// let variant = Variant::try_new(&metadata, &value).unwrap();
829+
/// // use the `as_object` method to access the object
830+
/// let obj = variant.as_object().expect("variant should be an object");
831+
/// assert_eq!(obj.field_by_name("name").unwrap(), Some(Variant::from("John")));
832+
/// ```
833+
pub fn as_object(&'m self) -> Option<&'m VariantObject<'m, 'v>> {
834+
if let Variant::Object(obj) = self {
835+
Some(obj)
836+
} else {
837+
None
838+
}
839+
}
840+
841+
/// Converts this variant to a `List` if it is a [`VariantList`].
842+
///
843+
/// Returns `Some(&VariantList)` for list variants,
844+
/// `None` for non-list variants.
845+
///
846+
/// # Examples
847+
/// ```
848+
/// # use parquet_variant::{Variant, VariantBuilder, VariantList};
849+
/// # let (metadata, value) = {
850+
/// # let mut builder = VariantBuilder::new();
851+
/// # let mut list = builder.new_list();
852+
/// # list.append_value("John");
853+
/// # list.append_value("Doe");
854+
/// # list.finish();
855+
/// # builder.finish()
856+
/// # };
857+
/// // list that is ["John", "Doe"]
858+
/// let variant = Variant::try_new(&metadata, &value).unwrap();
859+
/// // use the `as_list` method to access the list
860+
/// let list = variant.as_list().expect("variant should be a list");
861+
/// assert_eq!(list.len(), 2);
862+
/// assert_eq!(list.get(0).unwrap(), Variant::from("John"));
863+
/// assert_eq!(list.get(1).unwrap(), Variant::from("Doe"));
864+
/// ```
865+
pub fn as_list(&'m self) -> Option<&'m VariantList<'m, 'v>> {
866+
if let Variant::List(list) = self {
867+
Some(list)
868+
} else {
869+
None
870+
}
871+
}
872+
873+
/// Return the metadata associated with this variant, if any.
874+
///
875+
/// Returns `Some(&VariantMetadata)` for object and list variants,
812876
pub fn metadata(&self) -> Option<&'m VariantMetadata> {
813877
match self {
814878
Variant::Object(VariantObject { metadata, .. })

0 commit comments

Comments
 (0)