Skip to main content

codex_utils_image/
error.rs

1use image::ImageError;
2use image::ImageFormat;
3use std::path::PathBuf;
4use thiserror::Error;
5
6#[derive(Debug, Error)]
7pub enum ImageProcessingError {
8    #[error("failed to read image at {path}: {source}")]
9    Read {
10        path: PathBuf,
11        #[source]
12        source: std::io::Error,
13    },
14    #[error("failed to decode image at {path}: {source}")]
15    Decode {
16        path: PathBuf,
17        #[source]
18        source: image::ImageError,
19    },
20    #[error("failed to encode image as {format:?}: {source}")]
21    Encode {
22        format: ImageFormat,
23        #[source]
24        source: image::ImageError,
25    },
26    #[error("unsupported image `{mime}`")]
27    UnsupportedImageFormat { mime: String },
28    #[error("invalid image data URL: {reason}")]
29    InvalidDataUrl { reason: String },
30    #[error("image {representation} is too large ({size} bytes; max {max} bytes)")]
31    ImageTooLarge {
32        representation: &'static str,
33        size: usize,
34        max: usize,
35    },
36}
37
38impl ImageProcessingError {
39    pub fn decode_error(path: &std::path::Path, source: image::ImageError) -> Self {
40        if matches!(source, ImageError::Decoding(_)) {
41            return ImageProcessingError::Decode {
42                path: path.to_path_buf(),
43                source,
44            };
45        }
46
47        let mime = mime_guess::from_path(path)
48            .first()
49            .map(|mime_guess| mime_guess.essence_str().to_owned())
50            .unwrap_or_else(|| "unknown".to_string());
51        ImageProcessingError::UnsupportedImageFormat { mime }
52    }
53
54    pub fn is_invalid_image(&self) -> bool {
55        matches!(
56            self,
57            ImageProcessingError::Decode {
58                source: ImageError::Decoding(_),
59                ..
60            }
61        )
62    }
63}