1use std::num::TryFromIntError;
4
5use nom::error::ErrorKind;
6use nom::error::ParseError;
7
8pub type S2ProtoResult<I, O> = Result<(I, O), S2ProtocolError>;
10
11#[derive(thiserror::Error, Debug)]
12pub enum S2ProtocolError {
13 #[error("MPQ Error")]
15 MPQ(#[from] nom_mpq::MPQParserError),
16 #[error("Unsupported Protocol Version: {0}")]
18 UnsupportedProtocolVersion(u32),
19 #[error("Nom ByteAligned Error {0}")]
21 ByteAligned(String),
22 #[error("Nom BitPacked Error {0}")]
24 BitPacked(String),
25 #[error("Unexpected Tag: {0}")]
27 UnknownTag(i64),
28 #[error("Duplicate field {0} with tag {1}")]
30 DuplicateTag(String, i64),
31 #[error("Missing field {0}")]
33 MissingField(String),
34 #[error("TryFromIntError")]
36 ValueError(#[from] TryFromIntError),
37 #[error("IO Error")]
39 IoError(#[from] std::io::Error),
40 #[error("Expected a file, but got a directory")]
42 PathNotADir,
43 #[error("Unsupported Event Type")]
46 UnsupportedEventType,
47 #[error("Utf8 conversion error")]
49 Utf8Error(#[from] std::str::Utf8Error),
50 #[error("BitPackedTooLarge: {0}")]
52 BitPackedMoreThan64Bits(usize),
53}
54
55impl<I> From<nom::Err<nom::error::Error<I>>> for S2ProtocolError
57where
58 I: Clone + std::fmt::Debug,
59{
60 fn from(err: nom::Err<nom::error::Error<I>>) -> Self {
61 match err {
62 nom::Err::Incomplete(_) => {
63 unreachable!("This library is compatible with only complete parsers, not streaming")
64 }
65 nom::Err::Error(e) => S2ProtocolError::ByteAligned(format!("{e:?}")),
66 nom::Err::Failure(e) => S2ProtocolError::ByteAligned(format!("{e:?}")),
67 }
68 }
69}
70
71impl<I> ParseError<I> for S2ProtocolError
72where
73 I: Clone,
74{
75 fn from_error_kind(_input: I, kind: ErrorKind) -> Self {
76 S2ProtocolError::ByteAligned(format!("{kind:?}"))
77 }
78
79 fn append(_input: I, _kind: ErrorKind, other: Self) -> Self {
80 other
81 }
82}