1use std::collections::HashMap;
34use serde::{Deserialize, Serialize};
35use thiserror::Error;
36
37pub mod client;
38pub mod multipart;
39pub mod object;
40
41pub use client::StorageClient;
42
43#[derive(Error, Debug)]
45pub enum Error {
46 #[error("Bucket not found: {bucket}")]
47 BucketNotFound { bucket: String },
48
49 #[error("Object not found: {bucket}/{key}")]
50 ObjectNotFound { bucket: String, key: String },
51
52 #[error("Invalid bucket name: {name}")]
53 InvalidBucketName { name: String },
54
55 #[error("Invalid object key: {key}")]
56 InvalidKey { key: String },
57
58 #[error("Storage full: {used} / {capacity} bytes")]
59 StorageFull { used: u64, capacity: u64 },
60
61 #[error("Compression error: {0}")]
62 Compression(String),
63
64 #[error("Network error: {0}")]
65 Network(#[from] std::io::Error),
66
67 #[error("Serialization error: {0}")]
68 Serialization(#[from] serde_json::Error),
69
70 #[error("Internal error: {0}")]
71 Internal(String),
72}
73
74pub type Result<T> = std::result::Result<T, Error>;
75
76#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
78pub enum StorageClass {
79 Standard,
81
82 InfrequentAccess,
84
85 Archive,
87}
88
89impl Default for StorageClass {
90 fn default() -> Self {
91 Self::Standard
92 }
93}
94
95#[derive(Debug, Clone)]
97pub struct PutObjectRequest {
98 pub bucket: String,
99 pub key: String,
100 pub body: Vec<u8>,
101 pub content_type: Option<String>,
102 pub metadata: HashMap<String, String>,
103 pub storage_class: Option<StorageClass>,
104}
105
106impl Default for PutObjectRequest {
107 fn default() -> Self {
108 Self {
109 bucket: String::new(),
110 key: String::new(),
111 body: Vec::new(),
112 content_type: None,
113 metadata: HashMap::new(),
114 storage_class: None,
115 }
116 }
117}
118
119#[derive(Debug, Clone)]
121pub struct PutObjectResponse {
122 pub etag: String,
123 pub version_id: Option<String>,
124}
125
126#[derive(Debug, Clone)]
128pub struct GetObjectResponse {
129 pub body: Vec<u8>,
130 pub content_type: String,
131 pub content_length: usize,
132 pub etag: String,
133 pub last_modified: chrono::DateTime<chrono::Utc>,
134 pub metadata: HashMap<String, String>,
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
139pub struct ObjectInfo {
140 pub key: String,
141 pub size: usize,
142 pub etag: String,
143 pub last_modified: chrono::DateTime<chrono::Utc>,
144 pub storage_class: StorageClass,
145}
146
147#[cfg(test)]
148mod tests {
149 use super::*;
150
151 #[test]
152 fn test_storage_class_default() {
153 let class = StorageClass::default();
154 assert!(matches!(class, StorageClass::Standard));
155 }
156}