pub fn extension_to_mime(extension: &str) -> Option<&'static str> {
Some(match extension.to_lowercase().as_str() {
"jpg" | "jpeg" => "image/jpeg",
"png" => "image/png",
"gif" => "image/gif",
"psd" => "image/vnd.adobe.photoshop",
"tiff" | "tif" => "image/tiff",
"svg" => "image/svg+xml",
"ico" => "image/x-icon",
"bmp" => "image/bmp",
"webp" => "image/webp",
"jxl" => "image/jxl",
"dng" => "image/x-adobe-dng",
"heic" => "image/heic",
"heif" => "image/heif",
"mp2" | "mpa" | "mpe" | "mpeg" | "mpg" | "mpv2" => "video/mpeg",
"mp4" => "video/mp4",
"avi" => "video/avi",
"avif" => "image/avif",
"mov" | "qt" => "video/quicktime",
"m4a" => "audio/mp4",
"mid" | "rmi" => "audio/mid",
"mp3" => "audio/mpeg",
"flac" => "audio/flac",
"wav" => "audio/wav",
"aif" | "aifc" | "aiff" => "audio/aiff",
"ogg" => "audio/ogg",
"pdf" => "application/pdf",
"ai" => "application/postscript",
"arw" => "image/x-sony-arw",
"nef" => "image/x-nikon-nef",
"c2pa" | "application/x-c2pa-manifest-store" | "application/c2pa" => "application/c2pa",
#[cfg(feature = "unstable_structured_text")]
"md" | "markdown" => "text/markdown",
#[cfg(feature = "unstable_structured_text")]
"yaml" | "yml" => "application/yaml",
#[cfg(feature = "unstable_structured_text")]
"toml" => "application/toml",
#[cfg(feature = "unstable_structured_text")]
"css" => "text/css",
#[cfg(feature = "unstable_structured_text")]
"js" | "mjs" => "text/javascript",
#[cfg(feature = "unstable_structured_text")]
"py" => "text/x-python",
#[cfg(feature = "unstable_structured_text")]
"sql" => "application/sql",
#[cfg(feature = "unstable_structured_text")]
"tex" => "application/x-tex",
#[cfg(feature = "unstable_structured_text")]
"vtt" => "text/vtt",
#[cfg(feature = "unstable_structured_text")]
"rss" => "application/rss+xml",
#[cfg(feature = "unstable_structured_text")]
"atom" => "application/atom+xml",
#[cfg(feature = "unstable_plain_text")]
"txt" => "text/plain",
_ => return None,
})
}
pub(crate) fn normalize_format(format: &str) -> String {
format.trim().to_lowercase()
}
pub fn format_to_mime(format: &str) -> String {
let format = normalize_format(format);
match extension_to_mime(&format) {
Some(mime) => mime.to_string(),
None => format,
}
}
#[allow(unused)]
pub fn format_to_extension(format: &str) -> Option<&'static str> {
Some(match format.to_lowercase().as_str() {
"jpg" | "jpeg" | "image/jpeg" => "jpg",
"png" | "image/png" => "png",
"gif" | "image/gif" => "gif",
"psd" | "image/vnd.adobe.photoshop" => "psd",
"tiff" | "tif" | "image/tiff" => "tiff",
"svg" | "image/svg+xml" => "svg",
"ico" | "image/x-icon" => "ico",
"bmp" | "image/bmp" => "bmp",
"webp" | "image/webp" => "webp",
"dng" | "image/dng" => "dng",
"heic" | "image/heic" => "heic",
"heif" | "image/heif" => "heif",
"mp2" | "mpa" | "mpe" | "mpeg" | "mpg" | "mpv2" | "video/mpeg" => "mp2",
"mp4" | "video/mp4" => "mp4",
"avif" | "image/avif" => "avif",
"avi" | "video/avi" => "avi",
"mov" | "qt" | "video/quicktime" => "mov",
"m4a" | "audio/mp4" => "m4a",
"mid" | "rmi" | "audio/mid" => "mid",
"mp3" | "audio/mpeg" => "mp3",
"flac" | "audio/flac" => "flac",
"wav" | "audio/wav" | "audio/wave" | "audio.vnd.wave" => "wav",
"aif" | "aifc" | "aiff" | "audio/aiff" => "aif",
"ogg" | "audio/ogg" => "ogg",
"pdf" | "application/pdf" => "pdf",
"ai" | "application/postscript" => "ai",
"arw" | "image/x-sony-arw" => "arw",
"nef" | "image/x-nikon-nef" => "nef",
"c2pa" | "application/x-c2pa-manifest-store" | "application/c2pa" => "c2pa",
_ => return None,
})
}
pub fn format_from_path<P: AsRef<std::path::Path>>(path: P) -> Option<String> {
path.as_ref().extension().map(|ext| {
crate::utils::mime::format_to_mime(ext.to_string_lossy().to_lowercase().as_ref())
})
}
pub fn mime_from_path<P: AsRef<std::path::Path>>(path: P) -> Option<String> {
path.as_ref()
.extension()
.and_then(|ext| extension_to_mime(&ext.to_string_lossy()))
.map(|mime| mime.to_owned())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_format_to_mime_uppercase() {
assert_eq!(format_to_mime("IMAGE/JPEG"), "image/jpeg");
assert_eq!(format_to_mime("Image/Png"), "image/png");
assert_eq!(format_to_mime("JPG"), "image/jpeg");
assert_eq!(format_to_mime("PNG"), "image/png");
}
#[test]
fn test_format_to_mime_lowercase_unchanged() {
assert_eq!(format_to_mime("image/jpeg"), "image/jpeg");
assert_eq!(format_to_mime("jpg"), "image/jpeg");
assert_eq!(format_to_mime("image/svg+xml"), "image/svg+xml");
}
#[test]
fn test_format_to_mime_trims_whitespace() {
assert_eq!(format_to_mime(" image/jpeg "), "image/jpeg");
assert_eq!(format_to_mime("\timage/png\n"), "image/png");
assert_eq!(format_to_mime(" JPG "), "image/jpeg");
assert_eq!(format_to_mime(" image/svg+xml "), "image/svg+xml");
}
}