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

loot / loot-condition-interpreter / 14694602221

27 Apr 2025 05:37PM UTC coverage: 91.505% (-0.1%) from 91.633%
14694602221

push

github

Ortham
Remove check that paths are inside game path

It didn't work correctly for OpenMW or for additional data paths, fixing it would be significantly more complicated, and it doesn't really add any value.

4 of 4 new or added lines in 1 file covered. (100.0%)

2 existing lines in 1 file now uncovered.

4847 of 5297 relevant lines covered (91.5%)

15.15 hits per line

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

56.12
/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::PathBuf;
7

8
use nom::error::ErrorKind;
9
use nom::Err;
10

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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