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

geo-engine / geoengine / 5006008836

pending completion
5006008836

push

github

GitHub
Merge #785 #787

936 of 936 new or added lines in 50 files covered. (100.0%)

96010 of 107707 relevant lines covered (89.14%)

72676.46 hits per line

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

75.0
/operators/src/engine/operator.rs
1
use serde::{Deserialize, Serialize};
2
use tracing::debug;
3

4
use crate::error;
5
use crate::util::Result;
6
use async_trait::async_trait;
7
use geoengine_datatypes::dataset::DataId;
8

9
use super::{
10
    query_processor::{TypedRasterQueryProcessor, TypedVectorQueryProcessor},
11
    CloneablePlotOperator, CloneableRasterOperator, CloneableVectorOperator, CreateSpan,
12
    ExecutionContext, PlotResultDescriptor, RasterResultDescriptor, TypedPlotQueryProcessor,
13
    VectorResultDescriptor, WorkflowOperatorPath,
14
};
15

16
pub trait OperatorData {
17
    /// Get the ids of all the data involoved in this operator and its sources
18
    fn data_ids(&self) -> Vec<DataId> {
2✔
19
        let mut datasets = vec![];
2✔
20
        self.data_ids_collect(&mut datasets);
2✔
21
        datasets
2✔
22
    }
2✔
23

24
    fn data_ids_collect(&self, data_ids: &mut Vec<DataId>);
25
}
26

27
/// Common methods for `RasterOperator`s
28
#[typetag::serde(tag = "type")]
36✔
29
#[async_trait]
30
pub trait RasterOperator:
31
    CloneableRasterOperator + OperatorData + Send + Sync + std::fmt::Debug
32
{
33
    /// Internal initialization logic of the operator
34
    async fn _initialize(
35
        self: Box<Self>,
36
        path: WorkflowOperatorPath,
37
        context: &dyn ExecutionContext,
38
    ) -> Result<Box<dyn InitializedRasterOperator>>;
39

40
    /// Initialize the operator
41
    ///
42
    /// This method should not be overriden because it handles wrapping the operator using the
43
    /// execution context. Instead, `_initialize` should be implemented.
44
    async fn initialize(
288✔
45
        self: Box<Self>,
288✔
46
        path: WorkflowOperatorPath,
288✔
47
        context: &dyn ExecutionContext,
288✔
48
    ) -> Result<Box<dyn InitializedRasterOperator>> {
288✔
49
        let span = self.span();
288✔
50
        debug!("Initialize {}, path: {}", self.typetag_name(), &path);
288✔
51
        let op = self._initialize(path.clone(), context).await?;
288✔
52

53
        Ok(context.wrap_initialized_raster_operator(op, span, path))
278✔
54
    }
576✔
55

56
    /// Wrap a box around a `RasterOperator`
57
    fn boxed(self) -> Box<dyn RasterOperator>
390✔
58
    where
390✔
59
        Self: Sized + 'static,
390✔
60
    {
390✔
61
        Box::new(self)
390✔
62
    }
390✔
63

64
    fn span(&self) -> CreateSpan;
65
}
66

67
/// Common methods for `VectorOperator`s
68
#[typetag::serde(tag = "type")]
64✔
69
#[async_trait]
70
pub trait VectorOperator:
71
    CloneableVectorOperator + OperatorData + Send + Sync + std::fmt::Debug
72
{
73
    async fn _initialize(
74
        self: Box<Self>,
75
        path: WorkflowOperatorPath,
76
        context: &dyn ExecutionContext,
77
    ) -> Result<Box<dyn InitializedVectorOperator>>;
78

79
    async fn initialize(
172✔
80
        self: Box<Self>,
172✔
81
        path: WorkflowOperatorPath,
172✔
82
        context: &dyn ExecutionContext,
172✔
83
    ) -> Result<Box<dyn InitializedVectorOperator>> {
172✔
84
        let span = self.span();
172✔
85
        debug!("Initialize {}, path: {}", self.typetag_name(), &path);
172✔
86
        let op = self._initialize(path.clone(), context).await?;
172✔
87
        Ok(context.wrap_initialized_vector_operator(op, span, path))
163✔
88
    }
344✔
89

90
    /// Wrap a box around a `VectorOperator`
91
    fn boxed(self) -> Box<dyn VectorOperator>
216✔
92
    where
216✔
93
        Self: Sized + 'static,
216✔
94
    {
216✔
95
        Box::new(self)
216✔
96
    }
216✔
97

98
    fn span(&self) -> CreateSpan;
99
}
100

101
/// Common methods for `PlotOperator`s
102
#[typetag::serde(tag = "type")]
10✔
103
#[async_trait]
104
pub trait PlotOperator:
105
    CloneablePlotOperator + OperatorData + Send + Sync + std::fmt::Debug
106
{
107
    async fn _initialize(
108
        self: Box<Self>,
109
        path: WorkflowOperatorPath,
110
        context: &dyn ExecutionContext,
111
    ) -> Result<Box<dyn InitializedPlotOperator>>;
112

113
    async fn initialize(
67✔
114
        self: Box<Self>,
67✔
115
        path: WorkflowOperatorPath,
67✔
116
        context: &dyn ExecutionContext,
67✔
117
    ) -> Result<Box<dyn InitializedPlotOperator>> {
67✔
118
        let span = self.span();
67✔
119
        debug!("Initialize {}, path: {}", self.typetag_name(), &path);
67✔
120
        let op = self._initialize(path.clone(), context).await?;
67✔
121
        Ok(context.wrap_initialized_plot_operator(op, span, path))
55✔
122
    }
134✔
123

124
    /// Wrap a box around a `PlotOperator`
125
    fn boxed(self) -> Box<dyn PlotOperator>
76✔
126
    where
76✔
127
        Self: Sized + 'static,
76✔
128
    {
76✔
129
        Box::new(self)
76✔
130
    }
76✔
131

132
    fn span(&self) -> CreateSpan;
133
}
134

135
pub trait InitializedRasterOperator: Send + Sync {
136
    /// Get the result descriptor of the `Operator`
137
    fn result_descriptor(&self) -> &RasterResultDescriptor;
138

139
    /// Instantiate a `TypedVectorQueryProcessor` from a `RasterOperator`
140
    fn query_processor(&self) -> Result<TypedRasterQueryProcessor>;
141

142
    /// Wrap a box around a `RasterOperator`
143
    fn boxed(self) -> Box<dyn InitializedRasterOperator>
271✔
144
    where
271✔
145
        Self: Sized + 'static,
271✔
146
    {
271✔
147
        Box::new(self)
271✔
148
    }
271✔
149

150
    /// Get a canonic representation of the operator and its sources
151
    fn canonic_name(&self) -> CanonicOperatorName;
152
}
153

154
pub trait InitializedVectorOperator: Send + Sync {
155
    /// Get the result descriptor of the `Operator`
156
    fn result_descriptor(&self) -> &VectorResultDescriptor;
157

158
    /// Instantiate a `TypedVectorQueryProcessor` from a `RasterOperator`
159
    fn query_processor(&self) -> Result<TypedVectorQueryProcessor>;
160

161
    /// Wrap a box around a `RasterOperator`
162
    fn boxed(self) -> Box<dyn InitializedVectorOperator>
161✔
163
    where
161✔
164
        Self: Sized + 'static,
161✔
165
    {
161✔
166
        Box::new(self)
161✔
167
    }
161✔
168

169
    /// Get a canonic representation of the operator and its sources.
170
    /// This only includes *logical* operators, not wrappers
171
    fn canonic_name(&self) -> CanonicOperatorName;
172
}
173

174
/// A canonic name for an operator and its sources
175
#[derive(Clone, Debug, PartialEq, Eq)]
14✔
176
pub struct CanonicOperatorName(serde_json::Value);
177

