use std::num::NonZeroU64;
use derive_more::Display;
use serde::{Deserialize, Serialize};
use zarrs_metadata::ConfigurationSerialize;
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, Display)]
#[serde(tag = "kind", rename_all = "lowercase")]
#[display("{}", serde_json::to_string(self).unwrap_or_default())]
pub enum RectilinearChunkGridConfiguration {
Inline {
chunk_shapes: Vec<ChunkEdgeLengths>,
},
}
impl ConfigurationSerialize for RectilinearChunkGridConfiguration {}
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, derive_more::From)]
#[serde(untagged)]
pub enum RunLengthElement {
Repeated([NonZeroU64; 2]),
Single(NonZeroU64),
}
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, derive_more::From)]
#[serde(untagged)]
pub enum ChunkEdgeLengths {
Scalar(NonZeroU64),
Varying(Vec<RunLengthElement>),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rectilinear_spec_example() {
let json = r#"
{
"kind": "inline",
"chunk_shapes": [
4,
[1, 2, 3],
[[4, 2]],
[[1, 3], 3],
[4, 4, 4]
]
}"#;
let _config: RectilinearChunkGridConfiguration = serde_json::from_str(json).unwrap();
}
#[test]
fn rectilinear_scalar_chunk_shapes() {
let json = r#"
{
"kind": "inline",
"chunk_shapes": [
4,
[1, 2, 3],
[[4, 2]],
[[1, 3], 3],
[4, 4, 4]
]
}"#;
let config: RectilinearChunkGridConfiguration = serde_json::from_str(json).unwrap();
let RectilinearChunkGridConfiguration::Inline { chunk_shapes } = &config;
assert_eq!(chunk_shapes.len(), 5);
assert!(matches!(&chunk_shapes[0], ChunkEdgeLengths::Scalar(v) if v.get() == 4));
assert!(matches!(&chunk_shapes[1], ChunkEdgeLengths::Varying(_)));
}
#[test]
fn rectilinear_mixed_scalar_and_array() {
let json = r#"
{
"kind": "inline",
"chunk_shapes": [10, [5, 5]]
}"#;
let config: RectilinearChunkGridConfiguration = serde_json::from_str(json).unwrap();
let RectilinearChunkGridConfiguration::Inline { chunk_shapes } = &config;
assert_eq!(chunk_shapes.len(), 2);
assert!(matches!(&chunk_shapes[0], ChunkEdgeLengths::Scalar(v) if v.get() == 10));
assert!(matches!(&chunk_shapes[1], ChunkEdgeLengths::Varying(_)));
}
}