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
use nom::error::{ParseError, FromExternalError};
use crate::{Container, Marker};

#[derive(Debug, thiserror::Error)]
pub enum UbjsonError<'a> {
    #[error("Conversion failed, expected {expected:?}, got {actual:?}")]
    ConversionFailed {
        expected: Container<'a>,
        actual: Container<'a>,
    },
    #[error("Encountered an unexpected Marker: expected {expected:?}, got {actual:?}")]
    UnexpectedMarker {
        expected: Marker,
        actual: Marker,
    },
    #[error("Extraneous marker detected without an associated start: {0:?}")]
    ExtraMarker(Marker),
    #[error("Couldn't parse data length, missing or different type")]
    LengthParseError,
    #[error(transparent)]
    Utf8Error(#[from] std::str::Utf8Error),
    #[error("{0:?}")]
    ParseError(nom::error::VerboseError<&'a [u8]>),
    #[error(transparent)]
    NumericConversionError(#[from] std::num::TryFromIntError),
    #[error(transparent)]
    MarkerEnumConversionError(#[from] num_enum::TryFromPrimitiveError<Marker>),
    #[error(transparent)]
    Other(#[from] anyhow::Error),
}

impl<'a> ParseError<&'a [u8]> for UbjsonError<'a> {
    fn from_error_kind(input: &'a [u8], kind: nom::error::ErrorKind) -> Self {
        Self::ParseError(nom::error::VerboseError::from_error_kind(input, kind))
    }

    fn append(input: &'a [u8], kind: nom::error::ErrorKind, other: Self) -> Self {
        match other {
            Self::ParseError(error) => Self::ParseError(nom::error::VerboseError::append(input, kind, error)),
            other => other
        }
    }
}

impl<I: std::fmt::Debug, E: std::error::Error + Send + Sync + 'static> FromExternalError<I, E> for UbjsonError<'_> where Self: From<E> {
    fn from_external_error(_: I, _: nom::error::ErrorKind, e: E) -> Self {
        e.into()
    }
}

pub type UbjsonResult<'a, T> = Result<T, UbjsonError<'a>>;