1use crate::facade::DiskConfig;
4#[cfg(feature = "s3")]
5use crate::facade::DiskDriver;
6use std::collections::HashMap;
7use std::env;
8
9#[derive(Debug, Clone)]
11pub struct StorageConfig {
12 pub default: String,
14 pub disks: HashMap<String, DiskConfig>,
16}
17
18impl Default for StorageConfig {
19 fn default() -> Self {
20 let mut disks = HashMap::new();
21 disks.insert("local".to_string(), DiskConfig::local("./storage"));
22
23 Self {
24 default: "local".to_string(),
25 disks,
26 }
27 }
28}
29
30impl StorageConfig {
31 pub fn new(default: impl Into<String>) -> Self {
33 Self {
34 default: default.into(),
35 disks: HashMap::new(),
36 }
37 }
38
39 pub fn from_env() -> Self {
64 let default = env::var("FILESYSTEM_DISK").unwrap_or_else(|_| "local".to_string());
65 let mut disks = HashMap::new();
66
67 let local_root =
69 env::var("FILESYSTEM_LOCAL_ROOT").unwrap_or_else(|_| "./storage".to_string());
70 let mut local_config = DiskConfig::local(&local_root);
71 if let Ok(url) = env::var("FILESYSTEM_LOCAL_URL") {
72 local_config = local_config.with_url(url);
73 }
74 disks.insert("local".to_string(), local_config);
75
76 let public_root =
78 env::var("FILESYSTEM_PUBLIC_ROOT").unwrap_or_else(|_| "./storage/public".to_string());
79 let public_url =
80 env::var("FILESYSTEM_PUBLIC_URL").unwrap_or_else(|_| "/storage".to_string());
81 let public_config = DiskConfig::local(&public_root).with_url(public_url);
82 disks.insert("public".to_string(), public_config);
83
84 #[cfg(feature = "s3")]
86 if let Ok(bucket) = env::var("AWS_BUCKET") {
87 let region = env::var("AWS_DEFAULT_REGION").unwrap_or_else(|_| "us-east-1".to_string());
88 let mut s3_config = DiskConfig {
89 driver: DiskDriver::S3,
90 root: None,
91 url: None,
92 bucket: Some(bucket),
93 region: Some(region),
94 };
95 if let Ok(url) = env::var("AWS_URL") {
96 s3_config.url = Some(url);
97 }
98 disks.insert("s3".to_string(), s3_config);
99 }
100
101 Self { default, disks }
102 }
103
104 pub fn disk(mut self, name: impl Into<String>, config: DiskConfig) -> Self {
106 self.disks.insert(name.into(), config);
107 self
108 }
109
110 pub fn default_disk(mut self, name: impl Into<String>) -> Self {
112 self.default = name.into();
113 self
114 }
115
116 pub fn get_default(&self) -> &str {
118 &self.default
119 }
120
121 pub fn get_disk(&self, name: &str) -> Option<&DiskConfig> {
123 self.disks.get(name)
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130
131 #[test]
132 fn test_storage_config_defaults() {
133 let config = StorageConfig::default();
134 assert_eq!(config.default, "local");
135 assert!(config.disks.contains_key("local"));
136 }
137
138 #[test]
139 fn test_storage_config_builder() {
140 let config = StorageConfig::new("s3")
141 .disk("local", DiskConfig::local("./storage"))
142 .disk("public", DiskConfig::local("./public").with_url("/files"));
143
144 assert_eq!(config.default, "s3");
145 assert!(config.disks.contains_key("local"));
146 assert!(config.disks.contains_key("public"));
147 }
148
149 #[test]
150 fn test_storage_config_from_env() {
151 let config = StorageConfig::from_env();
153 assert_eq!(config.default, "local");
154 assert!(config.disks.contains_key("local"));
155 assert!(config.disks.contains_key("public"));
156 }
157}