diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-05-03 23:56:57 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-03 23:56:57 +0200 |
| commit | aa10ea8470763afe98d5ff558381f0a0beb0c017 (patch) | |
| tree | 938f58a8e0faa4f5216920fc3e82d86301d2f094 /src/eval | |
| parent | f9e115daf54c29358f890b137f50a33a781af680 (diff) | |
| parent | 51d0de09c6f7e2af4db3b65c3fe9595c501b82c9 (diff) | |
Merge pull request #69 from typst/shapeees
Advanced shapes
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/value.rs | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/src/eval/value.rs b/src/eval/value.rs index 6ce815a4..352906aa 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,47 @@ impl<T: Cast> Cast for Smart<T> { } } +impl<T> Cast for Sides<T> +where + T: Cast + Default + Clone, +{ + 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", } |
