From 0dd4ae0a7ac0c247078df492469ff20b8a90c886 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sat, 21 Aug 2021 16:38:51 +0200 Subject: [PATCH] Prune derives --- src/color.rs | 42 ++++++------ src/diag.rs | 2 +- src/eval/array.rs | 12 ++-- src/eval/capture.rs | 1 - src/eval/dict.rs | 24 +++---- src/eval/function.rs | 12 ++-- src/eval/mod.rs | 135 ++------------------------------------ src/eval/scope.rs | 4 +- src/eval/state.rs | 6 +- src/eval/str.rs | 30 ++++----- src/eval/template.rs | 18 ++--- src/eval/value.rs | 52 +++++++-------- src/eval/walk.rs | 129 ++++++++++++++++++++++++++++++++++++ src/font.rs | 47 ++++++------- src/geom/angle.rs | 21 +++--- src/geom/fr.rs | 12 ++-- src/geom/length.rs | 16 ++--- src/geom/linear.rs | 12 ++-- src/geom/relative.rs | 12 ++-- src/geom/sides.rs | 16 ++--- src/image.rs | 3 +- src/layout/background.rs | 1 - src/layout/constraints.rs | 10 --- src/layout/fixed.rs | 3 +- src/layout/grid.rs | 5 +- src/layout/image.rs | 1 - src/layout/pad.rs | 1 - src/layout/par.rs | 15 ----- src/layout/shaping.rs | 87 +++++++++++------------- src/layout/stack.rs | 2 - src/layout/tree.rs | 60 +---------------- src/loading/fs.rs | 2 +- src/loading/mem.rs | 2 +- src/loading/mod.rs | 5 +- src/paper.rs | 2 +- src/parse/mod.rs | 4 +- src/parse/parser.rs | 10 --- src/parse/scanner.rs | 7 -- src/parse/tokens.rs | 11 +--- src/source.rs | 15 ++--- src/syntax/ident.rs | 2 +- src/syntax/node.rs | 8 +-- src/syntax/pretty.rs | 16 ++--- src/syntax/span.rs | 42 +++++++----- src/syntax/token.rs | 8 +-- src/syntax/visit.rs | 8 +-- src/util/eco.rs | 36 +++++----- tests/typeset.rs | 5 +- 48 files changed, 434 insertions(+), 540 deletions(-) create mode 100644 src/eval/walk.rs diff --git a/src/color.rs b/src/color.rs index 124c20423..bf4cf05a0 100644 --- a/src/color.rs +++ b/src/color.rs @@ -12,14 +12,6 @@ pub enum Color { Rgba(RgbaColor), } -impl Display for Color { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - Self::Rgba(c) => Display::fmt(c, f), - } - } -} - impl Debug for Color { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { @@ -28,6 +20,14 @@ impl Debug for Color { } } +impl Display for Color { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + Self::Rgba(c) => Display::fmt(c, f), + } + } +} + /// An 8-bit RGBA color. #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] pub struct RgbaColor { @@ -97,16 +97,6 @@ impl FromStr for RgbaColor { } } -impl Display for RgbaColor { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b)?; - if self.a != 255 { - write!(f, "{:02x}", self.a)?; - } - Ok(()) - } -} - impl Debug for RgbaColor { fn fmt(&self, f: &mut Formatter) -> fmt::Result { if f.alternate() { @@ -121,18 +111,28 @@ impl Debug for RgbaColor { } } +impl Display for RgbaColor { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b)?; + if self.a != 255 { + write!(f, "{:02x}", self.a)?; + } + Ok(()) + } +} + /// The error when parsing an [`RgbaColor`] from a string fails. #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub struct ParseRgbaError; -impl std::error::Error for ParseRgbaError {} - -impl fmt::Display for ParseRgbaError { +impl Display for ParseRgbaError { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.pad("invalid color") } } +impl std::error::Error for ParseRgbaError {} + #[cfg(test)] mod tests { use super::*; diff --git a/src/diag.rs b/src/diag.rs index 90f640f6e..61432e932 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -22,7 +22,7 @@ pub type TypResult = Result>>; pub type StrResult = Result; /// An error in a source file. -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] +#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] pub struct Error { /// The erroneous location in the source code. pub span: Span, diff --git a/src/eval/array.rs b/src/eval/array.rs index e554b11ed..acf44ab2f 100644 --- a/src/eval/array.rs +++ b/src/eval/array.rs @@ -137,18 +137,18 @@ impl AddAssign for Array { } } -impl FromIterator for Array { - fn from_iter>(iter: T) -> Self { - Self(Rc::new(iter.into_iter().collect())) - } -} - impl Extend for Array { fn extend>(&mut self, iter: T) { Rc::make_mut(&mut self.0).extend(iter); } } +impl FromIterator for Array { + fn from_iter>(iter: T) -> Self { + Self(Rc::new(iter.into_iter().collect())) + } +} + impl IntoIterator for Array { type Item = Value; type IntoIter = std::vec::IntoIter; diff --git a/src/eval/capture.rs b/src/eval/capture.rs index a6e543f9d..f0a2b7292 100644 --- a/src/eval/capture.rs +++ b/src/eval/capture.rs @@ -5,7 +5,6 @@ use crate::syntax::visit::{immutable::visit_expr, Visit}; use crate::syntax::{Expr, Ident}; /// A visitor that captures variable slots. -#[derive(Debug)] pub struct CapturesVisitor<'a> { external: &'a Scopes<'a>, internal: Scopes<'a>, diff --git a/src/eval/dict.rs b/src/eval/dict.rs index 66baaec08..dfac04ed9 100644 --- a/src/eval/dict.rs +++ b/src/eval/dict.rs @@ -82,6 +82,12 @@ fn missing_key(key: &Str) -> String { format!("dictionary does not contain key: {}", key) } +impl Debug for Dict { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + f.debug_map().entries(self.0.iter()).finish() + } +} + impl Display for Dict { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.write_char('(')?; @@ -100,12 +106,6 @@ impl Display for Dict { } } -impl Debug for Dict { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - f.debug_map().entries(self.0.iter()).finish() - } -} - impl Add for Dict { type Output = Self; @@ -124,18 +124,18 @@ impl AddAssign for Dict { } } -impl FromIterator<(Str, Value)> for Dict { - fn from_iter>(iter: T) -> Self { - Self(Rc::new(iter.into_iter().collect())) - } -} - impl Extend<(Str, Value)> for Dict { fn extend>(&mut self, iter: T) { Rc::make_mut(&mut self.0).extend(iter); } } +impl FromIterator<(Str, Value)> for Dict { + fn from_iter>(iter: T) -> Self { + Self(Rc::new(iter.into_iter().collect())) + } +} + impl IntoIterator for Dict { type Item = (Str, Value); type IntoIter = std::collections::btree_map::IntoIter; diff --git a/src/eval/function.rs b/src/eval/function.rs index 7967090b6..57364d11d 100644 --- a/src/eval/function.rs +++ b/src/eval/function.rs @@ -38,6 +38,12 @@ impl Function { } } +impl Debug for Function { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + f.debug_struct("Function").field("name", &self.0.name).finish() + } +} + impl Display for Function { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.write_str(" fmt::Result { - f.debug_struct("Function").field("name", &self.0.name).finish() - } -} - impl PartialEq for Function { fn eq(&self, other: &Self) -> bool { // We cast to thin pointers for comparison. diff --git a/src/eval/mod.rs b/src/eval/mod.rs index f7a32127c..b8561a87e 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -13,6 +13,7 @@ mod scope; mod state; mod str; mod template; +mod walk; pub use self::str::*; pub use array::*; @@ -23,25 +24,24 @@ pub use scope::*; pub use state::*; pub use template::*; pub use value::*; +pub use walk::*; use std::cell::RefMut; use std::collections::HashMap; -use std::fmt::Write; use std::io; use std::mem; use std::path::PathBuf; use std::rc::Rc; use crate::diag::{At, Error, StrResult, Trace, Tracepoint, TypResult}; -use crate::geom::{Angle, Fractional, Gen, Length, Relative}; +use crate::geom::{Angle, Fractional, Length, Relative}; use crate::image::ImageStore; -use crate::layout::{ParChild, ParNode, StackChild, StackNode}; use crate::loading::Loader; use crate::parse::parse; use crate::source::{SourceId, SourceStore}; use crate::syntax::visit::Visit; use crate::syntax::*; -use crate::util::{EcoString, RefMutExt}; +use crate::util::RefMutExt; use crate::Context; /// Evaluate a parsed source file into a module. @@ -52,7 +52,7 @@ pub fn eval(ctx: &mut Context, source: SourceId, ast: &SyntaxTree) -> TypResult< } /// An evaluated module, ready for importing or instantiation. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Default, Clone)] pub struct Module { /// The top-level definitions that were bound in this module. pub scope: Scope, @@ -717,128 +717,3 @@ impl Access for CallExpr { }) } } - -/// Walk a syntax node and fill the currently built template. -pub trait Walk { - /// Walk the node. - fn walk(&self, ctx: &mut EvalContext) -> TypResult<()>; -} - -impl Walk for SyntaxTree { - fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> { - for node in self.iter() { - node.walk(ctx)?; - } - Ok(()) - } -} - -impl Walk for SyntaxNode { - fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> { - match self { - Self::Space => ctx.template.space(), - Self::Linebreak(_) => ctx.template.linebreak(), - Self::Parbreak(_) => ctx.template.parbreak(), - Self::Strong(_) => { - ctx.template.modify(|state| state.font_mut().strong ^= true); - } - Self::Emph(_) => { - ctx.template.modify(|state| state.font_mut().emph ^= true); - } - Self::Text(text) => ctx.template.text(text), - Self::Raw(raw) => raw.walk(ctx)?, - Self::Heading(heading) => heading.walk(ctx)?, - Self::List(list) => list.walk(ctx)?, - Self::Enum(enum_) => enum_.walk(ctx)?, - Self::Expr(expr) => match expr.eval(ctx)? { - Value::None => {} - Value::Int(v) => ctx.template.text(v.to_string()), - Value::Float(v) => ctx.template.text(v.to_string()), - Value::Str(v) => ctx.template.text(v), - Value::Template(v) => ctx.template += v, - // For values which can't be shown "naturally", we print the - // representation in monospace. - other => ctx.template.monospace(other.to_string()), - }, - } - Ok(()) - } -} - -impl Walk for RawNode { - fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> { - if self.block { - ctx.template.parbreak(); - } - - ctx.template.monospace(&self.text); - - if self.block { - ctx.template.parbreak(); - } - - Ok(()) - } -} - -impl Walk for HeadingNode { - fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> { - let level = self.level; - let body = self.body.eval(ctx)?; - - ctx.template.parbreak(); - ctx.template.save(); - ctx.template.modify(move |state| { - let font = state.font_mut(); - let upscale = 1.6 - 0.1 * level as f64; - font.size *= upscale; - font.strong = true; - }); - ctx.template += body; - ctx.template.restore(); - ctx.template.parbreak(); - - Ok(()) - } -} - -impl Walk for ListItem { - fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> { - let body = self.body.eval(ctx)?; - walk_item(ctx, '•'.into(), body); - Ok(()) - } -} - -impl Walk for EnumItem { - fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> { - let body = self.body.eval(ctx)?; - let mut label = EcoString::new(); - write!(&mut label, "{}.", self.number.unwrap_or(1)).unwrap(); - walk_item(ctx, label, body); - Ok(()) - } -} - -/// Walk a list or enum item, converting it into a stack. -fn walk_item(ctx: &mut EvalContext, label: EcoString, body: Template) { - ctx.template += Template::from_block(move |state| { - let label = ParNode { - dir: state.dirs.cross, - line_spacing: state.line_spacing(), - children: vec![ParChild::Text( - label.clone(), - state.aligns.cross, - Rc::clone(&state.font), - )], - }; - StackNode { - dirs: Gen::new(state.dirs.main, state.dirs.cross), - children: vec![ - StackChild::Any(label.into(), Gen::default()), - StackChild::Spacing((state.font.size / 2.0).into()), - StackChild::Any(body.to_stack(&state).into(), Gen::default()), - ], - } - }); -} diff --git a/src/eval/scope.rs b/src/eval/scope.rs index 2968ca205..0d7016873 100644 --- a/src/eval/scope.rs +++ b/src/eval/scope.rs @@ -12,7 +12,7 @@ use crate::util::EcoString; pub type Slot = Rc>; /// A stack of scopes. -#[derive(Debug, Default, Clone, PartialEq)] +#[derive(Debug, Default, Clone)] pub struct Scopes<'a> { /// The active scope. pub top: Scope, @@ -65,7 +65,7 @@ impl<'a> Scopes<'a> { } /// A map from variable names to variable slots. -#[derive(Default, Clone, PartialEq)] +#[derive(Default, Clone)] pub struct Scope { /// The mapping from names to slots. values: HashMap, diff --git a/src/eval/state.rs b/src/eval/state.rs index 760a830a9..055589152 100644 --- a/src/eval/state.rs +++ b/src/eval/state.rs @@ -63,7 +63,7 @@ impl Default for State { } /// Defines page properties. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct PageState { /// The class of this page. pub class: PaperClass, @@ -220,7 +220,7 @@ impl Default for FontState { } /// Font family definitions. -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct FamilyState { /// The user-defined list of font families. pub list: Rc>, @@ -250,7 +250,7 @@ impl Default for FamilyState { } /// Defines a line that is positioned over, under or on top of text. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct LineState { /// Stroke color of the line, defaults to the text color if `None`. pub stroke: Option, diff --git a/src/eval/str.rs b/src/eval/str.rs index 1a0e3e1f7..a358cd9fc 100644 --- a/src/eval/str.rs +++ b/src/eval/str.rs @@ -6,7 +6,7 @@ use crate::diag::StrResult; use crate::util::EcoString; /// A string value with inline storage and clone-on-write semantics. -#[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd)] pub struct Str(EcoString); impl Str { @@ -46,6 +46,20 @@ impl Str { } } +impl Deref for Str { + type Target = str; + + fn deref(&self) -> &str { + self.0.deref() + } +} + +impl Debug for Str { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Debug::fmt(&self.0, f) + } +} + impl Display for Str { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.write_char('"')?; @@ -63,20 +77,6 @@ impl Display for Str { } } -impl Debug for Str { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - Debug::fmt(&self.0, f) - } -} - -impl Deref for Str { - type Target = str; - - fn deref(&self) -> &str { - self.0.deref() - } -} - impl Add for Str { type Output = Self; diff --git a/src/eval/template.rs b/src/eval/template.rs index 2293796b7..92b3eb864 100644 --- a/src/eval/template.rs +++ b/src/eval/template.rs @@ -160,18 +160,18 @@ impl Template { } } -impl Display for Template { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - f.pad("