1#[cfg(feature = "ffi")]
2use sawp_ffi::GenerateFFI;
3
4use std::num::NonZeroUsize;
5
6use nom::error::ErrorKind as NomErrorKind;
8use nom::Needed as NomNeeded;
9
10pub type Result<T> = std::result::Result<T, Error>;
12
13pub type NomError<I> = nom::error::Error<I>;
15
16#[derive(Debug, PartialEq, Eq)]
24#[cfg_attr(feature = "ffi", derive(GenerateFFI))]
25#[cfg_attr(feature = "ffi", sawp_ffi(prefix = "sawp"))]
26pub struct Error {
27 pub kind: ErrorKind,
28}
29
30impl Error {
31 pub fn new(kind: ErrorKind) -> Self {
32 Self { kind }
33 }
34
35 pub fn incomplete_needed(size: usize) -> Self {
37 Error::new(ErrorKind::Incomplete(
38 NonZeroUsize::new(size)
39 .map(Needed::Size)
40 .unwrap_or(Needed::Unknown),
41 ))
42 }
43
44 pub fn incomplete() -> Self {
46 Error::new(ErrorKind::Incomplete(Needed::Unknown))
47 }
48
49 #[cfg(feature = "verbose")]
51 pub fn parse(msg: Option<String>) -> Self {
52 Error::new(ErrorKind::ParseError(msg))
53 }
54
55 #[cfg(not(feature = "verbose"))]
57 pub fn parse(_msg: Option<String>) -> Self {
58 Error::new(ErrorKind::ParseError(None))
59 }
60}
61
62impl From<ErrorKind> for Error {
63 fn from(kind: ErrorKind) -> Self {
64 Self::new(kind)
65 }
66}
67
68#[derive(Debug, PartialEq, Eq)]
73pub enum Needed {
74 Unknown,
75 Size(NonZeroUsize),
76}
77
78#[derive(Debug, PartialEq, Eq)]
80#[non_exhaustive]
81#[cfg_attr(feature = "ffi", derive(GenerateFFI))]
82#[cfg_attr(feature = "ffi", sawp_ffi(type_only, prefix = "sawp"))]
83pub enum ErrorKind {
84 Unimplemented,
86 InvalidData,
97 ParseError(Option<String>),
99 Incomplete(Needed),
104}
105
106impl From<NomErrorKind> for ErrorKind {
107 #[cfg(feature = "verbose")]
108 fn from(kind: NomErrorKind) -> Self {
109 Self::ParseError(Some(format!("{:?}", kind)))
110 }
111
112 #[cfg(not(feature = "verbose"))]
113 fn from(_kind: NomErrorKind) -> Self {
114 Self::ParseError(None)
115 }
116}
117
118impl<I: std::fmt::Debug> From<nom::Err<NomError<I>>> for Error {
119 fn from(nom_err: nom::Err<NomError<I>>) -> Self {
120 match nom_err {
121 nom::Err::Error(err) | nom::Err::Failure(err) => Error::new(err.code.into()),
122 nom::Err::Incomplete(needed) => match needed {
123 NomNeeded::Unknown => Error::incomplete(),
124 NomNeeded::Size(size) => Error::incomplete_needed(size.into()),
125 },
126 }
127 }
128}
129
130impl std::fmt::Display for Error {
131 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
132 match &self.kind {
133 ErrorKind::Unimplemented => write!(f, "Unimplemented feature"),
134 ErrorKind::InvalidData => write!(f, "Encountered invalid data"),
135 ErrorKind::ParseError(err) if err.is_some() => {
136 write!(f, "Parsing error: {}", err.clone().unwrap())
137 }
138 ErrorKind::ParseError(_) => write!(f, "Parsing error"),
139 ErrorKind::Incomplete(Needed::Unknown) => write!(f, "More bytes required to parse"),
140 ErrorKind::Incomplete(Needed::Size(n)) => {
141 write!(f, "{} more bytes required to parse", n)
142 }
143 }
144 }
145}
146
147impl std::error::Error for Error {}
148
149impl<I: std::fmt::Debug> From<NomError<I>> for Error {
150 fn from(nom_err: NomError<I>) -> Self {
151 Error::new(nom_err.code.into())
152 }
153}