oxigeo_rs3gw/lib.rs
1//! rs3gw storage backend integration for OxiGeo
2//!
3//! This crate provides high-performance cloud storage access for OxiGeo by integrating
4//! with [rs3gw](https://github.com/cool-japan/rs3gw), a Pure Rust S3-compatible storage gateway.
5//!
6//! # Features
7//!
8//! - **Multi-backend Support**: Local, S3, MinIO, GCS, Azure
9//! - **High Performance**: Zero-copy operations, heuristic read-ahead caching, deduplication
10//! - **Cloud-Optimized**: Optimized for COG (Cloud-Optimized GeoTIFF) and Zarr access
11//! - **Pure Rust**: No C/C++ dependencies (COOLJAPAN Policy compliant)
12//! - **Security**: Optional encryption-at-rest with AES-256-GCM
13//!
14//! # Architecture
15//!
16//! ```text
17//! ┌─────────────────────────────────────┐
18//! │ OxiGeo Drivers │
19//! │ (GeoTIFF, Zarr, NetCDF, etc.) │
20//! └──────────────┬──────────────────────┘
21//! │
22//! ▼
23//! ┌─────────────────────────────────────┐
24//! │ oxigeo-rs3gw (This Crate) │
25//! │ ┌──────────┐ ┌──────────┐ │
26//! │ │DataSource│ │ZarrStore │ │
27//! │ └──────────┘ └──────────┘ │
28//! └──────────────┬──────────────────────┘
29//! │
30//! ▼
31//! ┌─────────────────────────────────────┐
32//! │ rs3gw │
33//! │ ┌─────────────────────────────┐ │
34//! │ │ StorageBackend Trait │ │
35//! │ └─────────────────────────────┘ │
36//! │ │ │ │ │ │ │
37//! │ Local S3 MinIO GCS Azure │ │
38//! └─────────────────────────────────────┘
39//! ```
40//!
41//! # Usage Examples
42//!
43//! ## Reading a COG from S3
44//!
45//! ```no_run
46//! use oxigeo_rs3gw::{OxigeoBackend, Rs3gwDataSource};
47//! use oxigeo_core::io::DataSource;
48//!
49//! # #[cfg(feature = "s3")]
50//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
51//! // Configure S3 backend
52//! let backend = OxigeoBackend::S3 {
53//! region: "us-west-2".to_string(),
54//! bucket: "my-cog-bucket".to_string(),
55//! endpoint: None,
56//! access_key: None, // Uses AWS SDK default credentials
57//! secret_key: None,
58//! };
59//!
60//! // Create storage and data source
61//! let storage = backend.create_storage().await?;
62//! let source = Rs3gwDataSource::new(
63//! storage,
64//! "my-cog-bucket".to_string(),
65//! "images/landsat.cog.tif".to_string()
66//! ).await?;
67//!
68//! // Read data
69//! let size = source.size()?;
70//! println!("Image size: {} bytes", size);
71//! # Ok(())
72//! # }
73//! ```
74//!
75//! ## Using with MinIO
76//!
77//! ```no_run
78//! # #[cfg(feature = "s3")]
79//! # use oxigeo_rs3gw::{MinioBackendBuilder, Rs3gwDataSource};
80//!
81//! # #[cfg(feature = "s3")]
82//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
83//! let backend = MinioBackendBuilder::new(
84//! "http://localhost:9000",
85//! "geospatial-data",
86//! "minioadmin",
87//! "minioadmin"
88//! ).build();
89//!
90//! let storage = backend.create_storage().await?;
91//! let source = Rs3gwDataSource::new(
92//! storage,
93//! "geospatial-data".to_string(),
94//! "zarr/temperature.zarr".to_string()
95//! ).await?;
96//! # Ok(())
97//! # }
98//! ```
99//!
100//! ## Zarr Store Integration
101//!
102//! ```no_run
103//! # #[cfg(feature = "zarr")]
104//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
105//! use oxigeo_rs3gw::{OxigeoBackend, Rs3gwStore};
106//!
107//! let backend = OxigeoBackend::Local {
108//! root: "/data/zarr".into(),
109//! };
110//!
111//! let storage = backend.create_storage().await?;
112//! let store = Rs3gwStore::new(
113//! storage,
114//! "local".to_string(),
115//! "array.zarr".to_string()
116//! );
117//!
118//! // Use with Zarr array operations
119//! // let array = ZarrArray::open(store).await?;
120//! # Ok(())
121//! # }
122//! ```
123//!
124//! ## Advanced Features
125//!
126//! ### COG-Optimized Caching
127//!
128//! ```no_run
129//! # #[cfg(feature = "ml-cache")]
130//! # fn example() {
131//! use oxigeo_rs3gw::features::{CogCacheConfig, CogAccessPattern};
132//!
133//! // Configure cache for sequential tile access
134//! let cache_config = CogAccessPattern::Sequential.recommended_config();
135//! println!("Cache size: {} MB", cache_config.max_size_mb);
136//! println!("Prefetch radius: {} tiles", cache_config.prefetch_radius);
137//! # }
138//! ```
139//!
140//! ### Zarr Deduplication
141//!
142//! ```no_run
143//! # #[cfg(feature = "dedup")]
144//! # fn example() -> Result<(), String> {
145//! use oxigeo_rs3gw::features::{ZarrDedupConfig, ZarrDedupPresets};
146//!
147//! // Use preset for 256KB Zarr chunks
148//! let dedup_config = ZarrDedupPresets::medium_chunks();
149//!
150//! // Estimate potential savings
151//! let savings = oxigeo_rs3gw::features::dedup::estimate_savings(10000, 3000);
152//! println!("Estimated savings: {:.1}%", savings * 100.0);
153//! # Ok(())
154//! # }
155//! ```
156//!
157//! ### Encryption
158//!
159//! ```no_run
160//! # #[cfg(feature = "encryption")]
161//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
162//! use oxigeo_rs3gw::features::{EncryptionConfig, generate_key};
163//!
164//! // Generate a secure encryption key
165//! let key = generate_key()?;
166//!
167//! // Configure encryption
168//! let encryption = EncryptionConfig::new()
169//! .with_key(key)
170//! .with_metadata_encryption(true);
171//!
172//! encryption.validate().map_err(|e| e.to_string())?;
173//! # Ok(())
174//! # }
175//! ```
176
177#![warn(missing_docs)]
178#![warn(clippy::unwrap_used)]
179#![warn(clippy::panic)]
180
181pub mod config;
182pub mod datasource;
183pub mod error;
184pub mod features;
185
186#[cfg(feature = "zarr")]
187pub mod store;
188
189// Re-exports for convenience
190#[cfg(feature = "s3")]
191pub use config::{MinioBackendBuilder, S3BackendBuilder};
192pub use config::{OxigeoBackend, parse_url};
193pub use datasource::Rs3gwDataSource;
194pub use error::{Result, Rs3gwError};
195
196#[cfg(feature = "zarr")]
197pub use store::Rs3gwStore;
198
199// Version information
200/// The version of this crate
201pub const VERSION: &str = env!("CARGO_PKG_VERSION");
202
203/// The version of rs3gw this crate is compatible with
204pub const RS3GW_VERSION: &str = "0.1.0";
205
206#[cfg(test)]
207mod tests {
208 use super::*;
209
210 #[test]
211 fn test_version() {
212 assert!(!VERSION.is_empty());
213 assert!(!RS3GW_VERSION.is_empty());
214 }
215}