use std::path::Path;
pub const DEFAULT_MIME_TYPE: &str = "application/octet-stream";
pub fn guess_mime_type<P: AsRef<Path>>(path: P) -> String {
mime_guess::from_path(path.as_ref())
.first_or_octet_stream()
.to_string()
}
pub fn guess_from_extension(extension: &str) -> String {
let ext = extension.trim_start_matches('.');
mime_guess::from_ext(ext)
.first_or_octet_stream()
.to_string()
}
pub fn is_valid_mime_type(mime_type: &str) -> bool {
mime_type.parse::<mime::Mime>().is_ok()
}
pub fn normalize_mime_type(mime_type: &str) -> String {
mime_type
.parse::<mime::Mime>()
.map(|m| format!("{}/{}", m.type_(), m.subtype()))
.unwrap_or_else(|_| DEFAULT_MIME_TYPE.to_string())
}
pub fn extract_from_content_type(content_type: &str) -> String {
content_type
.split(';')
.next()
.unwrap_or(DEFAULT_MIME_TYPE)
.trim()
.to_string()
}
pub fn is_text_mime_type(mime_type: &str) -> bool {
if let Ok(mime) = mime_type.parse::<mime::Mime>() {
let type_str = mime.type_().as_str();
let subtype_str = mime.subtype().as_str();
return type_str == "text"
|| (type_str == "application" && matches!(
subtype_str,
"json" | "xml" | "javascript" | "x-yaml" | "yaml"
));
}
false
}
pub fn is_image_mime_type(mime_type: &str) -> bool {
mime_type
.parse::<mime::Mime>()
.map(|m| m.type_() == "image")
.unwrap_or(false)
}
pub fn is_video_mime_type(mime_type: &str) -> bool {
mime_type
.parse::<mime::Mime>()
.map(|m| m.type_() == "video")
.unwrap_or(false)
}
pub fn is_audio_mime_type(mime_type: &str) -> bool {
mime_type
.parse::<mime::Mime>()
.map(|m| m.type_() == "audio")
.unwrap_or(false)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_guess_mime_type() {
assert_eq!(guess_mime_type(Path::new("file.pdf")), "application/pdf");
assert_eq!(guess_mime_type(Path::new("image.png")), "image/png");
assert_eq!(guess_mime_type(Path::new("data.json")), "application/json");
assert_eq!(guess_mime_type(Path::new("unknown.xyz123")), DEFAULT_MIME_TYPE);
}
#[test]
fn test_guess_from_extension() {
assert_eq!(guess_from_extension("pdf"), "application/pdf");
assert_eq!(guess_from_extension(".pdf"), "application/pdf");
assert_eq!(guess_from_extension("json"), "application/json");
assert_eq!(guess_from_extension("unknown"), DEFAULT_MIME_TYPE);
}
#[test]
fn test_is_valid_mime_type() {
assert!(is_valid_mime_type("image/png"));
assert!(is_valid_mime_type("application/json"));
assert!(is_valid_mime_type("text/plain"));
assert!(!is_valid_mime_type("invalid"));
assert!(!is_valid_mime_type(""));
}
#[test]
fn test_normalize_mime_type() {
assert_eq!(normalize_mime_type("IMAGE/PNG"), "image/png");
assert_eq!(normalize_mime_type("text/html; charset=utf-8"), "text/html");
assert_eq!(normalize_mime_type("application/json"), "application/json");
assert_eq!(normalize_mime_type("invalid"), DEFAULT_MIME_TYPE);
}
#[test]
fn test_extract_from_content_type() {
assert_eq!(
extract_from_content_type("text/html; charset=utf-8"),
"text/html"
);
assert_eq!(
extract_from_content_type("application/json"),
"application/json"
);
assert_eq!(
extract_from_content_type("multipart/form-data; boundary=----WebKitFormBoundary"),
"multipart/form-data"
);
}
#[test]
fn test_is_text_mime_type() {
assert!(is_text_mime_type("text/plain"));
assert!(is_text_mime_type("text/html"));
assert!(is_text_mime_type("application/json"));
assert!(is_text_mime_type("application/xml"));
assert!(!is_text_mime_type("image/png"));
assert!(!is_text_mime_type("video/mp4"));
}
#[test]
fn test_is_image_mime_type() {
assert!(is_image_mime_type("image/png"));
assert!(is_image_mime_type("image/jpeg"));
assert!(is_image_mime_type("image/gif"));
assert!(!is_image_mime_type("text/plain"));
assert!(!is_image_mime_type("video/mp4"));
}
#[test]
fn test_is_video_mime_type() {
assert!(is_video_mime_type("video/mp4"));
assert!(is_video_mime_type("video/webm"));
assert!(!is_video_mime_type("image/png"));
assert!(!is_video_mime_type("text/plain"));
}
#[test]
fn test_is_audio_mime_type() {
assert!(is_audio_mime_type("audio/mpeg"));
assert!(is_audio_mime_type("audio/wav"));
assert!(!is_audio_mime_type("video/mp4"));
assert!(!is_audio_mime_type("text/plain"));
}
#[test]
fn test_modern_extensions() {
assert_eq!(guess_from_extension("webp"), "image/webp");
assert_eq!(guess_from_extension("wasm"), "application/wasm");
assert_eq!(guess_from_extension("opus"), "audio/ogg");
assert_eq!(guess_from_extension("webm"), "video/webm");
}
}