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

geo-engine / geoengine / 12950923969

24 Jan 2025 01:49PM UTC coverage: 90.059% (-0.002%) from 90.061%
12950923969

Pull #1010

github

web-flow
Merge 0bb105e1d into df8c694c8
Pull Request #1010: check compilation exit code

11 of 15 new or added lines in 2 files covered. (73.33%)

6 existing lines in 1 file now uncovered.

127257 of 141304 relevant lines covered (90.06%)

56966.68 hits per line

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

80.77
/expression/src/error.rs
1
use crate::codegen::DataType;
2
use snafu::Snafu;
3
use std::fmt::{Debug, Display};
4

5
/// An expression error type that concern the compilation, linkage and execution of an expression
6
#[derive(Debug, Snafu)]
×
7
#[snafu(visibility(pub(crate)))]
8
#[snafu(context(suffix(false)))] // disables default `Snafu` suffix
9
pub enum ExpressionExecutionError {
10
    #[snafu(display("Cannot create temporary directory"))]
11
    TempDir { source: std::io::Error },
12

13
    #[snafu(display("Cannot create workspace for dependencies"))]
14
    DepsWorkspace { source: std::io::Error },
15

16
    #[snafu(display("Cannot build dependencies"))]
17
    DepsBuild {
18
        /// [`cargo::util::errors::CargoResult`] has a lifetime that refers to a [`cargo::config::Config`].
19
        /// This is a debug print.
20
        debug: String,
21
    },
22

23
    #[snafu(display("Cannot store source code in temporary file"))]
24
    CannotGenerateSourceCodeFile { source: std::io::Error },
25

26
    #[snafu(display("Cannot format source code"))]
27
    CannotFormatSourceCodeFile { source: std::io::Error },
28

29
    #[snafu(display("Cannot store source code in temporary directory"))]
30
    CannotGenerateSourceCodeDirectory { source: std::io::Error },
31

32
    #[snafu(display("Cannot compile expression"))]
33
    Compiler { source: std::io::Error },
34

35
    #[snafu(display("Cannot load expression for execution"))]
36
    LinkExpression { source: libloading::Error },
37

38
    #[snafu(display(
39
        "Error during compilation of expression. Stdout: {stdout}, Stderr: {stderr}"
40
    ))]
41
    CompilationFailed { stderr: String, stdout: String },
42

43
    #[snafu(display("Unknown function in expression: {name}"))]
44
    LinkedFunctionNotFound {
45
        source: libloading::Error,
46
        name: String,
47
    },
48
}
49

50
#[derive(Clone, PartialEq, Eq)]
51
pub struct ExpressionParserError {
52
    source: crate::parser::PestError,
53
}
54

55
impl Display for ExpressionParserError {
56
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8✔
57
        Display::fmt(&self.source, f)
8✔
58
    }
8✔
59
}
60

61
impl Debug for ExpressionParserError {
62
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
×
UNCOV
63
        Debug::fmt(&self.source, f)
×
UNCOV
64
    }
×
65
}
66

67
impl std::error::Error for ExpressionParserError {
68
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
×
UNCOV
69
        self.source.source()
×
UNCOV
70
    }
×
71
}
72

73
impl ExpressionParserError {
74
    pub fn from_syntactic_error(source: crate::parser::PestError) -> Self {
×
UNCOV
75
        Self { source }
×
UNCOV
76
    }
×
77

78
    pub fn from_semantic_error(source: &ExpressionSemanticError, span: pest::Span) -> Self {
96✔
79
        Self {
96✔
80
            source: crate::parser::PestError::new_from_span(
96✔
81
                pest::error::ErrorVariant::CustomError {
96✔
82
                    message: source.to_string(),
96✔
83
                },
96✔
84
                span,
96✔
85
            ),
96✔
86
        }
96✔
87
    }
96✔
88

89
    pub fn from_definition_error(source: &ExpressionSemanticError) -> Self {
1✔
90
        Self {
1✔
91
            source: crate::parser::PestError::new_from_pos(
1✔
92
                pest::error::ErrorVariant::CustomError {
1✔
93
                    message: source.to_string(),
1✔
94
                },
1✔
95
                // we cannot point to anything other than the start of the file
1✔
96
                pest::Position::from_start(""),
1✔
97
            ),
1✔
98
        }
1✔
99
    }
1✔
100
}
101

102
impl ExpressionSemanticError {
103
    pub fn into_parser_error(self, span: pest::Span) -> ExpressionParserError {
96✔
104
        ExpressionParserError::from_semantic_error(&self, span)
96✔
105
    }
96✔
106

107
    pub fn into_definition_parser_error(self) -> ExpressionParserError {
1✔
108
        ExpressionParserError::from_definition_error(&self)
1✔
109
    }
1✔
110
}
111

