aseprite_reader2/
error.rs

1use std::{fmt::Debug, string::FromUtf8Error};
2
3use flate2::DecompressError;
4use nom::{error::ParseError, IResult};
5
6/// Errors that can occur during parsing
7///
8/// Encountering an error could mean one (or several) of these problems:
9/// - You passed in an incomplete file (For example when loading immediately after a file change, as this means that the file could be empty or only partially saved)
10/// - You passed in an invalid file (Not representing an .aseprite file)
11/// - You are passing a file that is either too old, or too new. Make sure that you are saving/using a compatible Aseprite file.
12///
13/// If you encounter this error even though you have checked for the above problems, please report this as a bug.
14#[derive(Debug, thiserror::Error)]
15pub enum AsepriteParseError<I: std::fmt::Debug> {
16    /// Color depth was invalid
17    #[error("Found invalid color depth {0}. Expected 32/16/8.")]
18    InvalidColorDepth(u16),
19    /// An embedded string was not utf-8
20    #[error("Found invalid UTF-8 {0}")]
21    InvalidUtf8(FromUtf8Error),
22    /// An invalid layer type was found
23    #[error("Found invalid layer type {0}. Expected 0 (Normal) / 1 (Group)")]
24    InvalidLayerType(u16),
25    /// An invalid blend mode was found
26    #[error("Found invalid blend mode {0}")]
27    InvalidBlendMode(u16),
28    /// The pixel data could not be decompressed
29    #[error("Found invalid compressed data {0}")]
30    InvalidCompressedData(DecompressError),
31    /// There was not enough compressed data
32    #[error("Did not find enough compressed data. File invalid.")]
33    NotEnoughCompressedData,
34    /// An invalid cel was found while decompressing
35    #[error("Found invalid cel while decompressing")]
36    InvalidCel,
37    /// An invalid cel type was found
38    #[error("Found invalid cel type {0}")]
39    InvalidCelType(u16),
40    /// An invalid animation direction was found
41    #[error("Found invalid animation type {0}")]
42    InvalidAnimationDirection(u8),
43
44    /// A generic [`nom`] error was found
45    #[error("Nom error: {nom:?}")]
46    GenericNom {
47        /// The input causing the error
48        input: I,
49        /// The error kind reported by [`nom`]
50        nom: nom::error::ErrorKind,
51    },
52
53    /// Could not parse a layer chunk
54    #[error("An error occured while parsing a layer_chunk")]
55    InvalidLayerChunk(Box<AsepriteParseError<I>>),
56    /// Could not parse a cel chunk
57    #[error("An error occured while parsing a layer_chunk")]
58    InvalidCelChunk(Box<AsepriteParseError<I>>),
59    /// Could not parse a cel extra chunk
60    #[error("An error occured while parsing a layer_chunk")]
61    InvalidCelExtraChunk(Box<AsepriteParseError<I>>),
62    /// Could not parse a tags chunk
63    #[error("An error occured while parsing a layer_chunk")]
64    InvalidTagsChunk(Box<AsepriteParseError<I>>),
65    /// Could not parse a palette chunk
66    #[error("An error occured while parsing a layer_chunk")]
67    InvalidPaletteChunk(Box<AsepriteParseError<I>>),
68    /// Could not parse a user data chunk
69    #[error("An error occured while parsing a layer_chunk")]
70    InvalidUserDataChunk(Box<AsepriteParseError<I>>),
71    /// Could not parse a slice chunk
72    #[error("An error occured while parsing a layer_chunk")]
73    InvalidSliceChunk(Box<AsepriteParseError<I>>),
74    /// Could not parse a color profile chunk
75    #[error("An error occured while parsing a layer_chunk")]
76    InvalidColorProfileChunk(Box<AsepriteParseError<I>>),
77}
78
79impl<I: Debug> ParseError<I> for AsepriteParseError<I> {
80    fn from_error_kind(input: I, kind: nom::error::ErrorKind) -> Self {
81        AsepriteParseError::GenericNom { input, nom: kind }
82    }
83
84    fn append(_input: I, _kind: nom::error::ErrorKind, other: Self) -> Self {
85        other
86    }
87}
88
89/// Errors that can happen while loading an aseprite file
90#[derive(Debug, thiserror::Error)]
91#[non_exhaustive]
92pub enum AsepriteError {
93    /// An error occured during parsing, see [`AsepriteParseError`] for possible causes
94    ///
95    /// Either way, this cannot be recovered from
96    #[error("An error occured during parsing: {0}")]
97    Parse(String),
98    /// An IO error occured
99    #[error("An IO error occured")]
100    Io(#[from] std::io::Error),
101    /// An invalid configuration was found while decoding
102    #[error("Invalid configuration of the aseprite file")]
103    InvalidConfiguration(#[from] AsepriteInvalidError),
104}
105
106impl<'a> From<AsepriteParseError<&'a [u8]>> for AsepriteError {
107    fn from(other: AsepriteParseError<&'a [u8]>) -> Self {
108        AsepriteError::Parse(other.to_string())
109    }
110}
111
112/// An invalid configuration exists in the aseprite file
113///
114/// This should not happen with files that have not been manually edited
115#[derive(Debug, thiserror::Error)]
116#[non_exhaustive]
117pub enum AsepriteInvalidError {
118    /// An invalid layer was specified in the aseprite file
119    #[error("An invalid layer was specified")]
120    InvalidLayer(usize),
121    /// An invalid frame was specified in the frame
122    #[error("An invalid frame was specified")]
123    InvalidFrame(usize),
124    /// An invalid palette index was specified as a color
125    #[error("An invalid palette index was specified as a color")]
126    InvalidPaletteIndex(usize),
127}
128
129pub(crate) type AseParseResult<'a, R> = IResult<&'a [u8], R, AsepriteParseError<&'a [u8]>>;
130pub(crate) type AseResult<R> = std::result::Result<R, AsepriteError>;