scirs2_io/zarr/types.rs
1//! Zarr v3 types: data types, compressors, array metadata, and array structs.
2
3use serde::{Deserialize, Serialize};
4
5/// Supported Zarr data types.
6#[non_exhaustive]
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8pub enum ZarrDataType {
9 /// 32-bit floating point
10 Float32,
11 /// 64-bit floating point
12 Float64,
13 /// 32-bit signed integer
14 Int32,
15 /// 64-bit signed integer
16 Int64,
17 /// 8-bit unsigned integer
18 UInt8,
19 /// 16-bit unsigned integer
20 UInt16,
21 /// 32-bit unsigned integer
22 UInt32,
23}
24
25impl ZarrDataType {
26 /// Returns the number of bytes per element.
27 pub fn byte_size(&self) -> usize {
28 match self {
29 ZarrDataType::Float32 => 4,
30 ZarrDataType::Float64 => 8,
31 ZarrDataType::Int32 => 4,
32 ZarrDataType::Int64 => 8,
33 ZarrDataType::UInt8 => 1,
34 ZarrDataType::UInt16 => 2,
35 ZarrDataType::UInt32 => 4,
36 }
37 }
38
39 /// Returns the Zarr v3 data type string.
40 pub fn as_str(&self) -> &'static str {
41 match self {
42 ZarrDataType::Float32 => "float32",
43 ZarrDataType::Float64 => "float64",
44 ZarrDataType::Int32 => "int32",
45 ZarrDataType::Int64 => "int64",
46 ZarrDataType::UInt8 => "uint8",
47 ZarrDataType::UInt16 => "uint16",
48 ZarrDataType::UInt32 => "uint32",
49 }
50 }
51}
52
53/// Zarr compressor configuration.
54///
55/// Actual compression is handled via oxiarc-* crates (COOLJAPAN Policy).
56/// For `None`, raw bytes are stored.
57#[non_exhaustive]
58#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
59pub enum ZarrCompressor {
60 /// No compression — store raw bytes.
61 None,
62 /// Blosc compression (placeholder; compression via oxiarc).
63 Blosc {
64 /// Blosc codec name (e.g., "lz4", "zstd").
65 cname: String,
66 /// Compression level (1–9).
67 clevel: u8,
68 },
69 /// GZip/Deflate compression via oxiarc-deflate.
70 GZip {
71 /// Compression level (1–9).
72 level: u8,
73 },
74 /// Zstandard compression via oxiarc-zstd.
75 Zstd {
76 /// Compression level (1–22).
77 level: u8,
78 },
79}
80
81/// Zarr v3 array metadata (zarr.json).
82#[non_exhaustive]
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct ZarrArrayMeta {
85 /// Shape of the array.
86 pub shape: Vec<usize>,
87 /// Chunk shape (must have same length as `shape`).
88 pub chunks: Vec<usize>,
89 /// Element data type.
90 pub dtype: ZarrDataType,
91 /// Compressor configuration.
92 pub compressor: ZarrCompressor,
93 /// Fill value for missing/unwritten chunks.
94 pub fill_value: f64,
95 /// Zarr format version (must be 3).
96 pub zarr_format: u8,
97 /// Separator character used in chunk keys ('/' for v3).
98 pub dimension_separator: char,
99}
100
101impl Default for ZarrArrayMeta {
102 fn default() -> Self {
103 Self {
104 shape: vec![],
105 chunks: vec![],
106 dtype: ZarrDataType::Float64,
107 compressor: ZarrCompressor::None,
108 fill_value: 0.0,
109 zarr_format: 3,
110 dimension_separator: '/',
111 }
112 }
113}
114
115/// An in-memory Zarr array with flat f64 storage.
116pub struct ZarrArray {
117 /// Array metadata.
118 pub meta: ZarrArrayMeta,
119 /// Flat data buffer in row-major order.
120 pub(crate) data: Vec<f64>,
121}
122
123impl ZarrArray {
124 /// Create a new ZarrArray with given metadata and flat data.
125 pub fn new(meta: ZarrArrayMeta, data: Vec<f64>) -> Self {
126 Self { meta, data }
127 }
128
129 /// Total number of elements.
130 pub fn len(&self) -> usize {
131 self.data.len()
132 }
133
134 /// Returns `true` if the array contains no elements.
135 pub fn is_empty(&self) -> bool {
136 self.data.is_empty()
137 }
138
139 /// Access data as a flat slice.
140 pub fn as_slice(&self) -> &[f64] {
141 &self.data
142 }
143}