112
/// An expression error type that concern the parsing of user code
113
#[derive(Debug, Snafu, Clone, PartialEq, Eq)]
97✔
114
#[snafu(visibility(pub(crate)))]
115
#[snafu(context(suffix(false)))] // disables default `Snafu` suffix
116
pub enum ExpressionSemanticError {
117
    #[snafu(display("The expression function must have a name"))]
118
    EmptyExpressionName,
119

120
    #[snafu(display("A parameter name must not be empty"))]
121
    EmptyParameterName,
122

123
    #[snafu(display("The parameter `{parameter}` was defined multiple times"))]
124
    DuplicateParameterName {
125
        parameter: String,
126
    },
127

128
    #[snafu(display("The variable `{variable}` was not defined"))]
129
    UnknownVariable {
130
        variable: String,
131
    },
132

133
    #[snafu(display("The variable `{variable}` was already defined"))]
134
    VariableShadowing {
135
        variable: String,
136
    },
137

138
    UnknownBooleanVariable {
139
        variable: String,
140
    },
141

142
    #[snafu(display("Unknown function `{function}`"))]
143
    UnknownFunction {
144
        function: String,
145
    },
146

147
    #[snafu(display(
148
        "Invalid function arguments for function `{name}`: expected {expected}, got {actual}",
149
        expected = display_strings(expected),
150
        actual = display_strings(actual)
151
    ))]
152
    InvalidFunctionArguments {
153
        name: String,
154
        expected: Vec<String>,
155
        actual: Vec<DataType>,
156
    },
157

158
    #[snafu(display("The if-then-else expression is missing a branch"))]
159
    MissingBranch,
160

161
    #[snafu(display("The if-then-else expression must have an else part"))]
162
    BranchStructureMalformed,
163

164
    #[snafu(display(
165
        "To output a value, the last statement must be an expression and not an assignment"
166
    ))]
167
    DoesNotEndWithExpression,
168

169
    #[snafu(display("Unexpected rule: {rule}"))]
170
    UnexpectedRule {
171
        rule: String,
172
    },
173

174
    #[snafu(display("Unexpected operator: expected (+, -, *, /, **), found {found}"))]
175
    UnexpectedOperator {
176
        found: String,
177
    },
178

179
    #[snafu(display("Unexpected operator: expected (<, <=, ==, !=, >=, >), found {comparator}"))]
180
    UnexpectedComparator {
181
        comparator: String,
182
    },
183

184
    #[snafu(display("Unexpected boolean rule: {rule}"))]
185
    UnexpectedBooleanRule {
186
        rule: String,
187
    },
188

189
    #[snafu(display("Unexpected boolean operator: {operator}"))]
190
    UnexpectedBooleanOperator {
191
        operator: String,
192
    },
193

194
    #[snafu(display("A comparison needs a left part, a comparator and a right part"))]
195
    ComparisonNeedsThreeParts,
196

197
    #[snafu(display("An assignment needs a variable name and an expression"))]
198
    AssignmentNeedsTwoParts,
199

200
    #[snafu(display("The constant `{constant}` is not a number"))]
201
    ConstantIsNotAdNumber {
202
        source: std::num::ParseFloatError,
203
        constant: String,
204
    },
205

206
    #[snafu(display("The function call is missing a function name"))]
207
    MalformedFunctionCall,
208

209
    #[snafu(display("The expression of form `A IS NODATA` is missing the left part"))]
210
    MalformedIdentifierIsNodata,
211

212
    #[snafu(display("All branches of an if-then-else expression must output the same type"))]
213
    AllBranchesMustOutputSameType,
214

215
    #[snafu(display("Comparisons can only be used with numbers"))]
216
    ComparisonsMustBeUsedWithNumbers,
217

218
    #[snafu(display("Operators can only be used with numbers"))]
219
    OperatorsMustBeUsedWithNumbers,
220

221
    #[snafu(display(
222
        "The expression was expected to output `{expected}`, but it outputs `{actual}`"
223
    ))]
224
    WrongOutputType {
225
        expected: DataType,
226
        actual: DataType,
227
    },
228
}
229

230
/// User-facing display of a list of strings
231
fn display_strings<S: Display>(strings: &[S]) -> String {
4✔
232
    let mut output = String::new();
4✔
233
    output.push('[');
4✔
234
    for (i, string) in strings.iter().enumerate() {
7✔
235
        if i > 0 {
7✔
236
            output.push_str(", ");
3✔
237
        }
4✔
238
        output.push_str(&string.to_string());
7✔
239
    }
240
    output.push(']');
4✔
241
    output
4✔
242
}
4✔
243

244
/// This module only ensures that the error types are `Send` and `Sync`.
245
mod send_sync_ensurance {
246
    use super::*;
247

248
    #[allow(dead_code)]
249
    trait SendSyncEnsurance: Send + Sync {}
250

251
    impl SendSyncEnsurance for ExpressionExecutionError {}
252

253
    impl SendSyncEnsurance for ExpressionSemanticError {}
254

255
    impl SendSyncEnsurance for ExpressionParserError {}
256
}
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