use clap::Subcommand;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Subcommand)]
pub enum BucketAction {
List,
Create {
name: String,
#[arg(short, long, default_value = "us-east-1")]
region: String,
},
Delete {
name: String,
#[arg(short, long)]
force: bool,
},
Info {
name: String,
},
GetPolicy {
name: String,
},
SetPolicy {
name: String,
policy_file: PathBuf,
},
}
#[derive(Subcommand)]
pub enum ObjectAction {
List {
bucket: String,
#[arg(short, long)]
prefix: Option<String>,
#[arg(short, long, default_value = "1000")]
max_keys: i32,
},
Upload {
bucket: String,
key: String,
file: PathBuf,
#[arg(short = 't', long)]
content_type: Option<String>,
},
Download {
bucket: String,
key: String,
output: PathBuf,
},
Delete {
bucket: String,
key: String,
},
Info {
bucket: String,
key: String,
},
}
#[derive(Subcommand)]
pub enum ReplicationAction {
GetConfig {
bucket: String,
},
SetConfig {
bucket: String,
config_file: PathBuf,
},
Metrics {
#[arg(short, long)]
destination: Option<String>,
},
}
#[derive(Subcommand)]
pub enum MetricsAction {
Get,
Storage,
Operations,
}
#[derive(Subcommand)]
pub enum MaintenanceAction {
Backup {
#[arg(short, long)]
name: Option<String>,
#[arg(short = 't', long, default_value = "full")]
snapshot_type: String,
},
IntegrityCheck {
#[arg(short, long)]
bucket: Option<String>,
},
Cleanup {
#[arg(short, long, default_value = "30")]
retention_days: u32,
},
}
#[derive(Subcommand)]
pub enum VersioningAction {
GetStatus {
bucket: String,
},
Enable {
bucket: String,
},
Suspend {
bucket: String,
},
ListVersions {
bucket: String,
#[arg(short, long)]
prefix: Option<String>,
#[arg(short, long, default_value = "1000")]
max_keys: i32,
},
}
#[derive(Subcommand)]
pub enum ObservabilityAction {
Profiling {
#[arg(short, long)]
pprof: bool,
},
BusinessMetrics,
Anomalies {
#[arg(short = 't', long)]
anomaly_type: Option<String>,
#[arg(short, long)]
severity: Option<String>,
#[arg(short, long)]
limit: Option<usize>,
},
Resources,
Health,
}
#[derive(Subcommand)]
pub enum TransformAction {
Image {
bucket: String,
key: String,
#[arg(short = 'w', long)]
width: Option<u32>,
#[arg(short = 'H', long)]
height: Option<u32>,
#[arg(short = 'f', long)]
format: Option<String>,
#[arg(short = 'q', long)]
quality: Option<u8>,
#[arg(short = 'o', long)]
output: PathBuf,
},
Compress {
bucket: String,
key: String,
#[arg(short = 'a', long, default_value = "zstd")]
algorithm: String,
#[arg(short = 'l', long)]
level: Option<u8>,
#[arg(short = 'o', long)]
output: PathBuf,
},
TestWasm {
plugin: PathBuf,
input: PathBuf,
#[arg(short = 'p', long)]
params: Option<String>,
#[arg(short = 'o', long)]
output: Option<PathBuf>,
},
}
#[derive(Subcommand)]
pub enum BatchAction {
DeleteByPrefix {
bucket: String,
prefix: String,
#[arg(long)]
dry_run: bool,
#[arg(short = 'm', long)]
max: Option<usize>,
},
CopyMultiple {
source_bucket: String,
dest_bucket: String,
#[arg(short = 's', long)]
source_prefix: String,
#[arg(short = 'd', long)]
dest_prefix: Option<String>,
#[arg(short = 'm', long)]
max: Option<usize>,
},
TagMultiple {
bucket: String,
prefix: String,
tags: String,
#[arg(short = 'm', long)]
max: Option<usize>,
},
}
#[derive(Subcommand)]
pub enum LifecycleAction {
Get {
bucket: String,
},
Set {
bucket: String,
policy_file: PathBuf,
},
Delete {
bucket: String,
},
ListRules {
bucket: String,
},
}
#[derive(Subcommand)]
pub enum PreprocessingAction {
Create {
#[arg(short, long)]
id: String,
#[arg(short, long)]
name: String,
#[arg(short, long)]
file: PathBuf,
},
List {
#[arg(short, long, default_value = "ml-datasets")]
bucket: String,
},
Get {
#[arg(short, long)]
id: String,
#[arg(short, long, default_value = "ml-datasets")]
bucket: String,
},
Delete {
#[arg(short, long)]
id: String,
#[arg(short, long, default_value = "ml-datasets")]
bucket: String,
},
Apply {
#[arg(short, long)]
pipeline: String,
#[arg(long)]
source_bucket: String,
#[arg(long)]
source_key: String,
#[arg(long)]
dest_bucket: String,
#[arg(long)]
dest_key: String,
},
Validate {
file: PathBuf,
},
}
#[derive(Debug, Clone)]
pub struct GcMultipartArgs {
pub bucket: Option<String>,
pub retention_hours: u64,
}
#[derive(Subcommand)]
pub enum ConfigAction {
Show,
Validate {
#[arg(long)]
config_file: Option<String>,
},
}
#[derive(Subcommand)]
pub enum ServerInfoAction {
Status,
}
#[derive(Debug, Serialize, Deserialize)]
#[allow(dead_code)]
pub struct BucketInfo {
pub name: String,
pub creation_date: Option<String>,
pub region: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[allow(dead_code)]
pub struct ObjectInfo {
pub key: String,
pub size: u64,
pub last_modified: String,
pub etag: String,
pub storage_class: Option<String>,
}
#[derive(Debug)]
pub struct LatencyStats {
pub min_ms: f64,
pub max_ms: f64,
pub avg_ms: f64,
pub p99_ms: f64,
pub samples: usize,
}
impl LatencyStats {
pub fn compute(mut samples: Vec<f64>) -> Option<Self> {
if samples.is_empty() {
return None;
}
samples.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
let count = samples.len();
let min_ms = samples[0];
let max_ms = samples[count - 1];
let avg_ms = samples.iter().sum::<f64>() / count as f64;
let p99_idx = ((count as f64 * 0.99) as usize).min(count - 1);
let p99_ms = samples[p99_idx];
Some(Self {
min_ms,
max_ms,
avg_ms,
p99_ms,
samples: count,
})
}
}