diff options
Diffstat (limited to 'src')
47 files changed, 417 insertions, 524 deletions
diff --git a/src/color.rs b/src/color.rs index 124c2042..bf4cf05a 100644 --- a/src/color.rs +++ b/src/color.rs @@ -12,18 +12,18 @@ pub enum Color { Rgba(RgbaColor), } -impl Display for Color { +impl Debug for Color { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Self::Rgba(c) => Display::fmt(c, f), + Self::Rgba(c) => Debug::fmt(c, f), } } } -impl Debug for Color { +impl Display for Color { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Self::Rgba(c) => Debug::fmt(c, f), + Self::Rgba(c) => Display::fmt(c, f), } } } @@ -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 90f640f6..61432e93 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -22,7 +22,7 @@ pub type TypResult<T> = Result<T, Box<Vec<Error>>>; pub type StrResult<T> = Result<T, String>; /// 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 e554b11e..acf44ab2 100644 --- a/src/eval/array.rs +++ b/src/eval/array.rs @@ -137,18 +137,18 @@ impl AddAssign for Array { } } -impl FromIterator<Value> for Array { - fn from_iter<T: IntoIterator<Item = Value>>(iter: T) -> Self { - Self(Rc::new(iter.into_iter().collect())) - } -} - impl Extend<Value> for Array { fn extend<T: IntoIterator<Item = Value>>(&mut self, iter: T) { Rc::make_mut(&mut self.0).extend(iter); } } +impl FromIterator<Value> for Array { + fn from_iter<T: IntoIterator<Item = Value>>(iter: T) -> Self { + Self(Rc::new(iter.into_iter().collect())) + } +} + impl IntoIterator for Array { type Item = Value; type IntoIter = std::vec::IntoIter<Value>; diff --git a/src/eval/capture.rs b/src/eval/capture.rs index a6e543f9..f0a2b729 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 66baaec0..dfac04ed 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<T: IntoIterator<Item = (Str, Value)>>(iter: T) -> Self { - Self(Rc::new(iter.into_iter().collect())) - } -} - impl Extend<(Str, Value)> for Dict { fn extend<T: IntoIterator<Item = (Str, Value)>>(&mut self, iter: T) { Rc::make_mut(&mut self.0).extend(iter); } } +impl FromIterator<(Str, Value)> for Dict { + fn from_iter<T: IntoIterator<Item = (Str, Value)>>(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<Str, Value>; diff --git a/src/eval/function.rs b/src/eval/function.rs index 7967090b..57364d11 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("<function")?; @@ -49,12 +55,6 @@ impl Display for Function { } } -impl Debug for Function { - fn fmt(&self, f: &mut Formatter) -> 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 f7a32127..b8561a87 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 2968ca20..0d701687 100644 --- a/src/eval/scope.rs +++ b/src/eval/scope.rs @@ -12,7 +12,7 @@ use crate::util::EcoString; pub type Slot = Rc<RefCell<Value>>; /// 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<EcoString, Slot>, diff --git a/src/eval/state.rs b/src/eval/state.rs index 760a830a..05558915 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<Vec<FontFamily>>, @@ -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<Paint>, diff --git a/src/eval/str.rs b/src/eval/str.rs index 1a0e3e1f..a358cd9f 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 2293796b..92b3eb86 100644 --- a/src/eval/template.rs +++ b/src/eval/template.rs @@ -160,15 +160,15 @@ impl Template { } } -impl Display for Template { +impl Debug for Template { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - f.pad("<template>") + f.pad("Template { .. }") } } -impl Debug for Template { +impl Display for Template { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - f.pad("Template { .. }") + f.pad("<template>") } } @@ -465,11 +465,11 @@ impl ParBuilder { } fn push_inner(&mut self, child: ParChild) { - if let ParChild::Text(curr_text, curr_props, curr_align) = &child { - if let Some(ParChild::Text(prev_text, prev_props, prev_align)) = + if let ParChild::Text(curr_text, curr_align, curr_props) = &child { + if let Some(ParChild::Text(prev_text, prev_align, prev_props)) = self.children.last_mut() { - if prev_align == curr_align && prev_props == curr_props { + if prev_align == curr_align && Rc::ptr_eq(prev_props, curr_props) { prev_text.push_str(&curr_text); return; } diff --git a/src/eval/value.rs b/src/eval/value.rs index 99efc2e5..5edf0362 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -144,6 +144,12 @@ impl From<usize> for Value { } } +impl From<RgbaColor> for Value { + fn from(v: RgbaColor) -> Self { + Self::Color(Color::Rgba(v)) + } +} + impl From<&str> for Value { fn from(v: &str) -> Self { Self::Str(v.into()) @@ -162,12 +168,6 @@ impl From<EcoString> for Value { } } -impl From<RgbaColor> for Value { - fn from(v: RgbaColor) -> Self { - Self::Color(Color::Rgba(v)) - } -} - impl From<Dynamic> for Value { fn from(v: Dynamic) -> Self { Self::Dyn(v) @@ -181,7 +181,7 @@ impl Dynamic { /// Create a new instance from any value that satisifies the required bounds. pub fn new<T>(any: T) -> Self where - T: Type + Debug + Display + Clone + PartialEq + 'static, + T: Type + Debug + Display + PartialEq + 'static, { Self(Rc::new(any)) } @@ -202,15 +202,15 @@ impl Dynamic { } } -impl Display for Dynamic { +impl Debug for Dynamic { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - Display::fmt(&self.0, f) + Debug::fmt(&self.0, f) } } -impl Debug for Dynamic { +impl Display for Dynamic { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - Debug::fmt(&self.0, f) + Display::fmt(&self.0, f) } } @@ -228,7 +228,7 @@ trait Bounds: Debug + Display + 'static { impl<T> Bounds for T where - T: Type + Debug + Display + Clone + PartialEq + 'static, + T: Type + Debug + Display + PartialEq + 'static, { fn as_any(&self) -> &dyn Any { self @@ -309,12 +309,6 @@ macro_rules! primitive { const TYPE_NAME: &'static str = $name; } - impl From<$type> for Value { - fn from(v: $type) -> Self { - Value::$variant(v) - } - } - impl Cast<Value> for $type { fn is(value: &Value) -> bool { matches!(value, Value::$variant(_) $(| Value::$other(_))*) @@ -332,6 +326,12 @@ macro_rules! primitive { } } } + + impl From<$type> for Value { + fn from(v: $type) -> Self { + Value::$variant(v) + } + } }; } @@ -342,17 +342,17 @@ macro_rules! dynamic { const TYPE_NAME: &'static str = $name; } - impl From<$type> for $crate::eval::Value { - fn from(v: $type) -> Self { - $crate::eval::Value::Dyn($crate::eval::Dynamic::new(v)) - } - } - castable! { $type: <Self as $crate::eval::Type>::TYPE_NAME, $($tts)* @this: Self => this.clone(), } + + impl From<$type> for $crate::eval::Value { + fn from(v: $type) -> Self { + $crate::eval::Value::Dyn($crate::eval::Dynamic::new(v)) + } + } }; } diff --git a/src/eval/walk.rs b/src/eval/walk.rs new file mode 100644 index 00000000..4c6a1605 --- /dev/null +++ b/src/eval/walk.rs @@ -0,0 +1,129 @@ +use std::fmt::Write; +use std::rc::Rc; + +use super::{Eval, EvalContext, Template, Value}; +use crate::diag::TypResult; +use crate::geom::Gen; +use crate::layout::{ParChild, ParNode, StackChild, StackNode}; +use crate::syntax::*; +use crate::util::EcoString; + +/// 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(|s| s.font_mut().strong ^= true), + Self::Emph(_) => ctx.template.modify(|s| s.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 ListNode { + fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> { + let body = self.body.eval(ctx)?; + walk_item(ctx, '•'.into(), body); + Ok(()) + } +} + +impl Walk for EnumNode { + 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(()) + } +} + +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/font.rs b/src/font.rs index 978fb601..dadf6830 100644 --- a/src/font.rs +++ b/src/font.rs @@ -14,8 +14,7 @@ use crate::geom::Length; use crate::loading::{FileHash, Loader}; /// A unique identifier for a loaded font face. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[derive(Serialize, Deserialize)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] pub struct FaceId(u32); impl FaceId { @@ -271,7 +270,7 @@ impl Face { /// A length in em units. /// /// `1em` is the same as the font size. -#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, PartialOrd)] +#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] pub struct Em(N64); impl Em { @@ -343,11 +342,15 @@ impl Display for VerticalFontMetric { } /// A generic or named font family. -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Debug, Clone, Eq, PartialEq, Hash)] pub enum FontFamily { + /// A family that has "serifs", small strokes attached to letters. Serif, + /// A family in which glyphs do not have "serifs", small attached strokes. SansSerif, + /// A family in which (almost) all glyphs are of equal width. Monospace, + /// A specific family with a name. Named(String), } @@ -575,15 +578,6 @@ impl Default for FontWeight { } } -impl Display for FontWeight { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self.to_str() { - Some(name) => f.pad(name), - None => write!(f, "{}", self.0), - } - } -} - impl Debug for FontWeight { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.pad(match *self { @@ -601,6 +595,15 @@ impl Debug for FontWeight { } } +impl Display for FontWeight { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self.to_str() { + Some(name) => f.pad(name), + None => write!(f, "{}", self.0), + } + } +} + /// The width of a font face. #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Serialize, Deserialize)] @@ -707,15 +710,6 @@ impl Default for FontStretch { } } -impl Display for FontStretch { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self.to_str() { - Some(name) => f.pad(name), - None => write!(f, "{}", self.to_ratio()), - } - } -} - impl Debug for FontStretch { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.pad(match *self { @@ -733,6 +727,15 @@ impl Debug for FontStretch { } } +impl Display for FontStretch { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self.to_str() { + Some(name) => f.pad(name), + None => write!(f, "{}", self.to_ratio()), + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/geom/angle.rs b/src/geom/angle.rs index 8f18210c..cf3e49a0 100644 --- a/src/geom/angle.rs +++ b/src/geom/angle.rs @@ -1,8 +1,11 @@ -use super::*; use decorum::N64; +use serde::{Deserialize, Serialize}; + +use super::*; /// An angle. #[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Serialize, Deserialize)] pub struct Angle(N64); impl Angle { @@ -52,6 +55,13 @@ impl Angle { } } +impl Debug for Angle { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + let unit = AngularUnit::Deg; + write!(f, "{}{}", self.to_unit(unit), unit) + } +} + impl Display for Angle { fn fmt(&self, f: &mut Formatter) -> fmt::Result { // Format with the unit that yields the shortest output, preferring @@ -66,13 +76,6 @@ impl Display for Angle { } } -impl Debug for Angle { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - let unit = AngularUnit::Deg; - write!(f, "{}{}", self.to_unit(unit), unit) - } -} - impl Neg for Angle { type Output = Self; @@ -134,7 +137,7 @@ impl Sum for Angle { } } /// Different units of angular measurement. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum AngularUnit { /// Radians. Rad, diff --git a/src/geom/fr.rs b/src/geom/fr.rs index 1768366a..eaf539d9 100644 --- a/src/geom/fr.rs +++ b/src/geom/fr.rs @@ -33,15 +33,15 @@ impl Fractional { } } -impl Display for Fractional { +impl Debug for Fractional { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "{}fr", self.get()) + Display::fmt(self, f) } } -impl Debug for Fractional { +impl Display for Fractional { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - Display::fmt(self, f) + write!(f, "{}fr", self.get()) } } diff --git a/src/geom/length.rs b/src/geom/length.rs index 343b523c..3510fa6f 100644 --- a/src/geom/length.rs +++ b/src/geom/length.rs @@ -126,6 +126,13 @@ impl Length { } } +impl Debug for Length { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + let unit = LengthUnit::Pt; + write!(f, "{}{}", self.to_unit(unit), unit) + } +} + impl Display for Length { fn fmt(&self, f: &mut Formatter) -> fmt::Result { use LengthUnit::*; @@ -142,13 +149,6 @@ impl Display for Length { } } -impl Debug for Length { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - let unit = LengthUnit::Pt; - write!(f, "{}{}", self.to_unit(unit), unit) - } -} - impl Neg for Length { type Output = Self; @@ -217,7 +217,7 @@ impl<'a> Sum<&'a Length> for Length { } /// Different units of length measurement. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum LengthUnit { /// Points. Pt, diff --git a/src/geom/linear.rs b/src/geom/linear.rs index 38d19b13..6a20b826 100644 --- a/src/geom/linear.rs +++ b/src/geom/linear.rs @@ -47,15 +47,15 @@ impl Linear { } } -impl Display for Linear { +impl Debug for Linear { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "{} + {}", self.rel, self.abs) + write!(f, "{:?} + {:?}", self.rel, self.abs) } } -impl Debug for Linear { +impl Display for Linear { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "{:?} + {:?}", self.rel, self.abs) + write!(f, "{} + {}", self.rel, self.abs) } } diff --git a/src/geom/relative.rs b/src/geom/relative.rs index 149c0b9c..7785788c 100644 --- a/src/geom/relative.rs +++ b/src/geom/relative.rs @@ -46,15 +46,15 @@ impl Relative { } } -impl Display for Relative { +impl Debug for Relative { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "{}%", 100.0 * self.get()) + Display::fmt(self, f) } } -impl Debug for Relative { +impl Display for Relative { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - Display::fmt(self, f) + write!(f, "{}%", 100.0 * self.get()) } } diff --git a/src/geom/sides.rs b/src/geom/sides.rs index f9fdc01f..d4fdf247 100644 --- a/src/geom/sides.rs +++ b/src/geom/sides.rs @@ -33,6 +33,14 @@ impl<T> Sides<T> { } } +impl Sides<Length> { + /// A size with `left` and `right` summed into `width`, and `top` and + /// `bottom` summed into `height`. + pub fn size(self) -> Size { + Size::new(self.left + self.right, self.top + self.bottom) + } +} + impl Sides<Linear> { /// Resolve the linear sides relative to the given `size`. pub fn resolve(self, size: Size) -> Sides<Length> { @@ -45,14 +53,6 @@ impl Sides<Linear> { } } -impl Sides<Length> { - /// A size with `left` and `right` summed into `width`, and `top` and - /// `bottom` summed into `height`. - pub fn size(self) -> Size { - Size::new(self.left + self.right, self.top + self.bottom) - } -} - impl<T> Get<Side> for Sides<T> { type Component = T; diff --git a/src/image.rs b/src/image.rs index 6ccfb11d..455f3105 100644 --- a/src/image.rs +++ b/src/image.rs @@ -13,8 +13,7 @@ use serde::{Deserialize, Serialize}; use crate::loading::{FileHash, Loader}; /// A unique identifier for a loaded image. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[derive(Serialize, Deserialize)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] pub struct ImageId(u32); impl ImageId { diff --git a/src/layout/background.rs b/src/layout/background.rs index 793782fd..306afd67 100644 --- a/src/layout/background.rs +++ b/src/layout/background.rs @@ -1,7 +1,6 @@ use super::*; /// A node that places a rectangular filled background behind its child. -#[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "layout-cache", derive(Hash))] pub struct BackgroundNode { /// The kind of shape to use as a background. diff --git a/src/layout/constraints.rs b/src/layout/constraints.rs index 1a26daeb..d808abd9 100644 --- a/src/layout/constraints.rs +++ b/src/layout/constraints.rs @@ -1,5 +1,3 @@ -use std::ops::Deref; - use super::*; /// Carries an item that is only valid in certain regions and the constraints @@ -12,14 +10,6 @@ pub struct Constrained<T> { pub constraints: Constraints, } -impl<T> Deref for Constrained<T> { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.item - } -} - /// Describe regions that match them. #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub struct Constraints { diff --git a/src/layout/fixed.rs b/src/layout/fixed.rs index 7f292f14..02660d1d 100644 --- a/src/layout/fixed.rs +++ b/src/layout/fixed.rs @@ -3,7 +3,6 @@ use decorum::N64; use super::*; /// A node that can fix its child's width and height. -#[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "layout-cache", derive(Hash))] pub struct FixedNode { /// The fixed width, if any. @@ -78,7 +77,7 @@ impl Layout for FixedNode { // relayout with expansion. if let Some(aspect) = aspect { if width.is_none() && height.is_none() { - let needed = frames[0].size.cap(size); + let needed = frames[0].item.size.cap(size); let width = needed.width.max(aspect * needed.height); regions.current = Size::new(width, width / aspect); regions.expand = Spec::splat(true); diff --git a/src/layout/grid.rs b/src/layout/grid.rs index d9b56b48..b4a1fe79 100644 --- a/src/layout/grid.rs +++ b/src/layout/grid.rs @@ -1,7 +1,6 @@ use super::*; /// A node that arranges its children in a grid. -#[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "layout-cache", derive(Hash))] pub struct GridNode { /// The `main` and `cross` directions of this grid. @@ -256,7 +255,7 @@ impl<'a> GridLayouter<'a> { for node in (0 .. self.rows.len()).filter_map(|y| self.cell(x, y)) { let size = Gen::new(available, Length::inf()).to_size(self.main); let regions = Regions::one(size, size, Spec::splat(false)); - let frame = node.layout(ctx, ®ions).remove(0); + let frame = node.layout(ctx, ®ions).remove(0).item; resolved.set_max(frame.size.get(self.cross)); } @@ -353,7 +352,7 @@ impl<'a> GridLayouter<'a> { let mut sizes = node .layout(ctx, &self.regions) .into_iter() - .map(|frame| frame.size.get(self.main)); + .map(|frame| frame.item.size.get(self.main)); if let Some(size) = sizes.next() { first.set_max(size); diff --git a/src/layout/image.rs b/src/layout/image.rs index 02a907f5..e3e5e741 100644 --- a/src/layout/image.rs +++ b/src/layout/image.rs @@ -4,7 +4,6 @@ use crate::image::ImageId; use ::image::GenericImageView; /// An image node. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "layout-cache", derive(Hash))] pub struct ImageNode { /// The id of the image file. diff --git a/src/layout/pad.rs b/src/layout/pad.rs index 51025e3c..3075472b 100644 --- a/src/layout/pad.rs +++ b/src/layout/pad.rs @@ -1,7 +1,6 @@ use super::*; /// A node that adds padding to its child. -#[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "layout-cache", derive(Hash))] pub struct PadNode { /// The amount of padding. diff --git a/src/layout/par.rs b/src/layout/par.rs index 317a91ad..84d784b0 100644 --- a/src/layout/par.rs +++ b/src/layout/par.rs @@ -1,4 +1,3 @@ -use std::fmt::{self, Debug, Formatter}; use std::rc::Rc; use unicode_bidi::{BidiInfo, Level}; @@ -11,7 +10,6 @@ use crate::util::{EcoString, RangeExt, SliceExt}; type Range = std::ops::Range<usize>; /// A node that arranges its children into a paragraph. -#[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "layout-cache", derive(Hash))] pub struct ParNode { /// The inline direction of this paragraph. @@ -23,7 +21,6 @@ pub struct ParNode { } /// A child of a paragraph node. -#[derive(Clone, Eq, PartialEq)] #[cfg_attr(feature = "layout-cache", derive(Hash))] pub enum ParChild { /// Spacing between other nodes. @@ -94,18 +91,6 @@ impl From<ParNode> for LayoutNode { } } -impl Debug for ParChild { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - Self::Spacing(amount) => write!(f, "Spacing({:?})", amount), - Self::Text(text, align, _) => write!(f, "Text({:?}, {:?})", text, align), - Self::Any(any, align) => { - f.debug_tuple("Any").field(any).field(align).finish() - } - } - } -} - /// A paragraph representation in which children are already layouted and text /// is separated into shapable runs. struct ParLayouter<'a> { diff --git a/src/layout/shaping.rs b/src/layout/shaping.rs index ba8704ea..fad7f234 100644 --- a/src/layout/shaping.rs +++ b/src/layout/shaping.rs @@ -1,5 +1,4 @@ use std::borrow::Cow; -use std::fmt::{self, Debug, Formatter}; use std::ops::Range; use rustybuzz::UnicodeBuffer; @@ -11,12 +10,45 @@ use crate::geom::{Dir, Length, Point, Size}; use crate::layout::Geometry; use crate::util::SliceExt; +/// Shape text into [`ShapedText`]. +pub fn shape<'a>( + ctx: &mut LayoutContext, + text: &'a str, + dir: Dir, + state: &'a FontState, +) -> ShapedText<'a> { + let mut glyphs = vec![]; + if !text.is_empty() { + shape_segment( + ctx, + &mut glyphs, + 0, + text, + dir, + state.size, + state.variant(), + state.families(), + None, + ); + } + + let (size, baseline) = measure(ctx, &glyphs, state); + + ShapedText { + text, + dir, + state, + size, + baseline, + glyphs: Cow::Owned(glyphs), + } +} + /// The result of shaping text. /// /// This type contains owned or borrowed shaped text runs, which can be /// measured, used to reshape substrings more quickly and converted into a /// frame. -#[derive(Clone)] pub struct ShapedText<'a> { /// The text that was shaped. pub text: &'a str, @@ -33,7 +65,7 @@ pub struct ShapedText<'a> { } /// A single glyph resulting from shaping. -#[derive(Debug, Copy, Clone)] +#[derive(Copy, Clone)] pub struct ShapedGlyph { /// The font face the glyph is contained in. pub face_id: FaceId, @@ -51,13 +83,6 @@ pub struct ShapedGlyph { pub safe_to_break: bool, } -/// A visual side. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -enum Side { - Left, - Right, -} - impl<'a> ShapedText<'a> { /// Build the shaped text's frame. pub fn build(&self, ctx: &LayoutContext) -> Frame { @@ -174,44 +199,10 @@ impl<'a> ShapedText<'a> { } } -impl Debug for ShapedText<'_> { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "Shaped({:?})", self.text) - } -} - -/// Shape text into [`ShapedText`]. -pub fn shape<'a>( - ctx: &mut LayoutContext, - text: &'a str, - dir: Dir, - state: &'a FontState, -) -> ShapedText<'a> { - let mut glyphs = vec![]; - if !text.is_empty() { - shape_segment( - ctx, - &mut glyphs, - 0, - text, - dir, - state.size, - state.variant(), - state.families(), - None, - ); - } - - let (size, baseline) = measure(ctx, &glyphs, state); - - ShapedText { - text, - dir, - state, - size, - baseline, - glyphs: Cow::Owned(glyphs), - } +/// A visual side. +enum Side { + Left, + Right, } /// Shape text with font fallback using the `families` iterator. diff --git a/src/layout/stack.rs b/src/layout/stack.rs index 51d17807..d07f68d7 100644 --- a/src/layout/stack.rs +++ b/src/layout/stack.rs @@ -1,7 +1,6 @@ use super::*; /// A node that stacks its children. -#[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "layout-cache", derive(Hash))] pub struct StackNode { /// The `main` and `cross` directions of this stack. @@ -14,7 +13,6 @@ pub struct StackNode { } /// A child of a stack node. -#[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "layout-cache", derive(Hash))] pub enum StackChild { /// Spacing between other nodes. diff --git a/src/layout/tree.rs b/src/layout/tree.rs index 1899a4d2..05f94c38 100644 --- a/src/layout/tree.rs +++ b/src/layout/tree.rs @@ -1,7 +1,6 @@ use super::*; use std::any::Any; -use std::fmt::{self, Debug, Formatter}; #[cfg(feature = "layout-cache")] use std::hash::{Hash, Hasher}; @@ -10,7 +9,6 @@ use std::hash::{Hash, Hasher}; use fxhash::FxHasher64; /// A tree of layout nodes. -#[derive(Debug, Clone, Eq, PartialEq)] pub struct LayoutTree { /// Runs of pages with the same properties. pub runs: Vec<PageRun>, @@ -24,7 +22,6 @@ impl LayoutTree { } /// A run of pages that all have the same properties. -#[derive(Debug, Clone, Eq, PartialEq)] pub struct PageRun { /// The size of each page. pub size: Size, @@ -47,7 +44,7 @@ impl PageRun { /// A dynamic layouting node. pub struct LayoutNode { - node: Box<dyn Bounds>, + node: Box<dyn Layout>, #[cfg(feature = "layout-cache")] hash: u64, } @@ -57,7 +54,7 @@ impl LayoutNode { #[cfg(not(feature = "layout-cache"))] pub fn new<T>(node: T) -> Self where - T: Layout + Debug + Clone + Eq + PartialEq + 'static, + T: Layout + 'static, { Self { node: Box::new(node) } } @@ -66,7 +63,7 @@ impl LayoutNode { #[cfg(feature = "layout-cache")] pub fn new<T>(node: T) -> Self where - T: Layout + Debug + Clone + Eq + PartialEq + Hash + 'static, + T: Layout + Hash + 'static, { let hash = { let mut state = FxHasher64::default(); @@ -99,60 +96,9 @@ impl Layout for LayoutNode { } } -impl Debug for LayoutNode { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - self.node.fmt(f) - } -} - -impl Clone for LayoutNode { - fn clone(&self) -> Self { - Self { - node: self.node.dyn_clone(), - #[cfg(feature = "layout-cache")] - hash: self.hash, - } - } -} - -impl Eq for LayoutNode {} - -impl PartialEq for LayoutNode { - fn eq(&self, other: &Self) -> bool { - self.node.dyn_eq(other.node.as_ref()) - } -} - #[cfg(feature = "layout-cache")] impl Hash for LayoutNode { fn hash<H: Hasher>(&self, state: &mut H) { state.write_u64(self.hash); } } - -trait Bounds: Layout + Debug + 'static { - fn as_any(&self) -> &dyn Any; - fn dyn_eq(&self, other: &dyn Bounds) -> bool; - fn dyn_clone(&self) -> Box<dyn Bounds>; -} - -impl<T> Bounds for T -where - T: Layout + Debug + Eq + PartialEq + Clone + 'static, -{ - fn as_any(&self) -> &dyn Any { - self - } - - fn dyn_eq(&self, other: &dyn Bounds) -> bool { - if let Some(other) = other.as_any().downcast_ref::<Self>() { - self == other - } else { - false - } - } - - fn dyn_clone(&self) -> Box<dyn Bounds> { - Box::new(self.clone()) - } -} diff --git a/src/loading/fs.rs b/src/loading/fs.rs index 46e3dba1..d03df3ba 100644 --- a/src/loading/fs.rs +++ b/src/loading/fs.rs @@ -13,7 +13,7 @@ use crate::font::FaceInfo; /// Loads fonts and files from the local file system. /// /// _This is only available when the `fs` feature is enabled._ -#[derive(Debug, Default, Clone)] +#[derive(Default)] pub struct FsLoader { faces: Vec<FaceInfo>, } diff --git a/src/loading/mem.rs b/src/loading/mem.rs index d7fb178f..9ff02d2d 100644 --- a/src/loading/mem.rs +++ b/src/loading/mem.rs @@ -9,7 +9,7 @@ use crate::font::FaceInfo; use crate::util::PathExt; /// Loads fonts and files from an in-memory storage. -#[derive(Debug, Default, Clone)] +#[derive(Default)] pub struct MemLoader { faces: Vec<FaceInfo>, files: HashMap<PathBuf, Cow<'static, [u8]>>, diff --git a/src/loading/mod.rs b/src/loading/mod.rs index e6cca012..4841e752 100644 --- a/src/loading/mod.rs +++ b/src/loading/mod.rs @@ -11,15 +11,12 @@ pub use mem::*; use std::io; use std::path::Path; -use serde::{Deserialize, Serialize}; - use crate::font::FaceInfo; /// A hash that identifies a file. /// /// Such a hash can be [resolved](Loader::resolve) from a path. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[derive(Serialize, Deserialize)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct FileHash(pub u64); /// Loads resources from a local or remote source. diff --git a/src/paper.rs b/src/paper.rs index 1a3391a1..5c9775b8 100644 --- a/src/paper.rs +++ b/src/paper.rs @@ -3,7 +3,7 @@ use crate::geom::{Length, Linear, Relative, Sides, Size}; /// Specification of a paper. -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone)] pub struct Paper { /// The broad class this paper belongs to. class: PaperClass, diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 37b65c04..649b4eb8 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -201,7 +201,7 @@ fn list_item(p: &mut Parser) -> SyntaxNode { let column = p.column(start); p.eat_assert(Token::Hyph); let body = tree_indented(p, column); - SyntaxNode::List(Box::new(ListItem { span: p.span_from(start), body })) + SyntaxNode::List(Box::new(ListNode { span: p.span_from(start), body })) } /// Parse a single enum item. @@ -210,7 +210,7 @@ fn enum_item(p: &mut Parser, number: Option<usize>) -> SyntaxNode { let column = p.column(start); p.eat_assert(Token::Numbering(number)); let body = tree_indented(p, column); - SyntaxNode::Enum(Box::new(EnumItem { + SyntaxNode::Enum(Box::new(EnumNode { span: p.span_from(start), number, body, diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 83e77a6a..c035319d 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -1,4 +1,3 @@ -use std::fmt::{self, Debug, Formatter}; use std::ops::Range; use super::{TokenMode, Tokens}; @@ -28,7 +27,6 @@ pub struct Parser<'s> { } /// A logical group of tokens, e.g. `[...]`. -#[derive(Debug, Copy, Clone)] struct GroupEntry { /// The start index of the group. Used by `Parser::end_group` to return the /// group's full span. @@ -391,11 +389,3 @@ impl<'s> Parser<'s> { self.groups.iter().any(|g| g.kind == kind) } } - -impl Debug for Parser<'_> { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - let mut s = self.tokens.scanner(); - s.jump(self.next_start()); - write!(f, "Parser({}|{})", s.eaten(), s.rest()) - } -} diff --git a/src/parse/scanner.rs b/src/parse/scanner.rs index f893c4d3..8e3e4278 100644 --- a/src/parse/scanner.rs +++ b/src/parse/scanner.rs @@ -1,4 +1,3 @@ -use std::fmt::{self, Debug, Formatter}; use std::slice::SliceIndex; /// A featureful char-based scanner. @@ -153,12 +152,6 @@ impl<'s> Scanner<'s> { } } -impl Debug for Scanner<'_> { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "Scanner({}|{})", self.eaten(), self.rest()) - } -} - /// Whether this character denotes a newline. #[inline] pub fn is_newline(character: char) -> bool { diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs index 684e340e..91d3ab7f 100644 --- a/src/parse/tokens.rs +++ b/src/parse/tokens.rs @@ -1,11 +1,8 @@ -use std::fmt::{self, Debug, Formatter}; - use super::{is_newline, Scanner}; use crate::geom::{AngularUnit, LengthUnit}; use crate::syntax::*; /// An iterator over the tokens of a string of source code. -#[derive(Clone)] pub struct Tokens<'s> { s: Scanner<'s>, mode: TokenMode, @@ -481,12 +478,6 @@ impl<'s> Tokens<'s> { } } -impl Debug for Tokens<'_> { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "Tokens({}|{})", self.s.eaten(), self.s.rest()) - } -} - fn keyword(ident: &str) -> Option<Token<'static>> { Some(match ident { "not" => Token::Not, @@ -512,6 +503,8 @@ fn keyword(ident: &str) -> Option<Token<'static>> { #[cfg(test)] #[allow(non_snake_case)] mod tests { + use std::fmt::Debug; + use super::*; use Option::None; diff --git a/src/source.rs b/src/source.rs index 877fd729..b02af1b6 100644 --- a/src/source.rs +++ b/src/source.rs @@ -15,8 +15,7 @@ use crate::parse::{is_newline, Scanner}; use crate::util::PathExt; /// A unique identifier for a loaded source file. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[derive(Serialize, Deserialize)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] pub struct SourceId(u32); impl SourceId { @@ -252,12 +251,6 @@ impl SourceFile { } } -impl AsRef<str> for SourceFile { - fn as_ref(&self) -> &str { - &self.src - } -} - /// The indices at which lines start (right behind newlines). /// /// The beginning of the string (index 0) is not returned. @@ -276,6 +269,12 @@ fn newlines(string: &str) -> impl Iterator<Item = usize> + '_ { }) } +impl AsRef<str> for SourceFile { + fn as_ref(&self) -> &str { + &self.src + } +} + #[cfg(feature = "codespan-reporting")] impl<'a> Files<'a> for SourceStore { type FileId = SourceId; diff --git a/src/syntax/ident.rs b/src/syntax/ident.rs index 66ffb46d..c47e6fb1 100644 --- a/src/syntax/ident.rs +++ b/src/syntax/ident.rs @@ -12,7 +12,7 @@ use crate::util::EcoString; /// - `_` and `-` as continuing characters. /// /// [uax31]: http://www.unicode.org/reports/tr31/ -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Debug, Clone, PartialEq)] pub struct Ident { /// The source code location. pub span: Span, diff --git a/src/syntax/node.rs b/src/syntax/node.rs index 4ff69c17..875d32f5 100644 --- a/src/syntax/node.rs +++ b/src/syntax/node.rs @@ -20,9 +20,9 @@ pub enum SyntaxNode { /// A section heading: `= Introduction`. Heading(Box<HeadingNode>), /// An item in an unordered list: `- ...`. - List(Box<ListItem>), + List(Box<ListNode>), /// An item in an enumeration (ordered list): `1. ...`. - Enum(Box<EnumItem>), + Enum(Box<EnumNode>), /// An expression. Expr(Expr), } @@ -55,7 +55,7 @@ pub struct HeadingNode { /// An item in an unordered list: `- ...`. #[derive(Debug, Clone, PartialEq)] -pub struct ListItem { +pub struct ListNode { /// The source code location. pub span: Span, /// The contents of the list item. @@ -64,7 +64,7 @@ pub struct ListItem { /// An item in an enumeration (ordered list): `1. ...`. #[derive(Debug, Clone, PartialEq)] -pub struct EnumItem { +pub struct EnumNode { /// The source code location. pub span: Span, /// The number, if any. diff --git a/src/syntax/pretty.rs b/src/syntax/pretty.rs index cf9ee69d..3c59914f 100644 --- a/src/syntax/pretty.rs +++ b/src/syntax/pretty.rs @@ -94,14 +94,14 @@ impl Pretty for SyntaxNode { Self::Emph(_) => p.push('_'), Self::Text(text) => p.push_str(text), Self::Raw(raw) => raw.pretty(p), - Self::Heading(n) => n.pretty(p), - Self::List(n) => n.pretty(p), - Self::Enum(n) => n.pretty(p), - Self::Expr(n) => { - if n.has_short_form() { + Self::Heading(heading) => heading.pretty(p), + Self::List(list) => list.pretty(p), + Self::Enum(enum_) => enum_.pretty(p), + Self::Expr(expr) => { + if expr.has_short_form() { p.push('#'); } - n.pretty(p); + expr.pretty(p); } } } @@ -173,14 +173,14 @@ impl Pretty for HeadingNode { } } -impl Pretty for ListItem { +impl Pretty for ListNode { fn pretty(&self, p: &mut Printer) { p.push_str("- "); self.body.pretty(p); } } -impl Pretty for EnumItem { +impl Pretty for EnumNode { fn pretty(&self, p: &mut Printer) { if let Some(number) = self.number { write!(p, "{}", number).unwrap(); diff --git a/src/syntax/span.rs b/src/syntax/span.rs index e4a4fd32..bfb9e755 100644 --- a/src/syntax/span.rs +++ b/src/syntax/span.rs @@ -1,3 +1,4 @@ +use std::cmp::Ordering; use std::fmt::{self, Debug, Formatter}; use std::ops::{Add, Range}; @@ -6,8 +7,7 @@ use serde::{Deserialize, Serialize}; use crate::source::SourceId; /// A value with the span it corresponds to in the source code. -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] -#[derive(Serialize, Deserialize)] +#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize)] pub struct Spanned<T> { /// The spanned value. pub v: T, @@ -48,8 +48,7 @@ impl<T: Debug> Debug for Spanned<T> { } /// Bounds of a slice of source code. -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] -#[derive(Serialize, Deserialize)] +#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize)] pub struct Span { /// The id of the source file. pub source: SourceId, @@ -127,9 +126,18 @@ impl Debug for Span { } } +impl PartialOrd for Span { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + if self.source == other.source { + Some(self.start.cmp(&other.start).then(self.end.cmp(&other.end))) + } else { + None + } + } +} + /// A byte position in source code. -#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] -#[derive(Serialize, Deserialize)] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] pub struct Pos(pub u32); impl Pos { @@ -148,17 +156,6 @@ impl Debug for Pos { } } -impl<T> Add<T> for Pos -where - T: Into<Pos>, -{ - type Output = Self; - - fn add(self, rhs: T) -> Self { - Pos(self.0 + rhs.into().0) - } -} - impl From<u32> for Pos { fn from(index: u32) -> Self { Self(index) @@ -171,6 +168,17 @@ impl From<usize> for Pos { } } +impl<T> Add<T> for Pos +where + T: Into<Pos>, +{ + type Output = Self; + + fn add(self, rhs: T) -> Self { + Pos(self.0 + rhs.into().0) + } +} + /// Convert a position or range into a span. pub trait IntoSpan { /// Convert into a span by providing the source id. diff --git a/src/syntax/token.rs b/src/syntax/token.rs index a4d1867a..219395cf 100644 --- a/src/syntax/token.rs +++ b/src/syntax/token.rs @@ -157,7 +157,7 @@ pub enum Token<'s> { } /// A quoted string token: `"..."`. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq)] pub struct StrToken<'s> { /// The string inside the quotes. /// @@ -170,7 +170,7 @@ pub struct StrToken<'s> { } /// A raw block token: `` `...` ``. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq)] pub struct RawToken<'s> { /// The raw text between the backticks. pub text: &'s str, @@ -181,7 +181,7 @@ pub struct RawToken<'s> { } /// A math formula token: `$2pi + x$` or `$[f'(x) = x^2]$`. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq)] pub struct MathToken<'s> { /// The formula between the dollars. pub formula: &'s str, @@ -193,7 +193,7 @@ pub struct MathToken<'s> { } /// A unicode escape sequence token: `\u{1F5FA}`. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq)] pub struct UnicodeEscapeToken<'s> { /// The escape sequence between the braces. pub sequence: &'s str, diff --git a/src/syntax/visit.rs b/src/syntax/visit.rs index 2b4649de..fe270ac5 100644 --- a/src/syntax/visit.rs +++ b/src/syntax/visit.rs @@ -104,12 +104,12 @@ impl_visitors! { v.visit_tree(r!(heading.body)); } - visit_list(v, item: ListItem) { - v.visit_tree(r!(item.body)); + visit_list(v, list: ListNode) { + v.visit_tree(r!(list.body)); } - visit_enum(v, item: EnumItem) { - v.visit_tree(r!(item.body)); + visit_enum(v, enum_: EnumNode) { + v.visit_tree(r!(enum_.body)); } visit_expr(v, expr: Expr) { diff --git a/src/util/eco.rs b/src/util/eco.rs index b44214bd..f1dfdfaf 100644 --- a/src/util/eco.rs +++ b/src/util/eco.rs @@ -163,24 +163,6 @@ impl EcoString { } } -impl Default for EcoString { - fn default() -> Self { - Self::new() - } -} - -impl Display for EcoString { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - Display::fmt(self.as_str(), f) - } -} - -impl Debug for EcoString { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - Debug::fmt(self.as_str(), f) - } -} - impl Deref for EcoString { type Target = str; @@ -201,6 +183,24 @@ impl Deref for EcoString { } } +impl Default for EcoString { + fn default() -> Self { + Self::new() + } +} + +impl Debug for EcoString { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Debug::fmt(self.as_str(), f) + } +} + +impl Display for EcoString { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(self.as_str(), f) + } +} + impl Eq for EcoString {} impl PartialEq for EcoString { |
