• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loot / loot-condition-interpreter / 14713787911

28 Apr 2025 05:18PM UTC coverage: 91.492% (-0.01%) from 91.505%
14713787911

push

github

Ortham
Update versions and changelog for v5.3.2

4850 of 5301 relevant lines covered (91.49%)

15.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.43
/src/error.rs
1
use std::error;
2
use std::fmt;
3
use std::io;
4
use std::num::NonZeroUsize;
5
use std::num::ParseIntError;
6
use std::path::Path;
7
use std::path::PathBuf;
8
use std::slice::EscapeAscii;
9

10
use nom::error::ErrorKind;
11
use nom::Err;
12

13
#[expect(clippy::error_impl_error)]
14
#[derive(Debug)]
15
#[non_exhaustive]
16
pub enum Error {
17
    ParsingIncomplete(MoreDataNeeded),
18
    // The string is the input that was not parsed.
19
    UnconsumedInput(String),
20
    /// The string is the input at which the error was encountered.
21
    ParsingError(String, ParsingErrorKind),
22
    PeParsingError(PathBuf, Box<dyn error::Error + Send + Sync + 'static>),
23
    IoError(PathBuf, io::Error),
24
}
25

26
fn escape<I: fmt::Display>(input: I) -> String {
3✔
27
    input.to_string().replace('"', "\\\"")
3✔
28
}
3✔
29

30
impl<I: fmt::Debug + fmt::Display> From<Err<ParsingError<I>>> for Error {
31
    fn from(error: Err<ParsingError<I>>) -> Self {
3✔
32
        match error {
×
33
            Err::Incomplete(nom::Needed::Unknown) => {
34
                Error::ParsingIncomplete(MoreDataNeeded::UnknownSize)
×
35
            }
36
            Err::Incomplete(nom::Needed::Size(size)) => {
×
37
                Error::ParsingIncomplete(MoreDataNeeded::Size(size))
×
38
            }
39
            Err::Error(e) | Err::Failure(e) => Error::ParsingError(escape(e.input), e.kind),
3✔
40
        }
41
    }
3✔
42
}
43

44
impl fmt::Display for Error {
45
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9✔
46
        match self {
×
47
            Error::ParsingIncomplete(MoreDataNeeded::UnknownSize) => write!(
×
48
                f,
×
49
                "An unknown number of bytes of additional input was expected by the parser"
×
50
            ),
×
51
            Error::ParsingIncomplete(MoreDataNeeded::Size(size)) => write!(
×
52
                f,
×
53
                "{size} bytes of additional input was expected by the parser"
×
54
            ),
×
55
            Error::UnconsumedInput(i) => {
2✔
56
                write!(f, "The parser did not consume the following input: \"{i}\"")
2✔
57
            }
58
            Error::ParsingError(i, e) => write!(
3✔
59
                f,
3✔
60
                "An error was encountered while parsing the expression \"{i}\": {e}"
3✔
61
            ),
3✔
62
            Error::PeParsingError(p, e) => write!(
2✔
63
                f,
2✔
64
                "An error was encountered while reading the version fields of \"{}\": {}",
2✔
65
                escape_ascii(p),
2✔
66
                e
2✔
67
            ),
2✔
68
            Error::IoError(p, e) => write!(
2✔
69
                f,
2✔
70
                "An error was encountered while accessing the path \"{}\": {}",
2✔
71
                escape_ascii(p),
2✔
72
                e
2✔
73
            ),
2✔
74
        }
75
    }
9✔
76
}
77

78
impl error::Error for Error {
79
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
×
80
        match self {
×
81
            Error::ParsingError(_, e) => Some(e),
×
82
            Error::PeParsingError(_, e) => Some(e.as_ref()),
×
83
            Error::IoError(_, e) => Some(e),
×
84
            _ => None,
×
85
        }
86
    }
×
87
}
88

89
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
90
pub enum MoreDataNeeded {
91
    /// It's not known how much more data are needed
92
    UnknownSize,
93
    /// Contains the number of bytes of data that are needed
94
    Size(NonZeroUsize),
95
}
96

97
#[derive(Clone, Debug, Eq, PartialEq)]
98
pub struct ParsingError<I: fmt::Debug + fmt::Display> {
99
    input: I,
100
    kind: ParsingErrorKind,
101
}
102

