modo_upload/config.rs
1use serde::Deserialize;
2
3/// Storage backend selector.
4#[derive(Debug, Clone, Deserialize, Default, PartialEq, Eq)]
5#[serde(rename_all = "lowercase")]
6pub enum StorageBackend {
7 /// Local filesystem storage (default).
8 #[default]
9 Local,
10 /// S3-compatible object storage (requires the `opendal` feature).
11 S3,
12}
13
14/// Upload configuration, deserialized from YAML via `modo::config::load()`.
15///
16/// The `s3` field is only available when the `opendal` feature is enabled.
17/// Irrelevant fields are silently ignored for the active backend.
18#[derive(Debug, Clone, Deserialize)]
19#[serde(default)]
20pub struct UploadConfig {
21 /// Which storage backend to use.
22 pub backend: StorageBackend,
23 /// Local directory for file uploads.
24 pub path: String,
25 /// Default max file size when no per-field `#[upload(max_size)]` is set.
26 /// Human-readable: "10mb", "500kb". None disables the default limit.
27 pub max_file_size: Option<String>,
28 /// S3 configuration (only available with the `opendal` feature).
29 #[cfg(feature = "opendal")]
30 pub s3: S3Config,
31}
32
33impl Default for UploadConfig {
34 fn default() -> Self {
35 Self {
36 backend: StorageBackend::default(),
37 path: "./uploads".to_string(),
38 max_file_size: Some("10mb".to_string()),
39 #[cfg(feature = "opendal")]
40 s3: S3Config::default(),
41 }
42 }
43}
44
45/// S3-compatible storage configuration.
46#[cfg(feature = "opendal")]
47#[derive(Debug, Clone, Default, Deserialize)]
48#[serde(default)]
49pub struct S3Config {
50 /// S3 bucket name.
51 pub bucket: String,
52 /// AWS region.
53 pub region: String,
54 /// Custom endpoint URL (for S3-compatible services like MinIO).
55 pub endpoint: String,
56 /// AWS access key ID.
57 pub access_key_id: String,
58 /// AWS secret access key.
59 pub secret_access_key: String,
60}