use axum::extract::Form as AxumForm;
pub type Form<T> = AxumForm<T>;
pub type Multipart = axum::extract::Multipart;
#[derive(Debug, Clone)]
pub struct FileConfig {
pub max_size: usize,
pub allowed_types: Vec<String>,
pub allowed_extensions: Vec<String>,
}
impl Default for FileConfig {
fn default() -> Self {
Self {
max_size: 10 * 1024 * 1024, allowed_types: vec![],
allowed_extensions: vec![],
}
}
}
impl FileConfig {
pub fn with_max_size(max_size: usize) -> Self {
Self {
max_size,
..Default::default()
}
}
pub fn allow_type(mut self, mime_type: impl Into<String>) -> Self {
self.allowed_types.push(mime_type.into());
self
}
pub fn allow_extension(mut self, ext: impl Into<String>) -> Self {
self.allowed_extensions.push(ext.into());
self
}
pub fn validate_size(&self, size: usize) -> Result<(), String> {
if size > self.max_size {
return Err(format!("File size {} exceeds maximum {}", size, self.max_size));
}
Ok(())
}
pub fn validate_type(&self, mime_type: &str) -> Result<(), String> {
if !self.allowed_types.is_empty() && !self.allowed_types.contains(&mime_type.to_string()) {
return Err(format!("MIME type {} not allowed", mime_type));
}
Ok(())
}
pub fn validate_extension(&self, filename: &str) -> Result<(), String> {
if !self.allowed_extensions.is_empty() {
if let Some(ext) = filename.split('.').last() {
if !self.allowed_extensions.contains(&ext.to_lowercase()) {
return Err(format!("File extension .{} not allowed", ext));
}
} else {
return Err("File has no extension".to_string());
}
}
Ok(())
}
}