103
impl<I: fmt::Debug + fmt::Display> From<(I, ErrorKind)> for ParsingError<I> {
104
    fn from((input, kind): (I, ErrorKind)) -> Self {
×
105
        use nom::error::ParseError;
106
        ParsingError::from_error_kind(input, kind)
×
107
    }
×
108
}
109

110
impl<I: fmt::Debug + fmt::Display> From<nom::error::Error<I>> for ParsingError<I> {
111
    fn from(error: nom::error::Error<I>) -> Self {
709✔
112
        use nom::error::ParseError;
113
        ParsingError::from_error_kind(error.input, error.code)
709✔
114
    }
709✔
115
}
116

117
impl<I: fmt::Debug + fmt::Display> fmt::Display for ParsingError<I> {
118
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
×
119
        write!(
×
120
            f,
×
121
            "An error was encountered while parsing the expression \"{}\": {}",
×
122
            self.input, self.kind
×
123
        )
×
124
    }
×
125
}
126

127
impl<I: fmt::Debug + fmt::Display> error::Error for ParsingError<I> {
128
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
×
129
        self.kind.source()
×
130
    }
×
131
}
132

133
impl<I: fmt::Debug + fmt::Display> nom::error::ParseError<I> for ParsingError<I> {
134
    fn from_error_kind(input: I, kind: ErrorKind) -> Self {
709✔
135
        ParsingError {
709✔
136
            input,
709✔
137
            kind: ParsingErrorKind::GenericParserError(kind.description().to_owned()),
709✔
138
        }
709✔
139
    }
709✔
140

141
    fn append(_: I, _: ErrorKind, other: Self) -> Self {
17✔
142
        other
17✔
143
    }
17✔
144
}
145

146
#[derive(Clone, Debug, Eq, PartialEq)]
147
pub enum ParsingErrorKind {
148
    InvalidRegexSyntax(String),
149
    InvalidRegexUnknown,
150
    InvalidCrc(ParseIntError),
151
    PathEndsInADirectorySeparator(PathBuf),
152
    PathIsNotInGameDirectory(PathBuf),
153
    GenericParserError(String),
154
}
155

156
impl ParsingErrorKind {
157
    pub fn at<I: fmt::Debug + fmt::Display>(self, input: I) -> ParsingError<I> {
6✔
158
        ParsingError { input, kind: self }
6✔
159
    }
6✔
160
}
161

162
impl From<regex::Error> for ParsingErrorKind {
163
    fn from(error: regex::Error) -> Self {
1✔
164
        match error {
1✔
165
            regex::Error::Syntax(s) => ParsingErrorKind::InvalidRegexSyntax(s),
1✔
166
            _ => ParsingErrorKind::InvalidRegexUnknown,
×
167
        }
168
    }
1✔
169
}
170

171
impl From<ParseIntError> for ParsingErrorKind {
172
    fn from(error: ParseIntError) -> Self {
1✔
173
        ParsingErrorKind::InvalidCrc(error)
1✔
174
    }
1✔
175
}
176

177
impl error::Error for ParsingErrorKind {
178
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
×
179
        match self {
×
180
            ParsingErrorKind::InvalidCrc(e) => Some(e),
×
181
            _ => None,
×
182
        }
183
    }
×
184
}
185

186
impl fmt::Display for ParsingErrorKind {
187
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3✔
188
        match self {
3✔
189
            ParsingErrorKind::InvalidRegexSyntax(s) => write!(f, "{s}"),
1✔
190
            ParsingErrorKind::InvalidRegexUnknown => write!(f, "Unknown regex parsing error"),
×
191
            ParsingErrorKind::InvalidCrc(e) => e.fmt(f),
1✔
192
            ParsingErrorKind::PathEndsInADirectorySeparator(p) => {
1✔
193
                write!(f, "\"{}\" ends in a directory separator", escape_ascii(p))
1✔
194
            }
195
            ParsingErrorKind::PathIsNotInGameDirectory(p) => {
×
196
                write!(f, "\"{}\" is not in the game directory", escape_ascii(p))
×
197
            }
198
            ParsingErrorKind::GenericParserError(e) => write!(f, "Error in parser: {e}"),
×
199
        }
200
    }
3✔
201
}
202

203
fn escape_ascii(path: &Path) -> EscapeAscii {
5✔
204
    path.as_os_str().as_encoded_bytes().escape_ascii()
5✔
205
}
5✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc