summaryrefslogtreecommitdiff
path: root/src/eval/value.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-04-08 17:08:30 +0200
committerLaurenz <laurmaedje@gmail.com>2022-04-09 12:02:35 +0200
commit29eb13ca6214461a4b0deb63d589cd39ad6d41c2 (patch)
treec86797d440cfcc801c87a3c64f479e39f2c068b1 /src/eval/value.rs
parent712c00ecb72b67da2c0788e5d3eb4dcc6366b2a7 (diff)
Sum color and length into stroke
Diffstat (limited to 'src/eval/value.rs')
-rw-r--r--src/eval/value.rs70
1 files changed, 67 insertions, 3 deletions
diff --git a/src/eval/value.rs b/src/eval/value.rs
index 1851cf28..cc312c5a 100644
--- a/src/eval/value.rs
+++ b/src/eval/value.rs
@@ -2,11 +2,16 @@ use std::any::Any;
use std::cmp::Ordering;
use std::fmt::{self, Debug, Formatter};
use std::hash::{Hash, Hasher};
+use std::num::NonZeroUsize;
use std::sync::Arc;
-use super::{ops, Args, Array, Content, Context, Dict, Func, Layout, RawLength, StrExt};
+use super::{
+ ops, Args, Array, Content, Context, Dict, Func, Layout, LayoutNode, RawLength, StrExt,
+};
use crate::diag::{with_alternative, At, StrResult, TypResult};
-use crate::geom::{Angle, Color, Em, Fraction, Length, Ratio, Relative, RgbaColor};
+use crate::geom::{
+ Angle, Color, Dir, Em, Fraction, Length, Paint, Ratio, Relative, RgbaColor,
+};
use crate::library::text::RawNode;
use crate::syntax::{Span, Spanned};
use crate::util::EcoString;
@@ -526,7 +531,7 @@ macro_rules! castable {
$(@$dyn_in:ident: $dyn_type:ty => $dyn_out:expr,)*
) => {
impl $crate::eval::Cast<$crate::eval::Value> for $type {
- fn is(value: &Value) -> bool {
+ fn is(value: &$crate::eval::Value) -> bool {
#[allow(unused_variables)]
match value {
$($pattern => true,)*
@@ -637,6 +642,14 @@ impl<T> Smart<T> {
}
}
+ /// Keeps `self` if it contains a custom value, otherwise returns `other`.
+ pub fn or(self, other: Smart<T>) -> Self {
+ match self {
+ Self::Custom(x) => Self::Custom(x),
+ Self::Auto => other,
+ }
+ }
+
/// Returns the contained custom value or a provided default value.
pub fn unwrap_or(self, default: T) -> T {
match self {
@@ -655,6 +668,14 @@ impl<T> Smart<T> {
Self::Custom(x) => x,
}
}
+
+ /// Returns the contained custom value or the default value.
+ pub fn unwrap_or_default(self) -> T
+ where
+ T: Default,
+ {
+ self.unwrap_or_else(T::default)
+ }
}
impl<T> Default for Smart<T> {
@@ -678,6 +699,49 @@ impl<T: Cast> Cast for Smart<T> {
}
}
+dynamic! {
+ Dir: "direction",
+}
+
+castable! {
+ usize,
+ Expected: "non-negative integer",
+ Value::Int(int) => int.try_into().map_err(|_| {
+ if int < 0 {
+ "must be at least zero"
+ } else {
+ "number too large"
+ }
+ })?,
+}
+
+castable! {
+ NonZeroUsize,
+ Expected: "positive integer",
+ Value::Int(int) => Value::Int(int)
+ .cast::<usize>()?
+ .try_into()
+ .map_err(|_| "must be positive")?,
+}
+
+castable! {
+ Paint,
+ Expected: "color",
+ Value::Color(color) => Paint::Solid(color),
+}
+
+castable! {
+ String,
+ Expected: "string",
+ Value::Str(string) => string.into(),
+}
+
+castable! {
+ LayoutNode,
+ Expected: "content",
+ Value::Content(content) => content.pack(),
+}
+
#[cfg(test)]
mod tests {
use super::*;