use std::path::PathBuf;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "backend", rename_all = "snake_case")]
pub enum StorageConfig {
Local {
#[serde(default = "default_local_root")]
root: PathBuf,
},
S3 {
bucket: String,
#[serde(default = "default_s3_region")]
region: String,
#[serde(default)]
endpoint: Option<String>,
#[serde(default)]
access_key_id: Option<String>,
#[serde(default)]
secret_access_key: Option<String>,
#[serde(default)]
path_style: bool,
},
Gcs {
bucket: String,
#[serde(default)]
credentials_path: Option<PathBuf>,
},
Azure {
account: String,
container: String,
#[serde(default)]
access_key: Option<String>,
},
}
fn default_local_root() -> PathBuf {
PathBuf::from("./data")
}
fn default_s3_region() -> String {
"us-east-1".to_owned()
}
impl Default for StorageConfig {
fn default() -> Self {
StorageConfig::Local { root: default_local_root() }
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn parses_local_backend_with_default_root() {
let cfg: StorageConfig = serde_json::from_value(json!({ "backend": "local" })).unwrap();
assert_eq!(cfg, StorageConfig::Local { root: PathBuf::from("./data") });
}
#[test]
fn parses_s3_backend() {
let cfg: StorageConfig = serde_json::from_value(json!({
"backend": "s3",
"bucket": "uploads",
"region": "eu-central-1",
"path_style": true
}))
.unwrap();
assert_eq!(
cfg,
StorageConfig::S3 {
bucket: "uploads".into(),
region: "eu-central-1".into(),
endpoint: None,
access_key_id: None,
secret_access_key: None,
path_style: true,
}
);
}
}