use super::controller::UploadController;
use crate::configs::{Config, ConfigError};
use axum::Router;
use std::sync::Arc;
use xecute::upload::{LocalStorage, UploadService, UploadStorage};
pub struct UploadModule;
impl UploadModule {
pub async fn router(config: &Config) -> Result<Router, Box<dyn std::error::Error + Send + Sync>> {
let uploads = &config.uploads;
if !uploads.enabled { return Ok(Router::new()); }
uploads.validate_location(config)?;
let storage: Arc<dyn UploadStorage> = match uploads.storage.as_str() {
"local" => Arc::new(LocalStorage::new(&uploads.directory).await?),
"s3" => {
#[cfg(feature = "s3")]
{ Arc::new(xecute::upload::S3Storage::from_environment(uploads.s3.clone()).await?) }
#[cfg(not(feature = "s3"))]
{ return Err(ConfigError::invalid("uploads.storage", "enable the s3 Cargo feature to use S3 storage").into()); }
}
_ => return Err(ConfigError::invalid("uploads.storage", "unsupported storage backend").into()),
};
let service = Arc::new(UploadService::new(uploads.policy()?, &uploads.directory, storage).await?);
Ok(UploadController::router(Arc::new(UploadController { service })))
}
pub async fn router_with_container(config: &Config, container: Arc<xecute::Container>) -> Result<Router, Box<dyn std::error::Error + Send + Sync>> {
Ok(xecute::with_container(Self::router(config).await?, container))
}
pub fn api_operations(config: &Config) -> Vec<xecute::ApiOperation> {
if !config.uploads.enabled { return Vec::new(); }
let mut operations = UploadController::api_operations();
for operation in &mut operations {
if let Some(schema) = operation.body_schema.as_mut() {
let files = &mut schema["properties"]["file"];
files["maxItems"] = serde_json::json!(config.uploads.max_files);
files["description"] = serde_json::json!(format!(
"Up to {} files; {} bytes per file; {} total bytes. Allowed types: {}.",
config.uploads.max_files, config.uploads.max_file_bytes,
config.uploads.max_total_bytes, config.uploads.allowed_types.join(", ")
));
schema["x-max-total-bytes"] = serde_json::json!(config.uploads.max_total_bytes);
}
}
operations
}
}