#[derive( Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Deserialize, serde::Serialize, )] pub(crate) enum ImageFormat { #[serde(rename = "avif")] Avif, #[serde(rename = "png")] Png, #[serde(rename = "jpeg")] Jpeg, #[serde(rename = "jxl")] Jxl, #[serde(rename = "webp")] Webp, } #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Deserialize)] pub(crate) struct ImageInput { pub(crate) format: ImageFormat, pub(crate) needs_reorient: bool, } #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Deserialize)] pub(crate) struct ImageOutput { pub(crate) format: ImageFormat, pub(crate) needs_transcode: bool, } impl ImageInput { pub(crate) const fn build_output(self, prescribed: Option) -> ImageOutput { if let Some(prescribed) = prescribed { let needs_transcode = self.needs_reorient || !self.format.const_eq(prescribed); return ImageOutput { format: prescribed, needs_transcode, }; } ImageOutput { format: self.format, needs_transcode: self.needs_reorient, } } } impl ImageFormat { pub(super) const fn const_eq(self, rhs: Self) -> bool { match (self, rhs) { (Self::Avif, Self::Avif) | (Self::Jpeg, Self::Jpeg) | (Self::Jxl, Self::Jxl) | (Self::Png, Self::Png) | (Self::Webp, Self::Webp) => true, (Self::Avif, _) | (Self::Jpeg, _) | (Self::Jxl, _) | (Self::Png, _) | (Self::Webp, _) => false, } } pub(super) const fn file_extension(self) -> &'static str { match self { Self::Avif => ".avif", Self::Jpeg => ".jpeg", Self::Jxl => ".jxl", Self::Png => ".png", Self::Webp => ".webp", } } pub(crate) const fn magick_format(self) -> &'static str { match self { Self::Avif => "AVIF", Self::Jpeg => "JPEG", Self::Jxl => "JXL", Self::Png => "PNG", Self::Webp => "Webp", } } pub(super) fn media_type(self) -> mime::Mime { match self { Self::Avif => super::mimes::image_avif(), Self::Jpeg => mime::IMAGE_JPEG, Self::Jxl => super::mimes::image_jxl(), Self::Png => mime::IMAGE_PNG, Self::Webp => super::mimes::image_webp(), } } }