use std::str::FromStr; use uuid::Uuid; use crate::error::Error; use crate::Result; #[derive(sqlx::FromRow, sqlx::Type)] pub struct File { file_id: Uuid, pub alt_text: String, extension: String, artwork_id: Option, } impl File { pub fn new(content_type: &str) -> Result { let file_id = Uuid::new_v4(); let content_type: FileType = FromStr::from_str(content_type)?; let extension = content_type.extension().to_owned(); // TODO: check file type really is content-type reported by form. Ok(Self { file_id, alt_text: String::new(), extension, artwork_id: None, }) } pub fn file_id(&self) -> Uuid { self.file_id } pub fn extension(&self) -> &str { &self.extension } pub fn artwork_id(&self) -> Option { self.artwork_id } } pub enum FileType { Audio(String), Video(String), Image(String), // TODO: text types // Text(String), } impl FileType { pub fn extension(&self) -> &str { match self { FileType::Audio(e) => e, FileType::Video(e) => e, FileType::Image(e) => e, } } } impl FromStr for FileType { type Err = Error; fn from_str(s: &str) -> Result { match s { "mp4" | "video/mp4" => Ok(FileType::Video("mp4".to_owned())), "mpeg" | "video/mpeg" => Ok(FileType::Video("mpeg".to_owned())), "webm" | "video/webm" => Ok(FileType::Video("webm".to_owned())), "ogv" | "video/ogg" => Ok(FileType::Video("ogv".to_owned())), "mp3" | "audio/mpeg" => Ok(FileType::Audio("mp3".to_owned())), "weba" | "audio/webm" => Ok(FileType::Audio("weba".to_owned())), "aac" | "audio/aac" => Ok(FileType::Audio("aac".to_owned())), "oga" | "audio/ogg" => Ok(FileType::Audio("oga".to_owned())), "wav" | "audio/wav" => Ok(FileType::Audio("wav".to_owned())), "webp" | "image/webp" => Ok(FileType::Image("webp".to_owned())), "apng" | "image/apng" => Ok(FileType::Image("apng".to_owned())), "avif" | "image/avif" => Ok(FileType::Image("avif".to_owned())), "bmp" | "image/bmp" => Ok(FileType::Image("bmp".to_owned())), "gif" | "image/gif" => Ok(FileType::Image("gif".to_owned())), "jpeg" | "image/jpeg" => Ok(FileType::Image("jpeg".to_owned())), "png" | "image/png" => Ok(FileType::Image("png".to_owned())), "svg" | "image/svg+xml" => Ok(FileType::Image("svg".to_owned())), "tiff" | "image/tiff" => Ok(FileType::Image("tiff".to_owned())), s => Err(Error::UnsupportedFileType(s.to_owned())), } } }