oxigdal_zarr/lib.rs
1//! OxiGDAL Zarr Driver - Pure Rust Zarr v2/v3 Support
2//!
3//! This crate provides a pure Rust implementation of the Zarr storage specification
4//! for chunked, compressed, N-dimensional arrays. It supports both Zarr v2 and v3
5//! specifications with various storage backends and compression codecs.
6//!
7//! # Features
8//!
9//! - **Zarr Versions**: Full support for both Zarr v2 and v3 specifications
10//! - **Storage Backends**: Filesystem, S3, HTTP, and in-memory storage
11//! - **Compression**: Blosc, Zstd, Gzip, LZ4 codecs
12//! - **Filters**: Shuffle, Delta, Scale-offset filters
13//! - **Async I/O**: Async support for cloud storage backends
14//! - **Parallel**: Parallel chunk reading and writing
15//! - **Caching**: LRU caching for chunks
16//!
17//! # Zarr Format
18//!
19//! Zarr is a format for the storage of chunked, compressed, N-dimensional arrays.
20//! It was designed for use in parallel computing and is widely used in scientific
21//! computing, particularly for earth observation and climate data.
22//!
23//! ## Key Concepts
24//!
25//! - **Array**: N-dimensional data structure
26//! - **Chunk**: Fixed-size sub-array for storage
27//! - **Codec**: Compression/encoding method
28//! - **Filter**: Data transformation before/after codec
29//! - **Group**: Hierarchical organization of arrays
30//! - **Attributes**: Metadata attached to arrays/groups
31//!
32//! # Example - Reading Zarr Array
33//!
34//! ```ignore
35//! use oxigdal_zarr::{ZarrReader, FilesystemStore};
36//! use oxigdal_zarr::metadata::v2::ArrayMetadataV2;
37//!
38//! // Open a Zarr v2 array
39//! let store = FilesystemStore::open("data.zarr")?;
40//! let reader = ZarrReader::open_v2(store)?;
41//!
42//! println!("Shape: {:?}", reader.shape());
43//! println!("Chunks: {:?}", reader.chunks());
44//! println!("Data type: {:?}", reader.dtype());
45//!
46//! // Read a chunk
47//! let chunk_coords = vec![0, 0, 0];
48//! let chunk_data = reader.read_chunk(&chunk_coords)?;
49//!
50//! // Read a slice
51//! let slice = reader.read_slice(&[0..10, 0..20, 0..30])?;
52//! ```
53//!
54//! # Example - Writing Zarr Array
55//!
56//! ```ignore
57//! use oxigdal_zarr::{ZarrWriter, FilesystemStore};
58//! use oxigdal_zarr::metadata::v2::{ArrayMetadataV2, DType};
59//! use oxigdal_zarr::codecs::Compressor;
60//!
61//! // Create a new Zarr v2 array
62//! let store = FilesystemStore::create("output.zarr")?;
63//! let metadata = ArrayMetadataV2 {
64//! shape: vec![100, 200, 300],
65//! chunks: vec![10, 20, 30],
66//! dtype: DType::Float32,
67//! compressor: Some(Compressor::Zstd { level: 3 }),
68//! fill_value: 0.0,
69//! order: 'C',
70//! filters: None,
71//! };
72//!
73//! let mut writer = ZarrWriter::create_v2(store, metadata)?;
74//!
75//! // Write a chunk
76//! let chunk_coords = vec![0, 0, 0];
77//! let chunk_data = vec![0.0f32; 10 * 20 * 30];
78//! writer.write_chunk(&chunk_coords, &chunk_data)?;
79//!
80//! writer.finalize()?;
81//! ```
82//!
83//! # Storage Backends
84//!
85//! ## Filesystem
86//!
87//! ```ignore
88//! use oxigdal_zarr::FilesystemStore;
89//!
90//! let store = FilesystemStore::open("data.zarr")?;
91//! ```
92//!
93//! ## S3
94//!
95//! ```ignore
96//! use oxigdal_zarr::S3Store;
97//!
98//! let store = S3Store::new("bucket-name", "prefix/data.zarr").await?;
99//! ```
100//!
101//! ## HTTP
102//!
103//! ```ignore
104//! use oxigdal_zarr::HttpStore;
105//!
106//! let store = HttpStore::new("https://example.com/data.zarr")?;
107//! ```
108
109#![cfg_attr(not(feature = "std"), no_std)]
110#![warn(clippy::all)]
111// Pedantic disabled to reduce noise - default clippy::all is sufficient
112// #![warn(clippy::pedantic)]
113#![deny(clippy::unwrap_used)]
114#![allow(clippy::module_name_repetitions)]
115#![allow(clippy::similar_names)]
116#![allow(clippy::too_many_arguments)]
117// Allow dead code for internal structures
118#![allow(dead_code)]
119// Allow partial documentation during development
120#![allow(missing_docs)]
121// Allow manual div_ceil for chunk calculations
122#![allow(clippy::manual_div_ceil)]
123// Allow expect() for internal state invariants
124#![allow(clippy::expect_used)]
125// Allow complex types for zarr data structures
126#![allow(clippy::type_complexity)]
127// Allow collapsible match for zarr format handling
128#![allow(clippy::collapsible_match)]
129// Allow manual strip for path parsing
130#![allow(clippy::manual_strip)]
131// Allow vec push after creation for chunk building
132#![allow(clippy::vec_init_then_push)]
133// Allow should_implement_trait for builder patterns
134#![allow(clippy::should_implement_trait)]
135// Allow doc list item overindentation in complex nested lists
136#![allow(clippy::doc_overindented_list_items)]
137
138#[cfg(feature = "alloc")]
139extern crate alloc;
140
141#[cfg(feature = "std")]
142extern crate std;
143
144pub mod chunk;
145pub mod codecs;
146pub mod consolidation;
147pub mod dimension;
148pub mod error;
149pub mod filters;
150pub mod metadata;
151pub mod reader;
152pub mod sharding;
153pub mod storage;
154pub mod transformers;
155pub mod writer;
156
157// Re-export commonly used types
158pub use chunk::{ChunkCoord, ChunkGrid, ChunkIndex};
159pub use consolidation::{ConsolidatedMetadata, ConsolidatedStore, consolidate_metadata};
160pub use dimension::{Dimension, DimensionSeparator, Shape};
161pub use error::{Result, ZarrError};
162#[cfg(feature = "v3")]
163pub use reader::v3::ZarrV3Reader;
164pub use reader::{ZarrReader, ZarrReaderV2};
165pub use storage::{Store, StoreKey};
166#[cfg(feature = "v3")]
167pub use writer::v3::ZarrV3Writer;
168pub use writer::{ZarrWriter, ZarrWriterV2};
169
170#[cfg(feature = "filesystem")]
171pub use storage::filesystem::FilesystemStore;
172
173#[cfg(feature = "s3")]
174pub use storage::s3::S3Storage;
175
176#[cfg(feature = "http")]
177pub use storage::http::HttpStorage;
178
179#[cfg(feature = "memory")]
180pub use storage::memory::MemoryStore;
181
182#[cfg(feature = "cache")]
183pub use storage::cache::CachingStorage;
184
185/// Crate version
186pub const VERSION: &str = env!("CARGO_PKG_VERSION");
187
188/// Crate name
189pub const NAME: &str = env!("CARGO_PKG_NAME");
190
191/// Zarr specification version 2
192pub const ZARR_VERSION_2: u8 = 2;
193
194/// Zarr specification version 3
195pub const ZARR_VERSION_3: u8 = 3;
196
197#[cfg(test)]
198mod tests {
199 use super::*;
200
201 #[test]
202 fn test_version() {
203 assert!(!VERSION.is_empty());
204 assert_eq!(NAME, "oxigdal-zarr");
205 }
206
207 #[test]
208 fn test_zarr_versions() {
209 assert_eq!(ZARR_VERSION_2, 2);
210 assert_eq!(ZARR_VERSION_3, 3);
211 }
212}