use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use thiserror::Error;
pub mod client;
pub mod multipart;
pub mod object;
pub use client::StorageClient;
#[derive(Error, Debug)]
pub enum Error {
#[error("Bucket not found: {bucket}")]
BucketNotFound { bucket: String },
#[error("Object not found: {bucket}/{key}")]
ObjectNotFound { bucket: String, key: String },
#[error("Invalid bucket name: {name}")]
InvalidBucketName { name: String },
#[error("Invalid object key: {key}")]
InvalidKey { key: String },
#[error("Storage full: {used} / {capacity} bytes")]
StorageFull { used: u64, capacity: u64 },
#[error("Compression error: {0}")]
Compression(String),
#[error("Network error: {0}")]
Network(#[from] std::io::Error),
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("Internal error: {0}")]
Internal(String),
}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum StorageClass {
Standard,
InfrequentAccess,
Archive,
}
impl Default for StorageClass {
fn default() -> Self {
Self::Standard
}
}
#[derive(Debug, Clone)]
pub struct PutObjectRequest {
pub bucket: String,
pub key: String,
pub body: Vec<u8>,
pub content_type: Option<String>,
pub metadata: HashMap<String, String>,
pub storage_class: Option<StorageClass>,
}
impl Default for PutObjectRequest {
fn default() -> Self {
Self {
bucket: String::new(),
key: String::new(),
body: Vec::new(),
content_type: None,
metadata: HashMap::new(),
storage_class: None,
}
}
}
#[derive(Debug, Clone)]
pub struct PutObjectResponse {
pub etag: String,
pub version_id: Option<String>,
}
#[derive(Debug, Clone)]
pub struct GetObjectResponse {
pub body: Vec<u8>,
pub content_type: String,
pub content_length: usize,
pub etag: String,
pub last_modified: chrono::DateTime<chrono::Utc>,
pub metadata: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ObjectInfo {
pub key: String,
pub size: usize,
pub etag: String,
pub last_modified: chrono::DateTime<chrono::Utc>,
pub storage_class: StorageClass,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_storage_class_default() {
let class = StorageClass::default();
assert!(matches!(class, StorageClass::Standard));
}
}