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<i32>,
}
impl File {
pub fn new(content_type: &str) -> Result<Self> {
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<i32> {
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<Self> {
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())),
}
}
}