Skip to main content

valo_codec/
error.rs

1//! Why a decode did not produce an image.
2use std::fmt;
3use valo::ImageError;
4
5/// DecodeError is why a decode did not produce an image.
6#[derive(Clone, Debug, PartialEq, Eq)]
7pub enum DecodeError {
8    /// NoDecoder means the loader was built with no decoders at all.
9    NoDecoder,
10
11    /// Unsupported means every decoder declined the bytes; each entry says why.
12    Unsupported(Vec<Declined>),
13
14    /// InvalidData means a decoder recognised the format and found the bytes damaged.
15    InvalidData(String),
16
17    /// LimitExceeded means a [`DecodeLimits`](crate::DecodeLimits) bound was hit; the text names
18    /// which one.
19    LimitExceeded(&'static str),
20
21    /// Failed means a decoder or the platform failed without proving the bytes invalid — an
22    /// allocation failure, a system API declining.
23    Failed(String),
24
25    /// Image means the decoded frame could not become an image on this device.
26    Image(ImageError),
27
28    /// Closed means the loader was dropped before the work ran.
29    Closed,
30}
31
32/// Declined records one decoder passing on an image.
33#[derive(Clone, Debug, PartialEq, Eq)]
34pub struct Declined {
35    /// `decoder` is the [`Decoder::name`](crate::Decoder::name).
36    pub decoder: &'static str,
37
38    /// `reason` is that decoder's own account.
39    pub reason: String,
40}
41
42impl From<ImageError> for DecodeError {
43    fn from(error: ImageError) -> Self {
44        Self::Image(error)
45    }
46}
47
48impl fmt::Display for DecodeError {
49    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50        match self {
51            Self::NoDecoder => f.write_str("no image decoder is registered"),
52            Self::Unsupported(declined) => {
53                f.write_str("no registered decoder reads this image")?;
54                for entry in declined {
55                    write!(f, "; {}: {}", entry.decoder, entry.reason)?;
56                }
57                Ok(())
58            }
59            Self::InvalidData(reason) => write!(f, "damaged image: {reason}"),
60            Self::LimitExceeded(limit) => write!(f, "decode limit exceeded: {limit}"),
61            Self::Failed(reason) => write!(f, "decode failed: {reason}"),
62            Self::Image(error) => write!(f, "image creation failed: {error}"),
63            Self::Closed => f.write_str("the image loader was closed before decoding"),
64        }
65    }
66}
67
68impl std::error::Error for DecodeError {}