use derive_more::Display;
use serde::{Deserialize, Serialize};
use super::AdditionalFieldsV3;
#[non_exhaustive]
#[derive(Serialize, Clone, Debug, Display)]
#[display("{}", serde_json::to_string(self).unwrap_or_default())]
pub struct GroupMetadataV3 {
pub zarr_format: monostate::MustBe!(3u64),
pub node_type: monostate::MustBe!("group"),
#[serde(default, skip_serializing_if = "serde_json::Map::is_empty")]
pub attributes: serde_json::Map<String, serde_json::Value>,
#[serde(flatten)]
pub additional_fields: AdditionalFieldsV3,
}
impl std::cmp::PartialEq for GroupMetadataV3 {
fn eq(&self, other: &Self) -> bool {
self.attributes == other.attributes
&& self.additional_fields == other.additional_fields
}
}
impl Eq for GroupMetadataV3 {}
impl Default for GroupMetadataV3 {
fn default() -> Self {
Self::new()
}
}
impl GroupMetadataV3 {
#[must_use]
pub fn new() -> Self {
Self {
zarr_format: monostate::MustBe!(3u64),
node_type: monostate::MustBe!("group"),
attributes: serde_json::Map::new(),
additional_fields: AdditionalFieldsV3::default(),
}
}
#[allow(clippy::missing_panics_doc)]
#[must_use]
pub fn to_string_pretty(&self) -> String {
serde_json::to_string_pretty(self).expect("group metadata is valid JSON")
}
#[must_use]
pub fn with_attributes(
mut self,
attributes: serde_json::Map<String, serde_json::Value>,
) -> Self {
self.attributes = attributes;
self
}
#[must_use]
pub fn with_additional_fields(mut self, additional_fields: AdditionalFieldsV3) -> Self {
self.additional_fields = additional_fields;
self
}
}
impl<'de> Deserialize<'de> for GroupMetadataV3 {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
struct GroupMetadataV3Raw {
zarr_format: monostate::MustBe!(3u64),
node_type: monostate::MustBe!("group"),
#[serde(default, skip_serializing_if = "serde_json::Map::is_empty")]
attributes: serde_json::Map<String, serde_json::Value>,
#[serde(flatten)]
additional_fields: serde_json::Map<String, serde_json::Value>,
}
let raw = GroupMetadataV3Raw::deserialize(deserializer)?;
let additional_fields: AdditionalFieldsV3 = raw
.additional_fields
.into_iter()
.filter(|(key, value)| {
!(key == "consolidated_metadata" && value.is_null())
})
.map(|(key, value)| (key, value.into()))
.collect();
Ok(GroupMetadataV3 {
zarr_format: raw.zarr_format,
node_type: raw.node_type,
attributes: raw.attributes,
additional_fields,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deserialize_with_consolidated_metadata_null() {
let json = r#"{
"attributes": {},
"zarr_format": 3,
"consolidated_metadata": null,
"node_type": "group"
}"#;
let metadata: GroupMetadataV3 = serde_json::from_str(json).unwrap();
assert!(metadata.additional_fields.is_empty());
}
}