Add pixel-transform

This commit is contained in:
2025-11-08 13:03:31 -08:00
parent e70170ee5b
commit 1329539059
11 changed files with 1433 additions and 113 deletions

View File

@@ -64,6 +64,8 @@ pub enum MimeType {
Jpg,
/// Portable Network Graphics (image/png)
Png,
/// Quite ok Image Format
Qoi,
/// Scalable Vector Graphics (image/svg+xml)
Svg,
/// Tagged Image File Format (image/tiff)
@@ -217,7 +219,9 @@ impl<'de> Deserialize<'de> for MimeType {
}
}
//
// MARK: misc
//
impl Default for MimeType {
fn default() -> Self {
@@ -243,6 +247,10 @@ impl From<&MimeType> for String {
}
}
//
// MARK: fromstr
//
impl FromStr for MimeType {
type Err = std::convert::Infallible;
@@ -251,7 +259,7 @@ impl FromStr for MimeType {
Ok(match s {
"application/octet-stream" => Self::Blob,
// MARK: Audio
// Audio
"audio/aac" => Self::Aac,
"audio/flac" => Self::Flac,
"audio/midi" | "audio/x-midi" => Self::Midi,
@@ -260,7 +268,7 @@ impl FromStr for MimeType {
"audio/wav" => Self::Wav,
"audio/webm" => Self::Weba,
// MARK: Video
// Video
"video/x-msvideo" => Self::Avi,
"video/mp4" => Self::Mp4,
"video/mpeg" => Self::Mpeg,
@@ -270,7 +278,7 @@ impl FromStr for MimeType {
"video/3gpp" => Self::ThreeGp,
"video/3gpp2" => Self::ThreeG2,
// MARK: Images
// Images
"image/apng" => Self::Apng,
"image/avif" => Self::Avif,
"image/bmp" => Self::Bmp,
@@ -281,8 +289,9 @@ impl FromStr for MimeType {
"image/svg+xml" => Self::Svg,
"image/tiff" => Self::Tiff,
"image/webp" => Self::Webp,
"image/qoi" => Self::Qoi,
// MARK: Text
// Text
"text/plain" => Self::Text,
"text/css" => Self::Css,
"text/csv" => Self::Csv,
@@ -292,11 +301,11 @@ impl FromStr for MimeType {
"application/ld+json" => Self::JsonLd,
"application/xml" | "text/xml" => Self::Xml,
// MARK: Documents
// Documents
"application/pdf" => Self::Pdf,
"application/rtf" => Self::Rtf,
// MARK: Archives
// Archives
"application/x-freearc" => Self::Arc,
"application/x-bzip" => Self::Bz,
"application/x-bzip2" => Self::Bz2,
@@ -308,14 +317,14 @@ impl FromStr for MimeType {
"application/x-tar" => Self::Tar,
"application/zip" | "application/x-zip-compressed" => Self::Zip,
// MARK: Fonts
// Fonts
"application/vnd.ms-fontobject" => Self::Eot,
"font/otf" => Self::Otf,
"font/ttf" => Self::Ttf,
"font/woff" => Self::Woff,
"font/woff2" => Self::Woff2,
// MARK: Applications
// Applications
"application/x-abiword" => Self::Abiword,
"application/vnd.amazon.ebook" => Self::Azw,
"application/x-cdf" => Self::Cda,
@@ -348,6 +357,10 @@ impl FromStr for MimeType {
}
}
//
// MARK: display
//
impl Display for MimeType {
/// Get a string representation of this mimetype.
///
@@ -368,7 +381,7 @@ impl Display for MimeType {
match self {
Self::Blob => write!(f, "application/octet-stream"),
// MARK: Audio
// Audio
Self::Aac => write!(f, "audio/aac"),
Self::Flac => write!(f, "audio/flac"),
Self::Midi => write!(f, "audio/midi"),
@@ -378,7 +391,7 @@ impl Display for MimeType {
Self::Wav => write!(f, "audio/wav"),
Self::Weba => write!(f, "audio/webm"),
// MARK: Video
// Video
Self::Avi => write!(f, "video/x-msvideo"),
Self::Mp4 => write!(f, "video/mp4"),
Self::Mpeg => write!(f, "video/mpeg"),
@@ -388,7 +401,7 @@ impl Display for MimeType {
Self::ThreeGp => write!(f, "video/3gpp"),
Self::ThreeG2 => write!(f, "video/3gpp2"),
// MARK: Images
// Images
Self::Apng => write!(f, "image/apng"),
Self::Avif => write!(f, "image/avif"),
Self::Bmp => write!(f, "image/bmp"),
@@ -399,8 +412,9 @@ impl Display for MimeType {
Self::Svg => write!(f, "image/svg+xml"),
Self::Tiff => write!(f, "image/tiff"),
Self::Webp => write!(f, "image/webp"),
Self::Qoi => write!(f, "image/qoi"),
// MARK: Text
// Text
Self::Text => write!(f, "text/plain"),
Self::Css => write!(f, "text/css"),
Self::Csv => write!(f, "text/csv"),
@@ -410,11 +424,11 @@ impl Display for MimeType {
Self::JsonLd => write!(f, "application/ld+json"),
Self::Xml => write!(f, "application/xml"),
// MARK: Documents
// Documents
Self::Pdf => write!(f, "application/pdf"),
Self::Rtf => write!(f, "application/rtf"),
// MARK: Archives
// Archives
Self::Arc => write!(f, "application/x-freearc"),
Self::Bz => write!(f, "application/x-bzip"),
Self::Bz2 => write!(f, "application/x-bzip2"),
@@ -426,14 +440,14 @@ impl Display for MimeType {
Self::Tar => write!(f, "application/x-tar"),
Self::Zip => write!(f, "application/zip"),
// MARK: Fonts
// Fonts
Self::Eot => write!(f, "application/vnd.ms-fontobject"),
Self::Otf => write!(f, "font/otf"),
Self::Ttf => write!(f, "font/ttf"),
Self::Woff => write!(f, "font/woff"),
Self::Woff2 => write!(f, "font/woff2"),
// MARK: Applications
// Applications
Self::Abiword => write!(f, "application/x-abiword"),
Self::Azw => write!(f, "application/vnd.amazon.ebook"),
Self::Cda => write!(f, "application/x-cdf"),
@@ -471,13 +485,15 @@ impl Display for MimeType {
}
impl MimeType {
// Must match `From<String>` above
//
// MARK: from extension
//
/// Try to guess a file's mime type from its extension.
/// `ext` should NOT start with a dot.
pub fn from_extension(ext: &str) -> Option<Self> {
Some(match ext {
// MARK: Audio
// Audio
"aac" => Self::Aac,
"flac" => Self::Flac,
"mid" | "midi" => Self::Midi,
@@ -487,7 +503,7 @@ impl MimeType {
"wav" => Self::Wav,
"weba" => Self::Weba,
// MARK: Video
// Video
"avi" => Self::Avi,
"mp4" => Self::Mp4,
"mpeg" => Self::Mpeg,
@@ -497,7 +513,7 @@ impl MimeType {
"3gp" => Self::ThreeGp,
"3g2" => Self::ThreeG2,
// MARK: Images
// Images
"apng" => Self::Apng,
"avif" => Self::Avif,
"bmp" => Self::Bmp,
@@ -508,8 +524,9 @@ impl MimeType {
"svg" => Self::Svg,
"tif" | "tiff" => Self::Tiff,
"webp" => Self::Webp,
"qoi" => Self::Qoi,
// MARK: Text
// Text
"txt" => Self::Text,
"css" => Self::Css,
"csv" => Self::Csv,
@@ -519,11 +536,11 @@ impl MimeType {
"jsonld" => Self::JsonLd,
"xml" => Self::Xml,
// MARK: Documents
// Documents
"pdf" => Self::Pdf,
"rtf" => Self::Rtf,
// MARK: Archives
// Archives
"arc" => Self::Arc,
"bz" => Self::Bz,
"bz2" => Self::Bz2,
@@ -535,14 +552,14 @@ impl MimeType {
"tar" => Self::Tar,
"zip" => Self::Zip,
// MARK: Fonts
// Fonts
"eot" => Self::Eot,
"otf" => Self::Otf,
"ttf" => Self::Ttf,
"woff" => Self::Woff,
"woff2" => Self::Woff2,
// MARK: Applications
// Applications
"abw" => Self::Abiword,
"azw" => Self::Azw,
"cda" => Self::Cda,
@@ -569,100 +586,105 @@ impl MimeType {
})
}
//
// MARK: to extension
//
/// Get the extension we use for files with this type.
/// Includes a dot. Might be the empty string.
pub fn extension(&self) -> &str {
/// Never includes a dot.
pub fn extension(&self) -> Option<&'static str> {
match self {
Self::Blob => "",
Self::Other(_) => "",
Self::Blob => None,
Self::Other(_) => None,
// MARK: Audio
Self::Aac => ".aac",
Self::Flac => ".flac",
Self::Midi => ".midi",
Self::Mp3 => ".mp3",
Self::Oga => ".oga",
Self::Opus => ".opus",
Self::Wav => ".wav",
Self::Weba => ".weba",
// Audio
Self::Aac => Some("aac"),
Self::Flac => Some("flac"),
Self::Midi => Some("midi"),
Self::Mp3 => Some("mp3"),
Self::Oga => Some("oga"),
Self::Opus => Some("opus"),
Self::Wav => Some("wav"),
Self::Weba => Some("weba"),
// MARK: Video
Self::Avi => ".avi",
Self::Mp4 => ".mp4",
Self::Mpeg => ".mpeg",
Self::Ogv => ".ogv",
Self::Ts => ".ts",
Self::WebmVideo => ".webm",
Self::ThreeGp => ".3gp",
Self::ThreeG2 => ".3g2",
// Video
Self::Avi => Some("avi"),
Self::Mp4 => Some("mp4"),
Self::Mpeg => Some("mpeg"),
Self::Ogv => Some("ogv"),
Self::Ts => Some("ts"),
Self::WebmVideo => Some("webm"),
Self::ThreeGp => Some("3gp"),
Self::ThreeG2 => Some("3g2"),
// MARK: Images
Self::Apng => ".apng",
Self::Avif => ".avif",
Self::Bmp => ".bmp",
Self::Gif => ".gif",
Self::Ico => ".ico",
Self::Jpg => ".jpg",
Self::Png => ".png",
Self::Svg => ".svg",
Self::Tiff => ".tiff",
Self::Webp => ".webp",
// Images
Self::Apng => Some("apng"),
Self::Avif => Some("avif"),
Self::Bmp => Some("bmp"),
Self::Gif => Some("gif"),
Self::Ico => Some("ico"),
Self::Jpg => Some("jpg"),
Self::Png => Some("png"),
Self::Svg => Some("svg"),
Self::Tiff => Some("tiff"),
Self::Webp => Some("webp"),
Self::Qoi => Some("qoi"),
// MARK: Text
Self::Text => ".txt",
Self::Css => ".css",
Self::Csv => ".csv",
Self::Html => ".html",
Self::Javascript => ".js",
Self::Json => ".json",
Self::JsonLd => ".jsonld",
Self::Xml => ".xml",
// Text
Self::Text => Some("txt"),
Self::Css => Some("css"),
Self::Csv => Some("csv"),
Self::Html => Some("html"),
Self::Javascript => Some("js"),
Self::Json => Some("json"),
Self::JsonLd => Some("jsonld"),
Self::Xml => Some("xml"),
// MARK: Documents
Self::Pdf => ".pdf",
Self::Rtf => ".rtf",
// Documents
Self::Pdf => Some("pdf"),
Self::Rtf => Some("rtf"),
// MARK: Archives
Self::Arc => ".arc",
Self::Bz => ".bz",
Self::Bz2 => ".bz2",
Self::Gz => ".gz",
Self::Jar => ".jar",
Self::Ogg => ".ogx",
Self::Rar => ".rar",
Self::SevenZ => ".7z",
Self::Tar => ".tar",
Self::Zip => ".zip",
// Archives
Self::Arc => Some("arc"),
Self::Bz => Some("bz"),
Self::Bz2 => Some("bz2"),
Self::Gz => Some("gz"),
Self::Jar => Some("jar"),
Self::Ogg => Some("ogx"),
Self::Rar => Some("rar"),
Self::SevenZ => Some("7z"),
Self::Tar => Some("tar"),
Self::Zip => Some("zip"),
// MARK: Fonts
Self::Eot => ".eot",
Self::Otf => ".otf",
Self::Ttf => ".ttf",
Self::Woff => ".woff",
Self::Woff2 => ".woff2",
// Fonts
Self::Eot => Some("eot"),
Self::Otf => Some("otf"),
Self::Ttf => Some("ttf"),
Self::Woff => Some("woff"),
Self::Woff2 => Some("woff2"),
// MARK: Applications
Self::Abiword => ".abw",
Self::Azw => ".azw",
Self::Cda => ".cda",
Self::Csh => ".csh",
Self::Doc => ".doc",
Self::Docx => ".docx",
Self::Epub => ".epub",
Self::Ics => ".ics",
Self::Mpkg => ".mpkg",
Self::Odp => ".odp",
Self::Ods => ".ods",
Self::Odt => ".odt",
Self::Php => ".php",
Self::Ppt => ".ppt",
Self::Pptx => ".pptx",
Self::Sh => ".sh",
Self::Vsd => ".vsd",
Self::Xhtml => ".xhtml",
Self::Xls => ".xls",
Self::Xlsx => ".xlsx",
Self::Xul => ".xul",
// Applications
Self::Abiword => Some("abw"),
Self::Azw => Some("azw"),
Self::Cda => Some("cda"),
Self::Csh => Some("csh"),
Self::Doc => Some("doc"),
Self::Docx => Some("docx"),
Self::Epub => Some("epub"),
Self::Ics => Some("ics"),
Self::Mpkg => Some("mpkg"),
Self::Odp => Some("odp"),
Self::Ods => Some("ods"),
Self::Odt => Some("odt"),
Self::Php => Some("php"),
Self::Ppt => Some("ppt"),
Self::Pptx => Some("pptx"),
Self::Sh => Some("sh"),
Self::Vsd => Some("vsd"),
Self::Xhtml => Some("xhtml"),
Self::Xls => Some("xls"),
Self::Xlsx => Some("xlsx"),
Self::Xul => Some("xul"),
}
}
}