diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-03-07 15:17:13 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-03-07 15:17:13 +0100 |
| commit | 25b5bd117529cd04bb789e1988eb3a3db8025a0e (patch) | |
| tree | 2fbb4650903123da047a1f1f11a0abda95286e12 /src/geom/smart.rs | |
| parent | 6ab7760822ccd24b4ef126d4737d41f1be15fe19 (diff) | |
Fully untyped model
Diffstat (limited to 'src/geom/smart.rs')
| -rw-r--r-- | src/geom/smart.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/geom/smart.rs b/src/geom/smart.rs index e115e99d..c977d651 100644 --- a/src/geom/smart.rs +++ b/src/geom/smart.rs @@ -31,6 +31,18 @@ impl<T> Smart<T> { } } + /// Map the contained custom value with `f` if it contains a custom value, + /// otherwise returns `default`. + pub fn map_or<F, U>(self, default: U, f: F) -> U + where + F: FnOnce(T) -> U, + { + match self { + Self::Auto => default, + Self::Custom(x) => f(x), + } + } + /// Keeps `self` if it contains a custom value, otherwise returns `other`. pub fn or(self, other: Smart<T>) -> Self { match self { @@ -72,3 +84,50 @@ impl<T> Default for Smart<T> { Self::Auto } } + +impl<T: Cast> Cast for Smart<T> { + fn is(value: &Value) -> bool { + matches!(value, Value::Auto) || T::is(value) + } + + fn cast(value: Value) -> StrResult<Self> { + match value { + Value::Auto => Ok(Self::Auto), + v if T::is(&v) => Ok(Self::Custom(T::cast(v)?)), + _ => <Self as Cast>::error(value), + } + } + + fn describe() -> CastInfo { + T::describe() + CastInfo::Type("auto") + } +} + +impl<T: Resolve> Resolve for Smart<T> { + type Output = Smart<T::Output>; + + fn resolve(self, styles: StyleChain) -> Self::Output { + self.map(|v| v.resolve(styles)) + } +} + +impl<T> Fold for Smart<T> +where + T: Fold, + T::Output: Default, +{ + type Output = Smart<T::Output>; + + fn fold(self, outer: Self::Output) -> Self::Output { + self.map(|inner| inner.fold(outer.unwrap_or_default())) + } +} + +impl<T: Into<Value>> From<Smart<T>> for Value { + fn from(v: Smart<T>) -> Self { + match v { + Smart::Custom(v) => v.into(), + Smart::Auto => Value::Auto, + } + } +} |
