#[cfg(feature = "ssr")]
use std::path::Path;
#[cfg(feature = "ssr")]
use crate::AppError;
#[derive(Debug, Clone)]
pub enum MimeType {
Image,
Video,
Audio,
Document,
Archive,
Other(String),
}
#[cfg(feature = "ssr")]
impl MimeType {
fn from_mime_str(mime_str: &str) -> Self {
match mime_str {
s if s.starts_with("image/") => MimeType::Image,
s if s.starts_with("video/") => MimeType::Video,
s if s.starts_with("audio/") => MimeType::Audio,
"application/pdf"
| "application/msword"
| "application/vnd.openxmlformats-officedocument.wordprocessingml.document" => {
MimeType::Document
}
"application/zip" | "application/x-tar" | "application/x-gzip" => MimeType::Archive,
_ => MimeType::Other(mime_str.to_string()),
}
}
}
#[cfg(feature = "ssr")]
pub async fn mimetype<P>(path: P) -> Result<MimeType, AppError>
where
P: AsRef<Path>,
{
use std::fs::File;
use std::io::Read;
let mut file = File::open(&path)
.map_err(|e| AppError::GenericError(format!("Failed to open file: {}", e)))?;
let mut buffer = Vec::new();
let bytes_to_read = 4096;
buffer.resize(bytes_to_read, 0);
let bytes_read = file
.read(&mut buffer)
.map_err(|e| AppError::GenericError(format!("Failed to read file: {}", e)))?;
buffer.truncate(bytes_read);
if let Some(kind) = infer::get(&buffer) {
return Ok(MimeType::from_mime_str(kind.mime_type()));
}
Err(AppError::GenericError(
"Could not determine MIME type".to_string(),
))
}