diff options
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/context.rs | 10 | ||||
| -rw-r--r-- | src/eval/state.rs | 36 | ||||
| -rw-r--r-- | src/eval/value.rs | 130 |
3 files changed, 91 insertions, 85 deletions
diff --git a/src/eval/context.rs b/src/eval/context.rs index ece33146..64a8fbbe 100644 --- a/src/eval/context.rs +++ b/src/eval/context.rs @@ -119,15 +119,17 @@ impl EvalContext { if !children.is_empty() || keep_empty(group.softness) { self.runs.push(NodePages { size: group.size, - child: Node::any(NodePad { + child: NodePad { padding: group.padding, - child: Node::any(NodeStack { + child: NodeStack { dirs: group.dirs, align: group.align, expansion: Gen::uniform(Expansion::Fill), children, - }), - }), + } + .into(), + } + .into(), }) } group.softness diff --git a/src/eval/state.rs b/src/eval/state.rs index 7860c004..2a8ee2f0 100644 --- a/src/eval/state.rs +++ b/src/eval/state.rs @@ -128,7 +128,22 @@ impl StateFont { impl Default for StateFont { fn default() -> Self { Self { - families: Rc::new(default_font_families()), + /// The default tree of font fallbacks. + families: Rc::new(fallback! { + list: ["sans-serif"], + classes: { + "serif" => ["source serif pro", "noto serif"], + "sans-serif" => ["source sans pro", "noto sans"], + "monospace" => ["source code pro", "noto sans mono"], + }, + base: [ + "source sans pro", + "noto sans", + "segoe ui emoji", + "noto emoji", + "latin modern math", + ], + }), variant: FontVariant { style: FontStyle::Normal, weight: FontWeight::REGULAR, @@ -141,22 +156,3 @@ impl Default for StateFont { } } } - -/// The default tree of font fallbacks. -fn default_font_families() -> FallbackTree { - fallback! { - list: ["sans-serif"], - classes: { - "serif" => ["source serif pro", "noto serif"], - "sans-serif" => ["source sans pro", "noto sans"], - "monospace" => ["source code pro", "noto sans mono"], - }, - base: [ - "source sans pro", - "noto sans", - "segoe ui emoji", - "noto emoji", - "latin modern math", - ], - } -} diff --git a/src/eval/value.rs b/src/eval/value.rs index a91ff137..80c6b820 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -1,6 +1,6 @@ use std::any::Any; use std::collections::HashMap; -use std::fmt::{self, Debug, Formatter}; +use std::fmt::{self, Debug, Display, Formatter}; use std::ops::Deref; use std::rc::Rc; @@ -45,14 +45,6 @@ pub enum Value { } impl Value { - /// Create a new dynamic value. - pub fn any<T>(any: T) -> Self - where - T: Type + Debug + Clone + PartialEq + 'static, - { - Self::Any(ValueAny::new(any)) - } - /// Try to cast the value into a specific type. pub fn cast<T>(self) -> CastResult<T, Self> where @@ -68,8 +60,8 @@ impl Value { Self::Bool(_) => bool::TYPE_NAME, Self::Int(_) => i64::TYPE_NAME, Self::Float(_) => f64::TYPE_NAME, - Self::Relative(_) => Relative::TYPE_NAME, Self::Length(_) => Length::TYPE_NAME, + Self::Relative(_) => Relative::TYPE_NAME, Self::Linear(_) => Linear::TYPE_NAME, Self::Color(_) => Color::TYPE_NAME, Self::Str(_) => String::TYPE_NAME, @@ -88,16 +80,24 @@ impl Eval for &Value { /// Evaluate everything contained in this value. fn eval(self, ctx: &mut EvalContext) -> Self::Output { - match self { - // Don't print out none values. - Value::None => {} - - // Pass through. - Value::Content(tree) => tree.eval(ctx), - - // Format with debug. - val => ctx.push(ctx.make_text_node(format!("{:?}", val))), - } + ctx.push(ctx.make_text_node(match self { + Value::None => return, + Value::Bool(v) => v.to_string(), + Value::Int(v) => v.to_string(), + Value::Float(v) => v.to_string(), + Value::Length(v) => v.to_string(), + Value::Relative(v) => v.to_string(), + Value::Linear(v) => v.to_string(), + Value::Color(v) => v.to_string(), + Value::Str(v) => v.clone(), + // TODO: Find good representation for composite types. + Value::Array(_v) => "(array)".into(), + Value::Dict(_v) => "(dictionary)".into(), + Value::Content(tree) => return tree.eval(ctx), + Value::Func(v) => v.to_string(), + Value::Any(v) => v.to_string(), + Value::Error => "(error)".into(), + })); } } @@ -110,21 +110,21 @@ impl Default for Value { impl Debug for Value { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Self::None => f.pad("none"), - Self::Bool(v) => v.fmt(f), - Self::Int(v) => v.fmt(f), - Self::Float(v) => v.fmt(f), - Self::Length(v) => v.fmt(f), - Self::Relative(v) => v.fmt(f), - Self::Linear(v) => v.fmt(f), - Self::Color(v) => v.fmt(f), - Self::Str(v) => v.fmt(f), - Self::Array(v) => v.fmt(f), - Self::Dict(v) => v.fmt(f), - Self::Content(v) => v.fmt(f), - Self::Func(v) => v.fmt(f), - Self::Any(v) => v.fmt(f), - Self::Error => f.pad("<error>"), + Self::None => f.pad("None"), + Self::Bool(v) => Debug::fmt(v, f), + Self::Int(v) => Debug::fmt(v, f), + Self::Float(v) => Debug::fmt(v, f), + Self::Length(v) => Debug::fmt(v, f), + Self::Relative(v) => Debug::fmt(v, f), + Self::Linear(v) => Debug::fmt(v, f), + Self::Color(v) => Debug::fmt(v, f), + Self::Str(v) => Debug::fmt(v, f), + Self::Array(v) => Debug::fmt(v, f), + Self::Dict(v) => Debug::fmt(v, f), + Self::Content(v) => Debug::fmt(v, f), + Self::Func(v) => Debug::fmt(v, f), + Self::Any(v) => Debug::fmt(v, f), + Self::Error => f.pad("Error"), } } } @@ -140,15 +140,18 @@ pub type ValueContent = Tree; /// A wrapper around a reference-counted executable function. #[derive(Clone)] -pub struct ValueFunc(Rc<dyn Fn(&mut EvalContext, &mut Args) -> Value>); +pub struct ValueFunc { + name: String, + f: Rc<dyn Fn(&mut EvalContext, &mut Args) -> Value>, +} impl ValueFunc { /// Create a new function value from a rust function or closure. - pub fn new<F>(func: F) -> Self + pub fn new<F>(name: impl Into<String>, f: F) -> Self where F: Fn(&mut EvalContext, &mut Args) -> Value + 'static, { - Self(Rc::new(func)) + Self { name: name.into(), f: Rc::new(f) } } } @@ -162,13 +165,18 @@ impl Deref for ValueFunc { type Target = dyn Fn(&mut EvalContext, &mut Args) -> Value; fn deref(&self) -> &Self::Target { - self.0.as_ref() + self.f.as_ref() } } +impl Display for ValueFunc { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "<function {}>", self.name) + } +} impl Debug for ValueFunc { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - f.pad("<function>") + Display::fmt(self, f) } } @@ -179,7 +187,7 @@ impl ValueAny { /// Create a new instance from any value that satisifies the required bounds. pub fn new<T>(any: T) -> Self where - T: Type + Debug + Clone + PartialEq + 'static, + T: Type + Debug + Display + Clone + PartialEq + 'static, { Self(Box::new(any)) } @@ -221,13 +229,19 @@ impl PartialEq for ValueAny { } } +impl Display for ValueAny { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&self.0, f) + } +} + impl Debug for ValueAny { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - self.0.fmt(f) + Debug::fmt(&self.0, f) } } -trait Bounds: Debug + 'static { +trait Bounds: Debug + Display + 'static { fn as_any(&self) -> &dyn Any; fn into_any(self: Box<Self>) -> Box<dyn Any>; fn dyn_eq(&self, other: &ValueAny) -> bool; @@ -237,7 +251,7 @@ trait Bounds: Debug + 'static { impl<T> Bounds for T where - T: Type + Debug + Clone + PartialEq + 'static, + T: Type + Debug + Display + Clone + PartialEq + 'static, { fn as_any(&self) -> &dyn Any { self @@ -304,6 +318,16 @@ impl<T, V> CastResult<T, V> { } } +impl Type for Value { + const TYPE_NAME: &'static str = "value"; +} + +impl Cast<Value> for Value { + fn cast(value: Value) -> CastResult<Self, Value> { + CastResult::Ok(value) + } +} + impl<T> Cast<Spanned<Value>> for T where T: Cast<Value>, @@ -390,15 +414,6 @@ impl From<&str> for Value { } } -impl<F> From<F> for Value -where - F: Fn(&mut EvalContext, &mut Args) -> Value + 'static, -{ - fn from(func: F) -> Self { - Self::Func(ValueFunc::new(func)) - } -} - impl From<ValueAny> for Value { fn from(v: ValueAny) -> Self { Self::Any(v) @@ -407,9 +422,8 @@ impl From<ValueAny> for Value { /// Make a type usable as a [`Value`]. /// -/// Given a type `T`, this implements the following traits: +/// Given a type `T`, this always implements the following traits: /// - [`Type`] for `T`, -/// - [`From<T>`](From) for [`Value`], /// - [`Cast<Value>`](Cast) for `T`. #[macro_export] macro_rules! impl_type { @@ -423,12 +437,6 @@ macro_rules! impl_type { const TYPE_NAME: &'static str = $type_name; } - impl From<$type> for $crate::eval::Value { - fn from(any: $type) -> Self { - $crate::eval::Value::any(any) - } - } - impl $crate::eval::Cast<$crate::eval::Value> for $type { fn cast( value: $crate::eval::Value, |
