diff --git a/src/eval/dict.rs b/src/eval/dict.rs index bf99ea17e..c1c3f5052 100644 --- a/src/eval/dict.rs +++ b/src/eval/dict.rs @@ -5,7 +5,7 @@ use std::ops::{Add, AddAssign}; use std::rc::Rc; use super::Value; -use crate::eco::EcoString; +use crate::util::EcoString; /// Create a new [`Dict`] from key-value pairs. #[macro_export] @@ -13,7 +13,7 @@ macro_rules! dict { ($($key:expr => $value:expr),* $(,)?) => {{ #[allow(unused_mut)] let mut map = std::collections::BTreeMap::new(); - $(map.insert($crate::eco::EcoString::from($key), $crate::eval::Value::from($value));)* + $(map.insert($crate::util::EcoString::from($key), $crate::eval::Value::from($value));)* $crate::eval::Dict::from_map(map) }}; } diff --git a/src/eval/function.rs b/src/eval/function.rs index daa5ff1e2..ca447a48d 100644 --- a/src/eval/function.rs +++ b/src/eval/function.rs @@ -3,7 +3,7 @@ use std::ops::Deref; use std::rc::Rc; use super::{Cast, EvalContext, Value}; -use crate::eco::EcoString; +use crate::util::EcoString; use crate::syntax::{Span, Spanned}; /// An evaluatable function. diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 5b00819b9..682a3855c 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -26,7 +26,7 @@ use std::path::Path; use std::rc::Rc; use crate::diag::{Diag, DiagSet, Pass}; -use crate::eco::EcoString; +use crate::util::EcoString; use crate::geom::{Angle, Fractional, Length, Relative}; use crate::image::ImageCache; use crate::loading::{FileId, Loader}; diff --git a/src/eval/template.rs b/src/eval/template.rs index 4d0039982..0be2492be 100644 --- a/src/eval/template.rs +++ b/src/eval/template.rs @@ -4,7 +4,7 @@ use std::ops::{Add, Deref}; use std::rc::Rc; use super::Value; -use crate::eco::EcoString; +use crate::util::EcoString; use crate::exec::ExecContext; use crate::syntax::{Expr, SyntaxTree}; diff --git a/src/eval/value.rs b/src/eval/value.rs index 4b3cd807e..b7fdcbc21 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -5,7 +5,7 @@ use std::rc::Rc; use super::{ops, Array, Dict, Function, Template, TemplateFunc}; use crate::color::{Color, RgbaColor}; -use crate::eco::EcoString; +use crate::util::EcoString; use crate::exec::ExecContext; use crate::geom::{Angle, Fractional, Length, Linear, Relative}; use crate::syntax::Spanned; diff --git a/src/exec/context.rs b/src/exec/context.rs index 725907f22..3a3eb7027 100644 --- a/src/exec/context.rs +++ b/src/exec/context.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use super::{Exec, ExecWithMap, State}; use crate::diag::{Diag, DiagSet, Pass}; -use crate::eco::EcoString; +use crate::util::EcoString; use crate::eval::{ExprMap, Template}; use crate::geom::{Align, Dir, Gen, GenAxis, Length, Linear, Sides, Size}; use crate::layout::{ diff --git a/src/exec/mod.rs b/src/exec/mod.rs index 8b769def1..ff4faa227 100644 --- a/src/exec/mod.rs +++ b/src/exec/mod.rs @@ -9,7 +9,7 @@ pub use state::*; use std::fmt::Write; use crate::diag::Pass; -use crate::eco::EcoString; +use crate::util::EcoString; use crate::eval::{ExprMap, Template, TemplateFunc, TemplateNode, TemplateTree, Value}; use crate::geom::{Dir, Gen}; use crate::layout::{LayoutTree, StackChild, StackNode}; diff --git a/src/layout/incremental.rs b/src/layout/incremental.rs index cbd553301..352434ede 100644 --- a/src/layout/incremental.rs +++ b/src/layout/incremental.rs @@ -269,46 +269,9 @@ impl Constraints { let current = regions.current.to_spec(); let base = regions.base.to_spec(); - self.exact.horizontal.set_if_some(current.horizontal); - self.exact.vertical.set_if_some(current.vertical); - self.base.horizontal.set_if_some(base.horizontal); - self.base.vertical.set_if_some(base.vertical); - } -} - -/// Extends length-related options by providing convenience methods for setting -/// minimum and maximum lengths on them, even if they are `None`. -pub trait OptionExt { - /// Sets `other` as the value if `self` is `None` or if it contains a - /// value larger than `other`. - fn set_min(&mut self, other: Length); - - /// Sets `other` as the value if `self` is `None` or if it contains a - /// value smaller than `other`. - fn set_max(&mut self, other: Length); - - /// Sets `other` as the value if `self` is `Some`. - fn set_if_some(&mut self, other: Length); -} - -impl OptionExt for Option { - fn set_min(&mut self, other: Length) { - match self { - Some(x) => x.set_min(other), - None => *self = Some(other), - } - } - - fn set_max(&mut self, other: Length) { - match self { - Some(x) => x.set_max(other), - None => *self = Some(other), - } - } - - fn set_if_some(&mut self, other: Length) { - if self.is_some() { - *self = Some(other); - } + self.exact.horizontal.and_set(Some(current.horizontal)); + self.exact.vertical.and_set(Some(current.vertical)); + self.base.horizontal.and_set(Some(base.horizontal)); + self.base.vertical.and_set(Some(base.vertical)); } } diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 0f88d150e..56e0687a0 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -32,6 +32,7 @@ use std::rc::Rc; use crate::font::FontCache; use crate::geom::*; use crate::image::ImageCache; +use crate::util::OptionExt; use crate::Context; /// Layout a tree into a collection of frames. diff --git a/src/layout/par.rs b/src/layout/par.rs index 56847b9bc..03d7efd56 100644 --- a/src/layout/par.rs +++ b/src/layout/par.rs @@ -5,9 +5,8 @@ use unicode_bidi::{BidiInfo, Level}; use xi_unicode::LineBreakIterator; use super::*; -use crate::eco::EcoString; use crate::exec::TextState; -use crate::util::{RangeExt, SliceExt}; +use crate::util::{EcoString, RangeExt, SliceExt}; type Range = std::ops::Range; diff --git a/src/lib.rs b/src/lib.rs index 5c4772489..da0063333 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,7 +33,6 @@ pub mod diag; #[macro_use] pub mod eval; pub mod color; -pub mod eco; pub mod exec; pub mod export; pub mod font; diff --git a/src/library/mod.rs b/src/library/mod.rs index 3c1d752dd..213106d6f 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -17,12 +17,12 @@ use std::fmt::{self, Display, Formatter}; use std::rc::Rc; use crate::color::{Color, RgbaColor}; -use crate::eco::EcoString; use crate::eval::{EvalContext, FuncArgs, Scope, Template, Type, Value}; use crate::exec::{Exec, FontFamily}; use crate::font::{FontStyle, FontWeight, VerticalFontMetric}; use crate::geom::*; use crate::syntax::Spanned; +use crate::util::EcoString; /// Construct a scope containing all standard library definitions. pub fn new() -> Scope { diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 38a489b27..a94345a85 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -15,8 +15,8 @@ pub use tokens::*; use std::rc::Rc; use crate::diag::Pass; -use crate::eco::EcoString; use crate::syntax::*; +use crate::util::EcoString; /// Parse a string of source code. pub fn parse(src: &str) -> Pass { diff --git a/src/parse/resolve.rs b/src/parse/resolve.rs index c36762150..f97d53835 100644 --- a/src/parse/resolve.rs +++ b/src/parse/resolve.rs @@ -1,6 +1,6 @@ use super::{is_newline, Scanner}; -use crate::eco::EcoString; use crate::syntax::{Ident, RawNode, Span}; +use crate::util::EcoString; /// Resolve all escape sequences in a string. pub fn resolve_string(string: &str) -> EcoString { diff --git a/src/syntax/ident.rs b/src/syntax/ident.rs index b1328bbe9..462361a5b 100644 --- a/src/syntax/ident.rs +++ b/src/syntax/ident.rs @@ -3,7 +3,7 @@ use std::ops::Deref; use unicode_xid::UnicodeXID; use super::Span; -use crate::eco::EcoString; +use crate::util::EcoString; /// An unicode identifier with a few extra permissible characters. /// diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 895a5bc5d..9a4ca708a 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -13,7 +13,7 @@ pub use node::*; pub use span::*; pub use token::*; -use crate::eco::EcoString; +use crate::util::EcoString; /// The abstract syntax tree. /// diff --git a/src/eco.rs b/src/util/eco.rs similarity index 100% rename from src/eco.rs rename to src/util/eco.rs diff --git a/src/util.rs b/src/util/mod.rs similarity index 71% rename from src/util.rs rename to src/util/mod.rs index 8a8c04b6d..2c53bc706 100644 --- a/src/util.rs +++ b/src/util/mod.rs @@ -1,9 +1,57 @@ //! Utilities. +mod eco; + +pub use eco::EcoString; + use std::cmp::Ordering; use std::ops::Range; use std::path::{Component, Path, PathBuf}; +/// Additional methods for options. +pub trait OptionExt { + /// Replace `self` with `other` if `self` is `Some`. + fn and_set(&mut self, other: Option); + + /// Sets `other` as the value if `self` is `None` or if it contains a value + /// larger than `other`. + fn set_min(&mut self, other: T) + where + T: Ord; + + /// Sets `other` as the value if `self` is `None` or if it contains a value + /// smaller than `other`. + fn set_max(&mut self, other: T) + where + T: Ord; +} + +impl OptionExt for Option { + fn and_set(&mut self, other: Option) { + if self.is_some() { + *self = other; + } + } + + fn set_min(&mut self, other: T) + where + T: Ord, + { + if self.as_ref().map_or(true, |x| other < *x) { + *self = Some(other); + } + } + + fn set_max(&mut self, other: T) + where + T: Ord, + { + if self.as_ref().map_or(true, |x| other > *x) { + *self = Some(other); + } + } +} + /// Additional methods for slices. pub trait SliceExt { /// Split a slice into consecutive groups with the same key.