1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use std::str::Utf8Error;

use nom::IResult;

use super::{
    palette::PaletteError,
    scalars::{Dword, Word},
};

#[derive(Debug, strum::Display)]
pub enum ParseError<'a> {
    /// This variant is used when the conversion between
    /// DWORD (u32) to usize fails. The only way this can
    /// happen is when running this code on a 16-bit system.
    DwordToUsize(Dword),
    /// This variant is used when the frame size is <4
    InvalidFrameSize(Dword),
    /// This variant is used when the chunk size is <4
    InvalidChunkSize(Dword),
    /// This variant is used when a string does not contain
    /// valid UTF-8 data and `str::from_utf8` returned an error.
    Utf8Error(Utf8Error),
    /// The uses index colors but the palette could not be
    /// generated due to errors in the palette chunks.
    PaletteError(PaletteError),
    /// The range of frame indices was invalid (from > to)
    InvalidFrameRange(Word, Word),
    /// This variant is used when a layer index is out
    /// of bounds (layer_index >= layer_count)
    LayerIndexOutOfBounds,
    /// This variant is used when a unsupported property
    /// type is found in the user data.
    InvalidPropertyType(Word),
    /// This variant is used when the nom combinators return
    /// an error.
    Nom(nom::error::Error<&'a [u8]>),
}

impl<'a> std::error::Error for ParseError<'a> {}

impl<'a> nom::error::ParseError<&'a [u8]> for ParseError<'a> {
    fn from_error_kind(input: &'a [u8], kind: nom::error::ErrorKind) -> Self {
        Self::Nom(nom::error::Error::from_error_kind(input, kind))
    }
    fn append(_input: &[u8], _kind: nom::error::ErrorKind, other: Self) -> Self {
        other
    }
}

impl<'a> nom::error::FromExternalError<&'a [u8], Utf8Error> for ParseError<'a> {
    fn from_external_error(_input: &'a [u8], _kind: nom::error::ErrorKind, e: Utf8Error) -> Self {
        ParseError::Utf8Error(e)
    }
}

pub type ParseResult<'a, O> = IResult<&'a [u8], O, ParseError<'a>>;