178
#[allow(clippy::derive_hash_xor_eq)] // since the hash is basically also derived (from String), this should be fine
179
impl std::hash::Hash for CanonicOperatorName {
180
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
11✔
181
        // TODO: serializing to string is potentially too expensive to perform each time.
11✔
182
        self.0.to_string().hash(state);
11✔
183
    }
11✔
184
}
185

186
impl<T> From<&T> for CanonicOperatorName
187
where
188
    T: Serialize,
189
{
190
    fn from(value: &T) -> Self {
524✔
191
        CanonicOperatorName(serde_json::to_value(value).unwrap())
524✔
192
    }
524✔
193
}
194

195
pub trait InitializedPlotOperator: Send + Sync {
196
    /// Get the result descriptor of the `Operator`
197
    fn result_descriptor(&self) -> &PlotResultDescriptor;
198

199
    /// Instantiate a `TypedVectorQueryProcessor` from a `RasterOperator`
200
    fn query_processor(&self) -> Result<TypedPlotQueryProcessor>;
201

202
    /// Wrap a box around a `RasterOperator`
203
    fn boxed(self) -> Box<dyn InitializedPlotOperator>
55✔
204
    where
55✔
205
        Self: Sized + 'static,
55✔
206
    {
55✔
207
        Box::new(self)
55✔
208
    }
55✔
209

210
    /// Get a canonic representation of the operator and its sources
211
    fn canonic_name(&self) -> CanonicOperatorName;
212
}
213

214
impl InitializedRasterOperator for Box<dyn InitializedRasterOperator> {
215
    fn result_descriptor(&self) -> &RasterResultDescriptor {
175✔
216
        self.as_ref().result_descriptor()
175✔
217
    }
175✔
218

219
    fn query_processor(&self) -> Result<TypedRasterQueryProcessor> {
188✔
220
        self.as_ref().query_processor()
188✔
221
    }
188✔
222

223
    fn canonic_name(&self) -> CanonicOperatorName {
1✔
224
        self.as_ref().canonic_name()
1✔
225
    }
1✔
226
}
227

228
impl InitializedVectorOperator for Box<dyn InitializedVectorOperator> {
229
    fn result_descriptor(&self) -> &VectorResultDescriptor {
173✔
230
        self.as_ref().result_descriptor()
173✔
231
    }
173✔
232

233
    fn query_processor(&self) -> Result<TypedVectorQueryProcessor> {
120✔
234
        self.as_ref().query_processor()
120✔
235
    }
120✔
236

237
    fn canonic_name(&self) -> CanonicOperatorName {
×
238
        self.as_ref().canonic_name()
×
239
    }
×
240
}
241

242
impl InitializedPlotOperator for Box<dyn InitializedPlotOperator> {
243
    fn result_descriptor(&self) -> &PlotResultDescriptor {
×
244
        self.as_ref().result_descriptor()
×
245
    }
×
246

247
    fn query_processor(&self) -> Result<TypedPlotQueryProcessor> {
51✔
248
        self.as_ref().query_processor()
51✔
249
    }
51✔
250

251
    fn canonic_name(&self) -> CanonicOperatorName {
×
252
        self.as_ref().canonic_name()
×
253
    }
×
254
}
255

256
/// An enum to differentiate between `Operator` variants
257
#[derive(Clone, Debug, Serialize, Deserialize)]
134✔
258
#[serde(tag = "type", content = "operator")]
259
pub enum TypedOperator {
260
    Vector(Box<dyn VectorOperator>),
261
    Raster(Box<dyn RasterOperator>),
262
    Plot(Box<dyn PlotOperator>),
263
}
264

