Skip to main content

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}