use crate::facade::DiskConfig;
#[cfg(feature = "s3")]
use crate::facade::DiskDriver;
use std::collections::HashMap;
use std::env;
#[derive(Debug, Clone)]
pub struct StorageConfig {
pub default: String,
pub disks: HashMap<String, DiskConfig>,
}
impl Default for StorageConfig {
fn default() -> Self {
let mut disks = HashMap::new();
disks.insert("local".to_string(), DiskConfig::local("./storage"));
Self {
default: "local".to_string(),
disks,
}
}
}
impl StorageConfig {
pub fn new(default: impl Into<String>) -> Self {
Self {
default: default.into(),
disks: HashMap::new(),
}
}
pub fn from_env() -> Self {
let default = env::var("FILESYSTEM_DISK").unwrap_or_else(|_| "local".to_string());
let mut disks = HashMap::new();
let local_root =
env::var("FILESYSTEM_LOCAL_ROOT").unwrap_or_else(|_| "./storage".to_string());
let mut local_config = DiskConfig::local(&local_root);
if let Ok(url) = env::var("FILESYSTEM_LOCAL_URL") {
local_config = local_config.with_url(url);
}
disks.insert("local".to_string(), local_config);
let public_root =
env::var("FILESYSTEM_PUBLIC_ROOT").unwrap_or_else(|_| "./storage/public".to_string());
let public_url =
env::var("FILESYSTEM_PUBLIC_URL").unwrap_or_else(|_| "/storage".to_string());
let public_config = DiskConfig::local(&public_root).with_url(public_url);
disks.insert("public".to_string(), public_config);
#[cfg(feature = "s3")]
if let Ok(bucket) = env::var("AWS_BUCKET") {
let region = env::var("AWS_DEFAULT_REGION").unwrap_or_else(|_| "us-east-1".to_string());
let mut s3_config = DiskConfig {
driver: DiskDriver::S3,
root: None,
url: None,
bucket: Some(bucket),
region: Some(region),
};
if let Ok(url) = env::var("AWS_URL") {
s3_config.url = Some(url);
}
disks.insert("s3".to_string(), s3_config);
}
Self { default, disks }
}
pub fn disk(mut self, name: impl Into<String>, config: DiskConfig) -> Self {
self.disks.insert(name.into(), config);
self
}
pub fn default_disk(mut self, name: impl Into<String>) -> Self {
self.default = name.into();
self
}
pub fn get_default(&self) -> &str {
&self.default
}
pub fn get_disk(&self, name: &str) -> Option<&DiskConfig> {
self.disks.get(name)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_storage_config_defaults() {
let config = StorageConfig::default();
assert_eq!(config.default, "local");
assert!(config.disks.contains_key("local"));
}
#[test]
fn test_storage_config_builder() {
let config = StorageConfig::new("s3")
.disk("local", DiskConfig::local("./storage"))
.disk("public", DiskConfig::local("./public").with_url("/files"));
assert_eq!(config.default, "s3");
assert!(config.disks.contains_key("local"));
assert!(config.disks.contains_key("public"));
}
#[test]
fn test_storage_config_from_env() {
let config = StorageConfig::from_env();
assert_eq!(config.default, "local");
assert!(config.disks.contains_key("local"));
assert!(config.disks.contains_key("public"));
}
}