265
impl TypedOperator {
266
    pub fn get_vector(self) -> Result<Box<dyn VectorOperator>> {
267
        if let TypedOperator::Vector(o) = self {
5✔
268
            return Ok(o);
5✔
269
        }
×
270
        Err(error::Error::InvalidOperatorType {
×
271
            expected: "Vector".to_owned(),
×
272
            found: self.type_name().to_owned(),
×
273
        })
×
274
    }
5✔
275

276
    pub fn get_raster(self) -> Result<Box<dyn RasterOperator>> {
277
        if let TypedOperator::Raster(o) = self {
23✔
278
            return Ok(o);
23✔
279
        }
×
280
        Err(error::Error::InvalidOperatorType {
×
281
            expected: "Raster".to_owned(),
×
282
            found: self.type_name().to_owned(),
×
283
        })
×
284
    }
23✔
285

286
    pub fn get_plot(self) -> Result<Box<dyn PlotOperator>> {
287
        if let TypedOperator::Plot(o) = self {
2✔
288
            return Ok(o);
2✔
289
        }
×
290
        Err(error::Error::InvalidOperatorType {
×
291
            expected: "Plot".to_owned(),
×
292
            found: self.type_name().to_owned(),
×
293
        })
×
294
    }
2✔
295

296
    fn type_name(&self) -> &str {
×
297
        match self {
×
298
            TypedOperator::Vector(_) => "Vector",
×
299
            TypedOperator::Raster(_) => "Raster",
×
300
            TypedOperator::Plot(_) => "Plot",
×
301
        }
302
    }
×
303
}
304

305
impl From<Box<dyn VectorOperator>> for TypedOperator {
306
    fn from(operator: Box<dyn VectorOperator>) -> Self {
22✔
307
        Self::Vector(operator)
22✔
308
    }
22✔
309
}
310

311
impl From<Box<dyn RasterOperator>> for TypedOperator {
312
    fn from(operator: Box<dyn RasterOperator>) -> Self {
5✔
313
        Self::Raster(operator)
5✔
314
    }
5✔
315
}
316

317
impl From<Box<dyn PlotOperator>> for TypedOperator {
318
    fn from(operator: Box<dyn PlotOperator>) -> Self {
13✔
319
        Self::Plot(operator)
13✔
320
    }
13✔
321
}
322

323
/// An enum to differentiate between `InitializedOperator` variants
324
pub enum TypedInitializedOperator {
325
    Vector(Box<dyn InitializedVectorOperator>),
326
    Raster(Box<dyn InitializedRasterOperator>),
327
    Plot(Box<dyn InitializedPlotOperator>),
328
}
329

330
impl From<Box<dyn InitializedVectorOperator>> for TypedInitializedOperator {
331
    fn from(operator: Box<dyn InitializedVectorOperator>) -> Self {
×
332
        TypedInitializedOperator::Vector(operator)
×
333
    }
×
334
}
335

336
impl From<Box<dyn InitializedRasterOperator>> for TypedInitializedOperator {
337
    fn from(operator: Box<dyn InitializedRasterOperator>) -> Self {
×
338
        TypedInitializedOperator::Raster(operator)
×
339
    }
×
340
}
341

342
impl From<Box<dyn InitializedPlotOperator>> for TypedInitializedOperator {
343
    fn from(operator: Box<dyn InitializedPlotOperator>) -> Self {
×
344
        TypedInitializedOperator::Plot(operator)
×
345
    }
×
346
}
347

348
#[macro_export]
349
macro_rules! call_on_typed_operator {
350
    ($typed_operator:expr, $operator_var:ident => $function_call:expr) => {
351
        match $typed_operator {
352
            $crate::engine::TypedOperator::Vector($operator_var) => $function_call,
353
            $crate::engine::TypedOperator::Raster($operator_var) => $function_call,
354
            $crate::engine::TypedOperator::Plot($operator_var) => $function_call,
355
        }
356
    };
357
}
358

359
impl OperatorData for TypedOperator {
360
    fn data_ids_collect(&self, data_ids: &mut Vec<DataId>) {
2✔
361
        match self {
2✔
362
            TypedOperator::Vector(v) => v.data_ids_collect(data_ids),
×
363
            TypedOperator::Raster(r) => r.data_ids_collect(data_ids),
2✔
364
            TypedOperator::Plot(p) => p.data_ids_collect(data_ids),
×
365
        }
366
    }
2✔
367
}
368

369
pub trait OperatorName {
370
    const TYPE_NAME: &'static str;
371
}
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