Skip to content

Commit

Permalink
fix: permit string compression levels in zstd codec metadata (for `…
Browse files Browse the repository at this point in the history
…zarr-python` compatibility)
  • Loading branch information
LDeakin committed Feb 5, 2025
1 parent 9d05d14 commit 623b918
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
1 change: 1 addition & 0 deletions zarrs_metadata/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Fixed
- Permit string compression levels in `zstd` codec metadata (for `zarr-python` compatibility)
- Use `bytes` codec with native endianness if unset for a Zarr V2 array

## [0.3.2] - 2025-02-04
Expand Down
26 changes: 21 additions & 5 deletions zarrs_metadata/src/v3/array/codec/zstd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use derive_more::{Display, From};
use serde::{Deserialize, Serialize};
use serde_json::Value;

/// The identifier for the `zstd` codec.
pub const IDENTIFIER: &str = "zstd";
Expand Down Expand Up @@ -40,12 +41,27 @@ pub struct ZstdCompressionLevel(i32);

impl<'de> serde::Deserialize<'de> for ZstdCompressionLevel {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let number = serde_json::Number::deserialize(d)?;
if let Some(number) = number.as_i64() {
if (-131_072..=22).contains(&number) {
#[allow(clippy::cast_possible_truncation)]
return Ok(Self(number as i32));
let value = Value::deserialize(d)?;
match value {
Value::Number(number) => {
if let Some(number) = number.as_i64() {
if (-131_072..=22).contains(&number) {
#[allow(clippy::cast_possible_truncation)]
return Ok(Self(number as i32));
}
}
}
Value::String(string) => {
// COMPATIBILITY: support data created with zarr-python that uses a string for the level
// https://github.com/zarr-developers/zarr-python/blob/a52048ddb2d5d069c3404e7457439a9ecb5e40c3/tests/test_v2.py#L278-L280
if let Ok(number) = string.parse::<i64>() {
if (-131_072..=22).contains(&number) {
#[allow(clippy::cast_possible_truncation)]
return Ok(Self(number as i32));
}
}
}
_ => {}
}
Err(serde::de::Error::custom(
"Zstd compression level must be an integer between -131072 and 22",
Expand Down

0 comments on commit 623b918

Please sign in to comment.