Skip to content

Commit 694fcc3

Browse files
committed
refactor: Rename ExprDeser to TypedExpr and make them typed
Make top-level expressions used by the consumers typed, making them evaluate to a specific type instead of generic value. Also add type aliases for the type expressions we use: * `ColorExpr` * `NumExpr` * `BoolExpr`
1 parent 452f5ba commit 694fcc3

4 files changed

Lines changed: 75 additions & 52 deletions

File tree

galileo-maplibre/src/layer/vector_tile.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use galileo::Color;
22
use galileo::expr::{
3-
ControlPoint, ExponentialInterpolation, Expr, ExprDeser, ExprValue, WithOpacityExpr,
3+
ColorExpr, ControlPoint, ExponentialInterpolation, Expr, ExprValue, WithOpacityExpr,
44
};
55
use galileo::galileo_types::cartesian::{CartesianPoint2d, Point2, Rect};
66
use galileo::galileo_types::geo::impls::GeoPoint2d;
@@ -62,9 +62,9 @@ pub fn try_create(
6262
///
6363
/// Maptiler supports having background layer in any position, and just adds filling of the
6464
/// entire tile. WE don't support this currently, and always put background at the back.
65-
fn get_background(layers: &[&MaplibreStyleLayer]) -> ExprDeser {
66-
const DEFAULT_TILE_BACKGROUND: ExprDeser =
67-
ExprDeser(Expr::Literal(ExprValue::Color(Color::TRANSPARENT)));
65+
fn get_background(layers: &[&MaplibreStyleLayer]) -> ColorExpr {
66+
const DEFAULT_TILE_BACKGROUND: ColorExpr =
67+
ColorExpr::new(Expr::Literal(ExprValue::Color(Color::TRANSPARENT)));
6868

6969
let layer = match layers {
7070
[] => return DEFAULT_TILE_BACKGROUND,

galileo/src/expr/mod.rs

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![allow(missing_docs)] //TODO: temporary allow
22

3+
use std::marker::PhantomData;
4+
35
use serde::{Deserialize, Deserializer, Serialize};
46

57
mod interpolation;
@@ -46,35 +48,57 @@ pub enum Expr {
4648

4749
#[derive(Debug, Clone, PartialEq, Serialize)]
4850
#[serde(transparent)]
49-
pub struct ExprDeser(pub Expr);
51+
pub struct TypedExpr<Out>(Expr, PhantomData<Out>);
52+
53+
pub type ColorExpr = TypedExpr<Color>;
54+
pub type NumExpr = TypedExpr<f64>;
55+
pub type BoolExpr = TypedExpr<bool>;
5056

51-
impl Default for ExprDeser {
57+
impl<T> Default for TypedExpr<T> {
5258
fn default() -> Self {
53-
Self(Expr::Literal(ExprValue::Null))
59+
Self(Expr::Literal(ExprValue::Null), PhantomData)
5460
}
5561
}
5662

57-
impl ExprDeser {
58-
pub fn eval<'a>(&'a self, f: &'a impl ExprFeature, v: ExprView) -> ExprValue<&'a str> {
59-
self.0.eval(f, v)
63+
impl<Out> TypedExpr<Out> {
64+
pub const fn new(expr: Expr) -> Self {
65+
Self(expr, PhantomData)
66+
}
67+
}
68+
69+
impl TypedExpr<Color> {
70+
pub fn eval(&self, f: &impl ExprFeature, v: ExprView) -> Option<Color> {
71+
self.0.eval(f, v).as_color()
72+
}
73+
}
74+
75+
impl TypedExpr<f64> {
76+
pub fn eval(&self, f: &impl ExprFeature, v: ExprView) -> Option<f64> {
77+
self.0.eval(f, v).as_number()
78+
}
79+
}
80+
81+
impl TypedExpr<bool> {
82+
pub fn eval(&self, f: &impl ExprFeature, v: ExprView) -> bool {
83+
self.0.eval(f, v).to_bool()
6084
}
6185
}
6286

63-
impl From<Expr> for ExprDeser {
87+
impl<Out> From<Expr> for TypedExpr<Out> {
6488
fn from(value: Expr) -> Self {
65-
Self(value)
89+
Self::new(value)
6690
}
6791
}
6892

69-
impl From<Color> for ExprDeser {
93+
impl From<Color> for TypedExpr<Color> {
7094
fn from(value: Color) -> Self {
71-
Self(Expr::Literal(value.into()))
95+
Expr::Literal(value.into()).into()
7296
}
7397
}
7498

75-
impl From<f64> for ExprDeser {
99+
impl From<f64> for TypedExpr<f64> {
76100
fn from(value: f64) -> Self {
77-
Self(Expr::Literal(value.into()))
101+
Expr::Literal(value.into()).into()
78102
}
79103
}
80104

@@ -90,7 +114,7 @@ impl From<f64> for Expr {
90114
}
91115
}
92116

93-
impl<'de> Deserialize<'de> for ExprDeser {
117+
impl<'de, Out> Deserialize<'de> for TypedExpr<Out> {
94118
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
95119
// Buffer into a generic value so we can inspect the shape without consuming the input.
96120
let value = serde_json::Value::deserialize(deserializer)?;
@@ -197,7 +221,7 @@ mod tests {
197221
#[test]
198222
fn deserialize_expr_from_string() {
199223
let json = r#""kind == \"road\"""#;
200-
let expr: ExprDeser = serde_json::from_str(json).unwrap();
224+
let expr: BoolExpr = serde_json::from_str(json).unwrap();
201225
assert_eq!(
202226
expr.0,
203227
Expr::Eq(
@@ -210,13 +234,13 @@ mod tests {
210234
#[test]
211235
fn deserialize_expr_from_object() {
212236
let json = r#"{"Get": "kind"}"#;
213-
let expr: ExprDeser = serde_json::from_str(json).unwrap();
237+
let expr: NumExpr = serde_json::from_str(json).unwrap();
214238
assert_eq!(expr.0, Expr::Get("kind".to_string()));
215239
}
216240

217241
#[test]
218242
fn deserialize_bad_string_returns_error() {
219243
let json = r#""@@@ not valid @@@""#;
220-
assert!(serde_json::from_str::<Expr>(json).is_err());
244+
assert!(serde_json::from_str::<NumExpr>(json).is_err());
221245
}
222246
}

galileo/src/layer/vector_tile_layer/mod.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use galileo_types::impls::{ClosedContour, Polygon};
1414
use parking_lot::Mutex;
1515
pub use vector_tile::VectorTile;
1616

17-
use crate::expr::{EmptyExprFeature, ExprDeser, ExprView};
17+
use crate::expr::{ColorExpr, EmptyExprFeature, ExprView};
1818
use crate::layer::Layer;
1919
use crate::layer::attribution::Attribution;
2020
use crate::layer::vector_tile_layer::style::VectorTileStyle;
@@ -55,7 +55,7 @@ impl std::fmt::Debug for VectorTileLayer {
5555

5656
#[derive(Debug, Clone)]
5757
struct PreviousBackground {
58-
color: ExprDeser,
58+
color: ColorExpr,
5959
replaced_at: web_time::Instant,
6060
}
6161

@@ -274,10 +274,7 @@ impl VectorTileLayer {
274274
};
275275

276276
let mut prev_background = self.prev_background.lock();
277-
let new_color = style
278-
.background
279-
.eval(&EmptyExprFeature, expr_view)
280-
.as_color()?;
277+
let new_color = style.background.eval(&EmptyExprFeature, expr_view)?;
281278
let color = match &*prev_background {
282279
Some(prev) => {
283280
let k = web_time::Instant::now()
@@ -289,7 +286,7 @@ impl VectorTileLayer {
289286
*prev_background = None;
290287
new_color
291288
} else {
292-
let prev_color = prev.color.eval(&EmptyExprFeature, expr_view).as_color()?;
289+
let prev_color = prev.color.eval(&EmptyExprFeature, expr_view)?;
293290
prev_color.blend(new_color.with_alpha((new_color.a() as f32 * k) as u8))
294291
}
295292
}

galileo/src/layer/vector_tile_layer/style.rs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use galileo_mvt::{MvtFeature, MvtValue};
44
use serde::{Deserialize, Serialize};
55

66
use crate::Color;
7-
use crate::expr::{ExprDeser, ExprFeature, ExprGeometryType, ExprValue, ExprView};
7+
use crate::expr::{
8+
BoolExpr, ColorExpr, ExprFeature, ExprGeometryType, ExprValue, ExprView, NumExpr,
9+
};
810
use crate::render::point_paint::PointPaint;
911
use crate::render::text::{
1012
FontStyle, FontWeight, HorizontalAlignment, TextStyle, VerticalAlignment,
@@ -21,7 +23,7 @@ pub struct VectorTileStyle {
2123
pub rules: Vec<StyleRule>,
2224

2325
/// Background color of tiles.
24-
pub background: ExprDeser,
26+
pub background: ColorExpr,
2527
}
2628

2729
/// A rule that specifies what kind of features can be drawing with the given symbol.
@@ -36,7 +38,7 @@ pub struct StyleRule {
3638
pub min_resolution: Option<f64>,
3739
/// Specifies a set of attributes of a feature that must have the given values for this rule to be applied.
3840
#[serde(default)]
39-
pub filter: Option<ExprDeser>,
41+
pub filter: Option<BoolExpr>,
4042
/// Symbol to draw a feature with.
4143
#[serde(default)]
4244
pub symbol: VectorTileSymbol,
@@ -54,7 +56,7 @@ impl StyleRule {
5456
z_index: Some(z_index),
5557
};
5658

57-
expr.eval(feature, expr_view).as_bool().unwrap_or(false)
59+
expr.eval(feature, expr_view)
5860
}
5961
}
6062

@@ -149,16 +151,16 @@ impl VectorTileSymbol {
149151
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
150152
pub struct VectorTilePointSymbol {
151153
/// Size of the point.
152-
pub size: ExprDeser,
154+
pub size: NumExpr,
153155
/// Color of the point.
154-
pub color: ExprDeser,
156+
pub color: ColorExpr,
155157
}
156158

157159
impl VectorTilePointSymbol {
158160
pub(crate) fn to_paint(&self, feature: &MvtFeature, view: ExprView) -> Option<PointPaint<'_>> {
159161
Some(PointPaint::circle(
160-
self.color.eval(feature, view).as_color()?,
161-
self.size.eval(feature, view).as_number()? as f32,
162+
self.color.eval(feature, view)?,
163+
self.size.eval(feature, view)? as f32,
162164
))
163165
}
164166
}
@@ -167,16 +169,16 @@ impl VectorTilePointSymbol {
167169
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
168170
pub struct VectorTileLineSymbol {
169171
/// Width of the line in pixels.
170-
pub width: ExprDeser,
172+
pub width: NumExpr,
171173
/// Color of the line in pixels.
172-
pub stroke_color: ExprDeser,
174+
pub stroke_color: ColorExpr,
173175
}
174176

175177
impl VectorTileLineSymbol {
176178
pub(crate) fn to_paint(&self, feature: &MvtFeature, view: ExprView) -> Option<LinePaint> {
177179
Some(LinePaint {
178-
color: self.stroke_color.eval(feature, view).as_color()?,
179-
width: self.width.eval(feature, view).as_number()?,
180+
color: self.stroke_color.eval(feature, view)?,
181+
width: self.width.eval(feature, view)?,
180182
offset: 0.0,
181183
line_cap: LineCap::Butt,
182184
})
@@ -187,13 +189,13 @@ impl VectorTileLineSymbol {
187189
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
188190
pub struct VectorTilePolygonSymbol {
189191
/// Color of the fill of polygon.
190-
pub fill_color: ExprDeser,
192+
pub fill_color: ColorExpr,
191193
}
192194

193195
impl VectorTilePolygonSymbol {
194196
pub(crate) fn to_paint(&self, feature: &MvtFeature, view: ExprView) -> Option<PolygonPaint> {
195197
Some(PolygonPaint {
196-
color: self.fill_color.eval(feature, view).as_color()?,
198+
color: self.fill_color.eval(feature, view)?,
197199
})
198200
}
199201
}
@@ -214,10 +216,10 @@ pub struct VtTextStyle {
214216
/// Name of the font to use.
215217
pub font_family: Vec<String>,
216218
/// Size of the font in pixels.
217-
pub font_size: ExprDeser,
219+
pub font_size: NumExpr,
218220
/// Color of the font.
219221
#[serde(default = "default_font_color_style")]
220-
pub font_color: ExprDeser,
222+
pub font_color: ColorExpr,
221223
/// Alignment of label along horizontal axis.
222224
#[serde(default)]
223225
pub horizontal_alignment: HorizontalAlignment,
@@ -232,10 +234,10 @@ pub struct VtTextStyle {
232234
pub style: FontStyle,
233235
/// Width of the outline around the letters.
234236
#[serde(default = "default_outline_width_style")]
235-
pub outline_width: ExprDeser,
237+
pub outline_width: NumExpr,
236238
/// Color of the outline around the letters.
237239
#[serde(default = "default_outline_color_style")]
238-
pub outline_color: ExprDeser,
240+
pub outline_color: ColorExpr,
239241
}
240242

241243
impl VtTextStyle {
@@ -244,27 +246,27 @@ impl VtTextStyle {
244246
pub fn get_value(self, feature: &MvtFeature, view: ExprView) -> Option<TextStyle> {
245247
Some(TextStyle {
246248
font_family: self.font_family,
247-
font_size: self.font_size.eval(feature, view).as_number()? as f32,
248-
font_color: self.font_color.eval(feature, view).as_color()?,
249+
font_size: self.font_size.eval(feature, view)? as f32,
250+
font_color: self.font_color.eval(feature, view)?,
249251
horizontal_alignment: self.horizontal_alignment,
250252
vertical_alignment: self.vertical_alignment,
251253
weight: self.weight,
252254
style: self.style,
253-
outline_width: self.outline_width.eval(feature, view).as_number()? as f32,
254-
outline_color: self.outline_color.eval(feature, view).as_color()?,
255+
outline_width: self.outline_width.eval(feature, view)? as f32,
256+
outline_color: self.outline_color.eval(feature, view)?,
255257
})
256258
}
257259
}
258260

259-
fn default_font_color_style() -> ExprDeser {
261+
fn default_font_color_style() -> ColorExpr {
260262
Color::BLACK.into()
261263
}
262264

263-
fn default_outline_color_style() -> ExprDeser {
265+
fn default_outline_color_style() -> ColorExpr {
264266
Color::TRANSPARENT.into()
265267
}
266268

267-
fn default_outline_width_style() -> ExprDeser {
269+
fn default_outline_width_style() -> NumExpr {
268270
0.0.into()
269271
}
270272

0 commit comments

Comments
 (0)