Skip to main content

oximedia_cloud/
types.rs

1//! Core types and traits for cloud storage
2
3use async_trait::async_trait;
4use bytes::Bytes;
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::fmt;
9
10use crate::error::Result;
11
12/// Core trait for cloud storage operations
13#[async_trait]
14pub trait CloudStorage: Send + Sync {
15    /// Upload data to the storage
16    async fn upload(&self, key: &str, data: Bytes) -> Result<()>;
17
18    /// Upload with options
19    async fn upload_with_options(
20        &self,
21        key: &str,
22        data: Bytes,
23        options: UploadOptions,
24    ) -> Result<()>;
25
26    /// Download data from storage
27    async fn download(&self, key: &str) -> Result<Bytes>;
28
29    /// Download a byte range
30    async fn download_range(&self, key: &str, start: u64, end: u64) -> Result<Bytes>;
31
32    /// List objects with a prefix
33    async fn list(&self, prefix: &str) -> Result<Vec<ObjectInfo>>;
34
35    /// List objects with pagination
36    async fn list_paginated(
37        &self,
38        prefix: &str,
39        continuation_token: Option<String>,
40        max_keys: usize,
41    ) -> Result<ListResult>;
42
43    /// Delete an object
44    async fn delete(&self, key: &str) -> Result<()>;
45
46    /// Delete multiple objects
47    async fn delete_batch(&self, keys: &[String]) -> Result<Vec<DeleteResult>>;
48
49    /// Get object metadata
50    async fn get_metadata(&self, key: &str) -> Result<ObjectMetadata>;
51
52    /// Update object metadata
53    async fn update_metadata(&self, key: &str, metadata: HashMap<String, String>) -> Result<()>;
54
55    /// Check if object exists
56    async fn exists(&self, key: &str) -> Result<bool>;
57
58    /// Copy object
59    async fn copy(&self, source_key: &str, dest_key: &str) -> Result<()>;
60
61    /// Generate a presigned URL for download
62    async fn presigned_download_url(&self, key: &str, expires_in_secs: u64) -> Result<String>;
63
64    /// Generate a presigned URL for upload
65    async fn presigned_upload_url(&self, key: &str, expires_in_secs: u64) -> Result<String>;
66
67    /// Set object storage class/tier
68    async fn set_storage_class(&self, key: &str, class: StorageClass) -> Result<()>;
69
70    /// Get storage statistics
71    async fn get_stats(&self, prefix: &str) -> Result<StorageStats>;
72}
73
74/// Information about a cloud object
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct ObjectInfo {
77    /// Object key/path
78    pub key: String,
79    /// Size in bytes
80    pub size: u64,
81    /// Last modified timestamp
82    pub last_modified: DateTime<Utc>,
83    /// ETag/checksum
84    pub etag: Option<String>,
85    /// Storage class
86    pub storage_class: Option<StorageClass>,
87    /// Content type
88    pub content_type: Option<String>,
89}
90
91/// Object metadata including user-defined metadata
92#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct ObjectMetadata {
94    /// Object information
95    pub info: ObjectInfo,
96    /// User-defined metadata
97    pub user_metadata: HashMap<String, String>,
98    /// System metadata
99    pub system_metadata: HashMap<String, String>,
100    /// Tags
101    pub tags: HashMap<String, String>,
102    /// Content encoding
103    pub content_encoding: Option<String>,
104    /// Content language
105    pub content_language: Option<String>,
106    /// Cache control
107    pub cache_control: Option<String>,
108    /// Content disposition
109    pub content_disposition: Option<String>,
110}
111
112/// Result of a list operation with pagination
113#[derive(Debug, Clone)]
114pub struct ListResult {
115    /// Objects found
116    pub objects: Vec<ObjectInfo>,
117    /// Token for next page
118    pub continuation_token: Option<String>,
119    /// Whether there are more results
120    pub is_truncated: bool,
121    /// Common prefixes (directories)
122    pub common_prefixes: Vec<String>,
123}
124
125/// Result of a delete operation
126#[derive(Debug, Clone)]
127pub struct DeleteResult {
128    /// Object key
129    pub key: String,
130    /// Whether deletion succeeded
131    pub success: bool,
132    /// Error message if failed
133    pub error: Option<String>,
134}
135
136/// Storage class/tier options
137#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
138pub enum StorageClass {
139    /// Standard/hot storage
140    Standard,
141    /// Infrequent access
142    InfrequentAccess,
143    /// Glacier/archive
144    Glacier,
145    /// Deep archive
146    DeepArchive,
147    /// Intelligent tiering
148    IntelligentTiering,
149    /// One zone infrequent access
150    OneZoneIA,
151    /// Reduced redundancy (deprecated)
152    ReducedRedundancy,
153}
154
155impl fmt::Display for StorageClass {
156    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157        match self {
158            StorageClass::Standard => write!(f, "STANDARD"),
159            StorageClass::InfrequentAccess => write!(f, "STANDARD_IA"),
160            StorageClass::Glacier => write!(f, "GLACIER"),
161            StorageClass::DeepArchive => write!(f, "DEEP_ARCHIVE"),
162            StorageClass::IntelligentTiering => write!(f, "INTELLIGENT_TIERING"),
163            StorageClass::OneZoneIA => write!(f, "ONEZONE_IA"),
164            StorageClass::ReducedRedundancy => write!(f, "REDUCED_REDUNDANCY"),
165        }
166    }
167}
168
169/// Options for upload operations
170#[derive(Debug, Clone, Default)]
171pub struct UploadOptions {
172    /// Content type
173    pub content_type: Option<String>,
174    /// Content encoding
175    pub content_encoding: Option<String>,
176    /// Cache control
177    pub cache_control: Option<String>,
178    /// Content disposition
179    pub content_disposition: Option<String>,
180    /// User metadata
181    pub metadata: HashMap<String, String>,
182    /// Tags
183    pub tags: HashMap<String, String>,
184    /// Storage class
185    pub storage_class: Option<StorageClass>,
186    /// Server-side encryption
187    pub encryption: Option<String>,
188    /// ACL (Access Control List)
189    pub acl: Option<String>,
190}
191
192/// Storage statistics
193#[derive(Debug, Clone, Default)]
194pub struct StorageStats {
195    /// Total size in bytes
196    pub total_size: u64,
197    /// Number of objects
198    pub object_count: u64,
199    /// Size by storage class
200    pub size_by_class: HashMap<String, u64>,
201    /// Count by storage class
202    pub count_by_class: HashMap<String, u64>,
203}
204
205/// Transfer progress information
206#[derive(Debug, Clone)]
207pub struct TransferProgress {
208    /// Bytes transferred
209    pub bytes_transferred: u64,
210    /// Total bytes
211    pub total_bytes: u64,
212    /// Transfer rate in bytes/sec
213    pub rate_bps: f64,
214    /// Estimated time remaining in seconds
215    pub eta_secs: Option<f64>,
216}
217
218impl TransferProgress {
219    /// Calculate progress percentage
220    #[must_use]
221    pub fn percentage(&self) -> f64 {
222        if self.total_bytes == 0 {
223            0.0
224        } else {
225            (self.bytes_transferred as f64 / self.total_bytes as f64) * 100.0
226        }
227    }
228
229    /// Check if transfer is complete
230    #[must_use]
231    pub fn is_complete(&self) -> bool {
232        self.bytes_transferred >= self.total_bytes
233    }
234}
235
236/// Lifecycle rule for automatic object management
237#[derive(Debug, Clone, Serialize, Deserialize)]
238pub struct LifecycleRule {
239    /// Rule ID
240    pub id: String,
241    /// Whether rule is enabled
242    pub enabled: bool,
243    /// Prefix filter
244    pub prefix: Option<String>,
245    /// Tags filter
246    pub tags: HashMap<String, String>,
247    /// Transitions
248    pub transitions: Vec<Transition>,
249    /// Expiration
250    pub expiration: Option<Expiration>,
251}
252
253/// Storage class transition
254#[derive(Debug, Clone, Serialize, Deserialize)]
255pub struct Transition {
256    /// Days after object creation
257    pub days: u32,
258    /// Target storage class
259    pub storage_class: StorageClass,
260}
261
262/// Object expiration configuration
263#[derive(Debug, Clone, Serialize, Deserialize)]
264pub struct Expiration {
265    /// Days after object creation
266    pub days: Option<u32>,
267    /// Specific date
268    pub date: Option<DateTime<Utc>>,
269    /// Delete expired object delete markers
270    pub expired_object_delete_marker: bool,
271}
272
273/// Replication configuration
274#[derive(Debug, Clone, Serialize, Deserialize)]
275pub struct ReplicationConfig {
276    /// Role ARN (AWS)
277    pub role: Option<String>,
278    /// Destination bucket
279    pub destination_bucket: String,
280    /// Destination storage class
281    pub destination_storage_class: Option<StorageClass>,
282    /// Replication rules
283    pub rules: Vec<ReplicationRule>,
284}
285
286/// Replication rule
287#[derive(Debug, Clone, Serialize, Deserialize)]
288pub struct ReplicationRule {
289    /// Rule ID
290    pub id: String,
291    /// Whether rule is enabled
292    pub enabled: bool,
293    /// Prefix filter
294    pub prefix: Option<String>,
295    /// Priority
296    pub priority: i32,
297    /// Delete marker replication
298    pub delete_marker_replication: bool,
299}