summaryrefslogtreecommitdiff
path: root/src/eval/value.rs
diff options
context:
space:
mode:
authorMartin Haug <mhaug@live.de>2022-05-02 15:49:46 +0200
committerMartin Haug <mhaug@live.de>2022-05-02 16:35:11 +0200
commit7b6f3a0ab9ae0dac19f62b62b9ecc96ea942a89e (patch)
treec1722475478ffae72f0bf7a8d96e11358625d147 /src/eval/value.rs
parent84a4961a5dd03072b0e94c715957475d4ae21e4f (diff)
A new `Cast` implementation for `Sides`
Reinstate circle
Diffstat (limited to 'src/eval/value.rs')
-rw-r--r--src/eval/value.rs40
1 files changed, 39 insertions, 1 deletions
diff --git a/src/eval/value.rs b/src/eval/value.rs
index 6ce815a4..c32614df 100644
--- a/src/eval/value.rs
+++ b/src/eval/value.rs
@@ -8,7 +8,7 @@ use std::sync::Arc;
use super::{ops, Args, Array, Dict, Func, RawLength};
use crate::diag::{with_alternative, StrResult};
use crate::geom::{
- Angle, Color, Dir, Em, Fraction, Length, Paint, Ratio, Relative, RgbaColor,
+ Angle, Color, Dir, Em, Fraction, Length, Paint, Ratio, Relative, RgbaColor, Sides,
};
use crate::library::text::RawNode;
use crate::model::{Content, Layout, LayoutNode};
@@ -596,6 +596,44 @@ impl<T: Cast> Cast for Smart<T> {
}
}
+impl<T: Cast + Default + Clone> Cast for Sides<T> {
+ fn is(value: &Value) -> bool {
+ matches!(value, Value::Dict(_)) || T::is(value)
+ }
+
+ fn cast(value: Value) -> StrResult<Self> {
+ match value {
+ Value::Dict(dict) => {
+ for (key, _) in &dict {
+ if !matches!(
+ key.as_str(),
+ "left" | "top" | "right" | "bottom" | "x" | "y" | "rest"
+ ) {
+ return Err(format!("unexpected key {key:?}"));
+ }
+ }
+
+ let sides = Sides {
+ left: dict.get("left".into()).or_else(|_| dict.get("x".into())),
+ top: dict.get("top".into()).or_else(|_| dict.get("y".into())),
+ right: dict.get("right".into()).or_else(|_| dict.get("x".into())),
+ bottom: dict.get("bottom".into()).or_else(|_| dict.get("y".into())),
+ }
+ .map(|side| {
+ side.or_else(|_| dict.get("rest".into()))
+ .and_then(|v| T::cast(v.clone()))
+ .unwrap_or_default()
+ });
+
+ Ok(sides)
+ }
+ v => T::cast(v)
+ .map(Sides::splat)
+ .map_err(|msg| with_alternative(msg, "dictionary")),
+ }
+ }
+}
+
dynamic! {
Dir: "direction",
}