s2protocol/
error.rs

1//! Error handling of S2Protocol
2
3use std::num::TryFromIntError;
4
5use nom::error::ErrorKind;
6use nom::error::ParseError;
7
8/// Holds the result of parsing progress and the possibly failures
9pub type S2ProtoResult<I, O> = Result<(I, O), S2ProtocolError>;
10
11#[derive(thiserror::Error, Debug)]
12pub enum S2ProtocolError {
13    /// Unable to parse the MPQ file, could be corrupted or not a replay file
14    #[error("MPQ Error")]
15    MPQ(#[from] nom_mpq::MPQParserError),
16    /// The protocol version is not yet supported.
17    #[error("Unsupported Protocol Version: {0}")]
18    UnsupportedProtocolVersion(u32),
19    /// Unable to parse the byte aligned data types
20    #[error("Nom ByteAligned Error {0}")]
21    ByteAligned(String),
22    /// Unable to parse the bit packed data types
23    #[error("Nom BitPacked Error {0}")]
24    BitPacked(String),
25    /// The data structure tag is not recognized
26    #[error("Unexpected Tag: {0}")]
27    UnknownTag(i64),
28    /// The data structure tag was already parsed
29    #[error("Duplicate field {0} with tag {1}")]
30    DuplicateTag(String, i64),
31    /// A required field was not found
32    #[error("Missing field {0}")]
33    MissingField(String),
34    /// Unable to parse a value that should have been an integer
35    #[error("TryFromIntError")]
36    ValueError(#[from] TryFromIntError),
37    /// An I/O Error
38    #[error("IO Error")]
39    IoError(#[from] std::io::Error),
40    /// The path provided was not a file
41    #[error("Expected a file, but got a directory")]
42    PathNotADir,
43    /// An error to be used in TryFrom, when converting from protocol-specific types into our
44    /// consolidated-types
45    #[error("Unsupported Event Type")]
46    UnsupportedEventType,
47    /// Conversion to UTF-8 failed, from the `Vec<u8>` "name" fields in the proto fields
48    #[error("Utf8 conversion error")]
49    Utf8Error(#[from] std::str::Utf8Error),
50    /// The data structure tag is not recognized
51    #[error("BitPackedTooLarge: {0}")]
52    BitPackedMoreThan64Bits(usize),
53}
54
55/// Conversion of errors from byte aligned parser
56impl<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}