1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
//! `zarrs` is Rust library for the [Zarr](https://zarr.dev) storage format for multidimensional arrays and metadata.
//!
//! If you are a Python user, check out [`zarrs-python`](https://github.com/zarrs/zarrs-python).
//! It includes a high-performance codec pipeline for the reference [`zarr-python`](https://github.com/zarr-developers/zarr-python) implementation.
//!
//! `zarrs` supports [Zarr V3](https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html) and a V3 compatible subset of [Zarr V2](https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html).
//! It is fully up-to-date and conformant with the Zarr 3.1 specification with support for:
//! - all *core extensions* (data types, codecs, chunk grids, chunk key encodings, storage transformers),
//! - all accepted [Zarr Enhancement Proposals (ZEPs)](https://zarr.dev/zeps/) and several draft ZEPs:
//! - ZEP 0003: Variable chunking
//! - ZEP 0007: Strings
//! - ZEP 0009: Zarr Extension Naming
//! - various registered extensions from [zarr-developers/zarr-extensions/](https://github.com/zarr-developers/zarr-extensions/),
//! - experimental codecs intended for future registration, and
//! - user-defined custom extensions and stores.
//!
//! A changelog can be found [here](https://github.com/zarrs/zarrs/blob/main/CHANGELOG.md).
//! Correctness issues with past versions are [detailed here](https://github.com/zarrs/zarrs/blob/main/doc/correctness_issues.md).
//!
//! Developed at the [Department of Materials Physics](https://physics.anu.edu.au/research/mp/), Australian National University, Canberra, Australia.
//!
//! ## Getting Started
//! - Review the [Zarr version support](#zarr-version-support), [array extension support](#array-extension-support) (codecs, data types, etc.), [storage support](#storage-support), and the [`zarrs` ecosystem](#zarrs-ecosystem).
//! - View the [the examples](#examples) below.
//! - Read the [documentation](https://docs.rs/zarrs/latest/zarrs/) and [The `zarrs` Book].
//!
//! ### Zarr Version Support
//!
//! `zarrs` has first-class Zarr V3 support and additionally supports a *compatible subset* of Zarr V2 data that:
//! - can be converted to V3 with only a metadata change, and
//! - uses array metadata that is recognised and supported for encoding/decoding.
//!
//! `zarrs` supports forward conversion from Zarr V2 to V3. See [Converting Zarr V2 to V3](https://book.zarrs.dev/v2_to_v3.html) in [The `zarrs` Book], or try the [`zarrs_reencode`](https://github.com/zarrs/zarrs_tools/blob/main/docs/zarrs_reencode.md) CLI tool.
//!
//! ### Array Extension Support
//!
//! Extensions are grouped into three categories:
//! - *Core*: defined in the Zarr V3 specification and are fully supported.
//! - *Registered*: specified at <https://github.com/zarr-developers/zarr-extensions/>
//! - Registered extensions listed in the below tables are fully supported unless otherwise indicated.
//! - *Experimental*: indicated by 🚧 in the tables below and **recommended for evaluation only**.
//! - Experimental extensions are either pending registration or have no formal specification outside of the `zarrs` docs.
//! - Experimental extensions may be unrecognised or incompatible with other Zarr implementations.
//! - Experimental extensions may change in future releases without maintaining backwards compatibility.
//! - *Deprecated*: indicated by ~~strikethrough~~ in the tables below
//! - Deprecated aliases will not be removed, but are not recommended for use in new arrays.
//! - Deprecated extensions may be removed in future releases.
//!
//! Extension names and aliases are configurable with [`Config::codec_aliases_v3_mut`](config::Config::codec_aliases_v3_mut) and similar methods for data types and Zarr V2.
//! `zarrs` will persist extension names if opening an existing array of creating an array from metadata.
//!
//! #### Data Types
//!
//!
//! #### Codecs
//!
//!
//! #### Chunk Grids
//!
//!
//! #### Chunk Key Encodings
//!
//!
//! #### Storage Transformers
//!
//!
//! ### Storage Support
//!
//! `zarrs` supports a huge range of stores (including custom stores) via the [`zarrs_storage`] API.
//!
//!
//! [`opendal`]: https://docs.rs/opendal/latest/opendal/
//! [`object_store`]: https://docs.rs/object_store/latest/object_store/
//! [`object_store`]: https://docs.rs/object_store/latest/object_store/
//! [`zarrs_icechunk`]: https://docs.rs/zarrs_icechunk/latest/zarrs_icechunk/
//! [`zarrs_object_store`]: https://docs.rs/zarrs_object_store/latest/zarrs_object_store/
//! [`zarrs_opendal`]: https://docs.rs/zarrs_opendal/latest/zarrs_opendal/
//!
//!
//! The [`opendal`] and [`object_store`] crates are popular Rust storage backends that are fully supported via [`zarrs_opendal`] and [`zarrs_object_store`].
//! These backends provide more feature complete HTTP stores than [`zarrs_http`].
//!
//! [`zarrs_icechunk`] implements the [Icechunk](https://icechunk.io) transactional storage engine, a storage specification for Zarr that supports [`object_store`] stores.
//!
//! The [`AsyncToSyncStorageAdapter`](crate::storage::storage_adapter::async_to_sync::AsyncToSyncStorageAdapter) enables some async stores to be used in a sync context.
//!
//! ## Logging
//! `zarrs` logs information and warnings using the [`log`] crate.
//! A logging implementation must be enabled to capture logs.
//! See the [`log`] crate documentation for more details.
//!
//! ## Examples
//! ### Create and Read a Zarr Hierarchy
//! # use std::{path::PathBuf, sync::Arc};
//!
//! // Create a filesystem store
//! let store_path: PathBuf = "/path/to/hierarchy.zarr".into();
//! # let store_path: PathBuf = "tests/data/array_write_read.zarr".into();
//! let store: zarrs::storage::ReadableWritableListableStorage = Arc::new(
//! // zarrs::filesystem requires the filesystem feature
//! zarrs::filesystem::FilesystemStore::new(&store_path)?
//! );
//! # let store = Arc::new(zarrs::storage::store::MemoryStore::new());
//!
//! // Write the root group metadata
//! zarrs::group::GroupBuilder::new()
//! .build(store.clone(), "/")?
//! // .attributes(...)
//! .store_metadata()?;
//!
//! // Create a new sharded V3 array using the array builder
//! let array = zarrs::array::ArrayBuilder::new(
//! vec![3, 4], // array shape
//! vec![2, 2], // regular chunk (shard) shape
//! zarrs::array::DataType::Float32,
//! 0.0f32, // fill value
//! )
//! .array_to_bytes_codec(Arc::new(
//! // The sharding codec requires the sharding feature
//! zarrs::array::codec::ShardingCodecBuilder::new(
//! [2, 1].try_into()? // inner chunk shape
//! )
//! .bytes_to_bytes_codecs(vec![
//! // GzipCodec requires the gzip feature
//! # #[cfg(feature = "gzip")]
//! Arc::new(zarrs::array::codec::GzipCodec::new(5)?),
//! ])
//! .build()
//! ))
//! .dimension_names(["y", "x"].into())
//! .attributes(serde_json::json!({"Zarr V3": "is great"}).as_object().unwrap().clone())
//! .build(store.clone(), "/array")?; // /path/to/hierarchy.zarr/array
//!
//! // Store the array metadata
//! array.store_metadata()?;
//! println!("{}", serde_json::to_string_pretty(array.metadata())?);
//! // {
//! // "zarr_format": 3,
//! // "node_type": "array",
//! // ...
//! // }
//!
//! // Perform some write operations on the chunks
//! array.store_chunk_elements::<f32>(
//! &[0, 1], // chunk index
//! &[0.2, 0.3, 1.2, 1.3]
//! )?;
//! array.store_array_subset_ndarray::<f32, _>(
//! &[1, 1], // array index (start of subset)
//! ndarray::array![[-1.1, -1.2], [-2.1, -2.2]]
//! )?;
//! array.erase_chunk(&[1, 1])?;
//!
//! // Retrieve all array elements as an ndarray
//! let array_all = array.retrieve_array_subset_ndarray::<f32>(&array.subset_all())?;
//! println!("{array_all:4}");
//! // [[ NaN, NaN, 0.2, 0.3],
//! // [ NaN, -1.1, -1.2, 1.3],
//! // [ NaN, -2.1, NaN, NaN]]
//!
//! // Retrieve a chunk directly
//! let array_chunk = array.retrieve_chunk_ndarray::<f32>(
//! &[0, 1], // chunk index
//! )?;
//! println!("{array_chunk:4}");
//! // [[ 0.2, 0.3],
//! // [ -1.2, 1.3]]
//!
//! // Retrieve an inner chunk
//! use zarrs::array::ArrayShardedReadableExt;
//! let shard_index_cache = zarrs::array::ArrayShardedReadableExtCache::new(&array);
//! let array_inner_chunk = array.retrieve_inner_chunk_ndarray_opt::<f32>(
//! &shard_index_cache,
//! &[0, 3], // inner chunk index
//! &zarrs::array::codec::CodecOptions::default(),
//! )?;
//! println!("{array_inner_chunk:4}");
//! // [[ 0.3],
//! // [ 1.3]]
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! ### Additional Examples
//! Various examples can be found in the [`examples/`](https://github.com/zarrs/zarrs/blob/main/zarrs/examples) directory of the `zarrs` repository that demonstrate:
//! - creating and manipulating zarr hierarchies with various stores (sync and async), codecs, etc,
//! - converting between Zarr V2 and V3, and
//! - creating custom data types.
//!
//! Examples can be run with `cargo run --example <EXAMPLE_NAME>`.
//! - Some examples require non-default features, which can be enabled with `--all-features` or `--features <FEATURES>`.
//! - Some examples support a `-- --usage-log` argument to print storage API calls during execution.
//!
//! ## Crate Features
//! #### Default
//! - `filesystem`: Re-export [`zarrs_filesystem`] as [`zarrs::filesystem`](crate::filesystem`).
//! - `ndarray`: [`ndarray`] utility functions for [`Array`](crate::array::Array).
//! - Codecs: `blosc`, `crc32c`, `gzip`, `sharding`, `transpose`, `zstd`.
//!
//! #### Non-Default
//! - `async`: an **experimental** asynchronous API for [`stores`](storage), [`Array`](crate::array::Array), and [`Group`](group::Group).
//! - The async API is runtime-agnostic. This has some limitations that are detailed in the [`Array`](crate::array::Array) docs.
//! - The async API is not as performant as the sync API.
//! - Codecs: `adler32`, `bitround`, `bz2`, `fletcher32`, `gdeflate`, `pcodec`, `zfp`, `zlib`.
//! - `dlpack`: adds convenience methods for [`DLPack`](https://arrow.apache.org/docs/python/dlpack.html) tensor interop to [`Array`](crate::array::Array).
//! - Additional [`Element`](crate::array::Element)/[`ElementOwned`](crate::array::ElementOwned) implementations:
//! - `float8`: add support for [`float8`] subfloat data types.
//! - `jiff`: add support for [`jiff`] time data types.
//! - `chrono`: add support for [`chrono`] time data types.
//!
//! ## `zarrs` Ecosystem
//!
//! ## Licence
//! `zarrs` is licensed under either of
//! - the Apache License, Version 2.0 [LICENSE-APACHE](https://docs.rs/crate/zarrs/latest/source/LICENCE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0> or
//! - the MIT license [LICENSE-MIT](https://docs.rs/crate/zarrs/latest/source/LICENCE-MIT) or <http://opensource.org/licenses/MIT>, at your option.
//!
//! Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
//!
//! [The `zarrs` Book]: https://book.zarrs.dev
pub use zarrs_metadata as metadata;
pub use zarrs_metadata_ext as metadata_ext;
pub use zarrs_plugin as plugin;
pub use zarrs_registry as registry;
pub use zarrs_storage as storage;
pub use zarrs_filesystem as filesystem;
/// Get a mutable slice of the spare capacity in a vector.
/// Log a warning that an extension is experimental and may be incompatible with other Zarr V3 implementations.
///
/// # Arguments
/// * `name` - The name of the extension (e.g., `vlen`, `regular_bounded`)
/// * `extension_type` - The type of extension (e.g., `codec`, `chunk grid`, `chunk key encoding`)
pub
/// Log a warning that a deprecated extension name is being used.
///
/// # Arguments
/// * `deprecated_name` - The deprecated name being used (e.g., `binary`)
/// * `extension_type` - The type of extension (e.g., `codec`, `chunk grid`, `chunk key encoding`)
/// * `current_name` - The current/preferred name (e.g., `bytes`)
pub
use iter_concurrent_limit;
/// A serial equivalent of [`rayon_iter_concurrent_limit::iter_concurrent_limit`] for WASM compatibility.