| Crates.io | zarrs_conventions |
| lib.rs | zarrs_conventions |
| version | 0.1.1 |
| created_at | 2025-12-30 17:26:21.654342+00 |
| updated_at | 2026-01-07 17:40:40.284283+00 |
| description | Zarr conventions for the zarrs ecosystem |
| homepage | |
| repository | https://github.com/clbarnes/zarrs_conventions |
| max_upload_size | |
| id | 2013061 |
| size | 130,309 |
An implementation of zarr-conventions for zarrs ecosystem.
Individual conventions should be defined in their own crates.
use zarrs_conventions::{
NestedRepr, PrefixedRepr, ZarrConventionImpl, ZarrConventions, ConventionDefinition, register_zarr_conventions,
};
// re-exported crates
use zarrs_conventions::{uuid, iref};
/// Example from the conventions spec:
/// <https://github.com/zarr-conventions/zarr-conventions-spec>
#[derive(Debug, serde::Deserialize, serde::Serialize, PartialEq)]
struct Proj {
pub code: String,
}
impl ZarrConventionImpl for Proj {
const DEFINITION: ConventionDefinition = ConventionDefinition {
uuid: uuid::uuid!("ef154843-db6c-41c3-8ccf-64294a8fa889"),
schema_url: iref::uri!(
"https://raw.githubusercontent.com/zarr-experimental/proj-nested-key/refs/tags/v1/schema.json"
),
spec_url: iref::uri!("https://example.com/specs/proj"),
name: "proj",
description: "Coordinate reference system information for geospatial data.",
};
}
// Allows the type to be represented in `{ ..., "attributes": { ..., "proj:code": "mycode" } }` form.
// Optional (so long as NestedRepr is implemented).
impl PrefixedRepr for Proj {
const PREFIX: &'static str = "proj:";
}
// Allows the type to be represented in `{ ..., "attributes": { ..., "proj": { "code": "mycode" } } }` form.
// Optional (so long as PrefixedRepr is implemented).
impl NestedRepr for Proj {
const KEY: &'static str = "proj";
}
// Allow this convention to be discovered at runtime by importers of this module.
// Not strictly necessary.
register_zarr_conventions!(Proj);
use serde_json::{Value, json};
use zarr_conventions::{AttributesParser, AttributesBuilder};
// From the `"attributes"` field of Zarr v3 metadata.
// The full metadata document may look like
// `{ "zarr_format": 3, "node_type": "group", "attributes": ... }`
let attributes = json!(
{
"zarr_conventions": [
{"schema_url": "https://example.com/schema/nested.json"},
{"schema_url": "https://example.com/schema/prefixed.json"},
{"schema_url": "https://example.com/schema/either.json"},
{"schema_url": "https://example.com/schema/something_else.json"},
],
"nested": {"bouba": "kiki"},
"prefixed:foo": "bar",
"either": {"alice": "bob"},
"either:charlie": "dan",
"other_key": "other_value",
}
);
// Assume these types are fully defined and have the appropriate *Repr traits implemented.
struct Nested;
struct Prefixed;
struct Either;
// We don't have to define the final "something_else" convention; the parser will just treat it as unstructured.
let parser: AttributesParser = serde_json::from_value(attributes);
// Ok(None) if the requested convention is not listed in zarr_conventions.
// Err if it is, but cannot be deserialised.
let maybe_nested: Option<Nested> = parser.parse_nested().unwrap();
let maybe_prefixed: Option<Prefixed> = parser.parse_prefixed().unwrap();
let maybe_either: Option<Either> = parser.parse().unwrap();
// Unstructured attributes can still be retrieved.
let other_value: Option<String> = parser.get("other_key").unwrap();
// Prepare to write metadata
let builder = AttributesBuilder::default();
// Disable writing of the name and description in zarr_conventions,
// to keep the length down.
// At least one of uuid, spec_url, schema_url must remain true.
builder.name(false).description(false);
// The list of zarr_conventions will be populated automatically
// when conventional metadata is added.
builder.add_nested(maybe_nested.unwrap()).unwrap();
builder.add_prefixed(maybe_prefixed.unwrap()).unwrap();
// For conventional metadata which can be represented either way,
// you have to pick one when serialising.
builder.add_nested(maybe_either.unwrap()).unwrap();
// You can add arbitrary attributes
builder.add_attribute("other_key", other_value).unwrap();
let value = builder.build().unwrap();
println!("{value:#}");