Skip to main content

aseprite/
error.rs

1use std::fmt;
2use std::io;
3
4/// Errors that can occur when reading or writing Aseprite files.
5#[derive(Debug)]
6pub enum AsepriteError {
7    /// An I/O error occurred during reading or writing.
8    Io(io::Error),
9    /// The file does not start with the Aseprite magic number `0xA5E0`.
10    InvalidMagic,
11    /// The file uses a color depth that is not 8, 16, or 32 bits.
12    UnsupportedColorDepth(u16),
13    /// A frame index is out of bounds.
14    FrameOutOfBounds(usize),
15    /// Pixel data buffer size does not match the expected size for the given dimensions and color mode.
16    PixelSizeMismatch { expected: usize, actual: usize },
17    /// A tag's frame range extends beyond the number of frames in the file.
18    InvalidFrameRange,
19    /// Indexed color mode requires a palette, but none was set.
20    MissingPalette,
21    /// A linked cel references a source frame that does not contain a cel on the same layer.
22    LinkedCelNotFound { layer: usize, source_frame: usize },
23    /// A chunk's declared size is invalid.
24    InvalidChunkSize,
25    /// A chunk or property type ID is not recognized.
26    UnsupportedChunkType(u16),
27    /// A value exceeds the format's limit (e.g., more than 256 palette entries).
28    FormatLimitExceeded { field: &'static str, value: usize, max: usize },
29}
30
31impl fmt::Display for AsepriteError {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        match self {
34            Self::Io(e) => write!(f, "I/O error: {e}"),
35            Self::InvalidMagic => write!(f, "invalid magic number (expected 0xA5E0)"),
36            Self::UnsupportedColorDepth(d) => write!(f, "unsupported color depth: {d}"),
37            Self::FrameOutOfBounds(i) => write!(f, "frame index {i} out of bounds"),
38            Self::PixelSizeMismatch { expected, actual } => {
39                write!(f, "pixel data size mismatch: expected {expected}, got {actual}")
40            }
41            Self::InvalidFrameRange => write!(f, "invalid frame range"),
42            Self::MissingPalette => write!(f, "indexed color mode requires a palette"),
43            Self::LinkedCelNotFound { layer, source_frame } => {
44                write!(f, "linked cel not found: layer {layer}, source frame {source_frame}")
45            }
46            Self::InvalidChunkSize => write!(f, "invalid chunk size"),
47            Self::UnsupportedChunkType(t) => write!(f, "unsupported chunk type: 0x{t:04X}"),
48            Self::FormatLimitExceeded { field, value, max } => {
49                write!(f, "format limit exceeded for {field}: {value} > {max}")
50            }
51        }
52    }
53}
54
55impl std::error::Error for AsepriteError {
56    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
57        match self {
58            Self::Io(e) => Some(e),
59            _ => None,
60        }
61    }
62}
63
64impl From<io::Error> for AsepriteError {
65    fn from(e: io::Error) -> Self {
66        Self::Io(e)
67    }
68}