use derive_more::{Display, From};
use serde::{Deserialize, Serialize};
use zarrs_metadata::{v3::MetadataV3, ConfigurationSerialize};
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, Display, From)]
#[non_exhaustive]
#[serde(untagged)]
pub enum VlenCodecConfiguration {
V0_1(VlenCodecConfigurationV0_1),
V0(VlenCodecConfigurationV0),
}
impl ConfigurationSerialize for VlenCodecConfiguration {}
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, Display)]
#[serde(deny_unknown_fields)]
#[display("{}", serde_json::to_string(self).unwrap_or_default())]
pub struct VlenCodecConfigurationV0 {
pub index_codecs: Vec<MetadataV3>,
pub data_codecs: Vec<MetadataV3>,
pub index_data_type: VlenIndexDataType,
}
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, Display)]
#[serde(deny_unknown_fields)]
#[display("{}", serde_json::to_string(self).unwrap_or_default())]
pub struct VlenCodecConfigurationV0_1 {
pub index_codecs: Vec<MetadataV3>,
pub data_codecs: Vec<MetadataV3>,
pub index_data_type: VlenIndexDataType,
pub index_location: VlenIndexLocation,
}
#[derive(Serialize, Deserialize, Clone, Copy, Eq, PartialEq, Debug, Display)]
#[serde(rename_all = "lowercase")]
pub enum VlenIndexLocation {
Start,
End,
}
#[derive(Serialize, Deserialize, Clone, Copy, Eq, PartialEq, Debug, Display)]
#[serde(rename_all = "lowercase")]
pub enum VlenIndexDataType {
UInt32,
UInt64,
}
impl VlenCodecConfigurationV0 {
#[must_use]
pub fn new(
index_codecs: Vec<MetadataV3>,
data_codecs: Vec<MetadataV3>,
index_data_type: VlenIndexDataType,
) -> Self {
Self {
index_codecs,
data_codecs,
index_data_type,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn codec_vlen_simple_v0_0() {
serde_json::from_str::<VlenCodecConfiguration>(
r#"{
"data_codecs": [{"name": "bytes"}],
"index_codecs": [{"name": "bytes","configuration": { "endian": "little" }}],
"index_data_type": "uint32"
}"#,
)
.unwrap();
}
#[test]
fn codec_vlen_simple_v0_1_start() {
serde_json::from_str::<VlenCodecConfiguration>(
r#"{
"data_codecs": [{"name": "bytes"}],
"index_codecs": [{"name": "bytes","configuration": { "endian": "little" }}],
"index_data_type": "uint32",
"index_location": "start"
}"#,
)
.unwrap();
}
#[test]
fn codec_vlen_compressed() {
serde_json::from_str::<VlenCodecConfiguration>(r#"{
"data_codecs": [{"name": "bytes"},{"name": "blosc","configuration": {"cname": "zstd", "clevel":5,"shuffle": "bitshuffle", "typesize":1,"blocksize":0}}],
"index_codecs": [{"name": "bytes","configuration": { "endian": "little" }},{"name": "blosc","configuration":{"cname": "zstd", "clevel":5,"shuffle": "shuffle", "typesize":4,"blocksize":0}}],
"index_data_type": "uint32",
"index_location": "end"
}"#).unwrap();
}
}