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

geo-engine / geoengine / 13676494082

05 Mar 2025 12:55PM UTC coverage: 90.081%. First build
13676494082

Pull #1030

github

web-flow
Merge 11898d88c into dd906c06e
Pull Request #1030: Rust-2024

2219 of 2334 new or added lines in 98 files covered. (95.07%)

126332 of 140243 relevant lines covered (90.08%)

57394.86 hits per line

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

55.0
/operators/src/processing/expression/mod.rs
1
mod error;
2
mod raster_operator;
3
mod raster_query_processor;
4
mod vector_operator;
5

6
pub use error::{RasterExpressionError, VectorExpressionError};
7
pub use raster_operator::{Expression, ExpressionParams}; // TODO: rename to `RasterExpression`
8
pub use vector_operator::{VectorExpression, VectorExpressionParams};
9

10
use self::error::ExpressionDependenciesInitializationError;
11
use crate::util::Result;
12
use geoengine_datatypes::primitives::{
13
    AsGeoOption, MultiLineString, MultiLineStringRef, MultiPoint, MultiPointRef, MultiPolygon,
14
    MultiPolygonRef, NoGeometry,
15
};
16
use geoengine_expression::{ExpressionDependencies, error::ExpressionExecutionError};
17
use std::sync::{Arc, OnceLock};
18

19
/// The expression dependencies are initialized once and then reused for all expression evaluations.
20
static EXPRESSION_DEPENDENCIES: OnceLock<
21
    Result<ExpressionDependencies, Arc<ExpressionExecutionError>>,
22
> = OnceLock::new();
23

24
/// Initializes the expression dependencies once so that they can be reused for all expression evaluations.
25
/// Compiling the dependencies takes a while, so this can drastically improve performance on the first expression call.
26
///
27
/// If it fails, you can retry or terminate the program.
28
///
NEW
29
pub async fn initialize_expression_dependencies()
×
NEW
30
-> Result<(), ExpressionDependenciesInitializationError> {
×
31
    crate::util::spawn_blocking(|| {
×
32
        let dependencies = ExpressionDependencies::new()?;
×
33

34
        // if set returns an error, it was initialized before so it is ok for this functions purpose
35
        let _ = EXPRESSION_DEPENDENCIES.set(Ok(dependencies));
×
36
        Ok(())
×
37
    })
×
38
    .await?
×
39
}
×
40

41
fn generate_expression_dependencies()
2✔
42
-> Result<ExpressionDependencies, Arc<ExpressionExecutionError>> {
2✔
43
    ExpressionDependencies::new().map_err(Arc::new)
2✔
44
}
2✔
45

46
pub fn get_expression_dependencies()
22✔
47
-> Result<&'static ExpressionDependencies, Arc<ExpressionExecutionError>> {
22✔
48
    EXPRESSION_DEPENDENCIES
22✔
49
        .get_or_init(generate_expression_dependencies)
22✔
50
        .as_ref()
22✔
51
        .map_err(Clone::clone)
22✔
52
}
22✔
53

54
/// Replaces all non-alphanumeric characters in a string with underscores.
55
/// Prepends an underscore if the string is empty or starts with a number.
56
fn canonicalize_name(name: &str) -> String {
12✔
57
    let prepend_underscore = name.chars().next().is_none_or(char::is_numeric);
12✔
58

12✔
59
    let mut canonicalized_name =
12✔
60
        String::with_capacity(name.len() + usize::from(prepend_underscore));
12✔
61

12✔
62
    if prepend_underscore {
12✔
63
        canonicalized_name.push('_');
×
64
    }
12✔
65

66
    for c in name.chars() {
32✔
67
        canonicalized_name.push(if c.is_alphanumeric() { c } else { '_' });
32✔
68
    }
69

70
    canonicalized_name
12✔
71
}
12✔
72

73
/// Convenience trait for converting [`geoengine_datatypes`] types to [`geoengine_expression`] types.
74
trait AsExpressionGeo: AsGeoOption {
75
    type ExpressionGeometryType: Send;
76

77
    fn as_expression_geo(&self) -> Option<Self::ExpressionGeometryType>;
78
}
79

80
/// Convenience trait for converting [`geoengine_expression`] types to [`geoengine_datatypes`] types.
81
trait FromExpressionGeo: Sized {
82
    type ExpressionGeometryType: Send;
83

84
    fn from_expression_geo(geom: Self::ExpressionGeometryType) -> Option<Self>;
85
}
86

87
impl AsExpressionGeo for MultiPointRef<'_> {
88
    type ExpressionGeometryType = geoengine_expression::MultiPoint;
89

90
    fn as_expression_geo(&self) -> Option<Self::ExpressionGeometryType> {
108✔
91
        self.as_geo_option().map(Into::into)
108✔
92
    }
108✔
93
}
94

95
impl AsExpressionGeo for MultiLineStringRef<'_> {
96
    type ExpressionGeometryType = geoengine_expression::MultiLineString;
97

98
    fn as_expression_geo(&self) -> Option<Self::ExpressionGeometryType> {
×
99
        self.as_geo_option().map(Into::into)
×
100
    }
×
101
}
102

103
impl AsExpressionGeo for MultiPolygonRef<'_> {
104
    type ExpressionGeometryType = geoengine_expression::MultiPolygon;
105

106
    fn as_expression_geo(&self) -> Option<Self::ExpressionGeometryType> {
4✔
107
        self.as_geo_option().map(Into::into)
4✔
108
    }
4✔
109
}
110

111
impl AsExpressionGeo for NoGeometry {
112
    // fallback type
113
    type ExpressionGeometryType = geoengine_expression::MultiPoint;
114

115
    fn as_expression_geo(&self) -> Option<Self::ExpressionGeometryType> {
×
116
        self.as_geo_option().map(Into::into)
×
117
    }
×
118
}
119

120
impl FromExpressionGeo for MultiPoint {
121
    type ExpressionGeometryType = geoengine_expression::MultiPoint;
122

123
    fn from_expression_geo(geom: Self::ExpressionGeometryType) -> Option<Self> {
2✔
124
        let geo_geom: geo::MultiPoint = geom.into();
2✔
125
        geo_geom.try_into().ok()
2✔
126
    }
2✔
127
}
128

129
impl FromExpressionGeo for MultiLineString {
130
    type ExpressionGeometryType = geoengine_expression::MultiLineString;
131

132
    fn from_expression_geo(geom: Self::ExpressionGeometryType) -> Option<Self> {
×
133
        let geo_geom: geo::MultiLineString = geom.into();
×
134
        Some(geo_geom.into())
×
135
    }
×
136
}
137

138
impl FromExpressionGeo for MultiPolygon {
139
    type ExpressionGeometryType = geoengine_expression::MultiPolygon;
140

141
    fn from_expression_geo(geom: Self::ExpressionGeometryType) -> Option<Self> {
×
142
        let geo_geom: geo::MultiPolygon = geom.into();
×
143
        Some(geo_geom.into())
×
144
    }
×
145
}
146

147
impl FromExpressionGeo for NoGeometry {
148
    // fallback type
149
    type ExpressionGeometryType = geoengine_expression::MultiPoint;
150

151
    fn from_expression_geo(_geom: Self::ExpressionGeometryType) -> Option<Self> {
×
152
        None
×
153
    }
×
154
}
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

© 2025 Coveralls, Inc