diff --git a/src/group.rs b/src/group.rs index cb944ace..fb3e3926 100644 --- a/src/group.rs +++ b/src/group.rs @@ -29,8 +29,10 @@ use thiserror::Error; use crate::{ metadata::{ - group_metadata_v2_to_v3, v3::UnsupportedAdditionalFieldError, AdditionalFields, - GroupMetadataV2, MetadataConvertVersion, MetadataEraseVersion, MetadataRetrieveVersion, + group_metadata_v2_to_v3, + v3::{group::ConsolidatedMetadata, UnsupportedAdditionalFieldError}, + AdditionalFields, GroupMetadataV2, MetadataConvertVersion, MetadataEraseVersion, + MetadataRetrieveVersion, }, node::{NodePath, NodePathError}, storage::{ @@ -145,6 +147,30 @@ impl Group { (GM::V2(metadata), V::V3) => GM::V3(group_metadata_v2_to_v3(&metadata)), } } + + /// Get the consolidated metadata. Returns [`None`] if `consolidated_metadata` is absent. + /// + /// Consolidated metadata is not currently supported for Zarr V2 groups. + #[must_use] + pub fn consolidated_metadata(&self) -> Option<&ConsolidatedMetadata> { + if let GroupMetadata::V3(group_metadata) = &self.metadata { + group_metadata.consolidated_metadata.as_ref() + } else { + None + } + } + + /// Set the consolidated metadata. + /// + /// Consolidated metadata is not currently supported for Zarr V2 groups, and this function is a no-op. + pub fn set_consolidated_metadata( + &mut self, + consolidated_metadata: Option, + ) { + if let GroupMetadata::V3(group_metadata) = &mut self.metadata { + group_metadata.consolidated_metadata = consolidated_metadata; + } + } } impl Group { diff --git a/src/metadata/v3/group.rs b/src/metadata/v3/group.rs index 4f879a1a..5f6d549a 100644 --- a/src/metadata/v3/group.rs +++ b/src/metadata/v3/group.rs @@ -33,8 +33,8 @@ pub struct GroupMetadataV3 { #[serde(default, skip_serializing_if = "serde_json::Map::is_empty")] pub attributes: serde_json::Map, /// Consolidated metadata. - #[serde(default, skip_serializing_if = "ConsolidatedMetadata::is_empty")] - pub consolidated_metadata: ConsolidatedMetadata, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub consolidated_metadata: Option, /// Additional fields. #[serde(flatten)] pub additional_fields: AdditionalFields, @@ -58,7 +58,7 @@ impl GroupMetadataV3 { node_type: monostate::MustBe!("group"), attributes, additional_fields, - consolidated_metadata: ConsolidatedMetadata::default(), + consolidated_metadata: None, } } } @@ -88,13 +88,6 @@ impl Default for ConsolidatedMetadata { } } -impl ConsolidatedMetadata { - #[must_use] - fn is_empty(&self) -> bool { - self.metadata.is_empty() - } -} - /// The "kind" of consolidated metadata. #[non_exhaustive] #[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, Display)] @@ -137,6 +130,7 @@ mod tests { assert_eq!( group_metadata .consolidated_metadata + .unwrap() .metadata .get(&NodePath::new("/subgroup").unwrap()) .unwrap(), diff --git a/tests/hierarchy.rs b/tests/hierarchy.rs index 75ebc1eb..8bb32e3d 100644 --- a/tests/hierarchy.rs +++ b/tests/hierarchy.rs @@ -1,6 +1,8 @@ use std::sync::Arc; use zarrs::{ + group::Group, + metadata::v3::group::ConsolidatedMetadata, node::{Node, NodePath}, storage::store::FilesystemStore, }; @@ -43,4 +45,12 @@ fn consolidated_metadata() { let actual = Node::open(&store, node_path).unwrap(); assert_eq!(consolidated, actual.metadata()); } + + let mut group = Group::open(store, "/").unwrap(); + assert!(group.consolidated_metadata().is_none()); + group.set_consolidated_metadata(Some(ConsolidatedMetadata { + metadata: consolidated_metadata, + ..Default::default() + })); + assert!(group.consolidated_metadata().is_some()); }