diff options
Diffstat (limited to 'src/model')
| -rw-r--r-- | src/model/args.rs | 4 | ||||
| -rw-r--r-- | src/model/array.rs | 55 | ||||
| -rw-r--r-- | src/model/cast.rs | 3 | ||||
| -rw-r--r-- | src/model/content.rs | 14 | ||||
| -rw-r--r-- | src/model/dict.rs | 4 | ||||
| -rw-r--r-- | src/model/eval.rs | 5 | ||||
| -rw-r--r-- | src/model/func.rs | 6 | ||||
| -rw-r--r-- | src/model/library.rs | 3 | ||||
| -rw-r--r-- | src/model/methods.rs | 3 | ||||
| -rw-r--r-- | src/model/module.rs | 3 | ||||
| -rw-r--r-- | src/model/ops.rs | 3 | ||||
| -rw-r--r-- | src/model/scope.rs | 3 | ||||
| -rw-r--r-- | src/model/str.rs | 8 | ||||
| -rw-r--r-- | src/model/symbol.rs | 10 | ||||
| -rw-r--r-- | src/model/value.rs | 2 |
15 files changed, 70 insertions, 56 deletions
diff --git a/src/model/args.rs b/src/model/args.rs index 9ab07ed8..159e9a77 100644 --- a/src/model/args.rs +++ b/src/model/args.rs @@ -1,5 +1,7 @@ use std::fmt::{self, Debug, Formatter, Write}; +use ecow::EcoVec; + use super::{Array, Cast, Dict, Str, Value}; use crate::diag::{bail, At, SourceResult}; use crate::syntax::{Span, Spanned}; @@ -10,7 +12,7 @@ pub struct Args { /// The span of the whole argument list. pub span: Span, /// The positional and named arguments. - pub items: Vec<Arg>, + pub items: EcoVec<Arg>, } /// An argument to a function call: `12` or `draw: false`. diff --git a/src/model/array.rs b/src/model/array.rs index 12abac4e..0a84072d 100644 --- a/src/model/array.rs +++ b/src/model/array.rs @@ -1,31 +1,33 @@ use std::cmp::Ordering; use std::fmt::{self, Debug, Formatter, Write}; use std::ops::{Add, AddAssign}; -use std::sync::Arc; + +use ecow::{format_eco, EcoString, EcoVec}; use super::{ops, Args, Func, Value, Vm}; use crate::diag::{bail, At, SourceResult, StrResult}; -use crate::util::{format_eco, ArcExt, EcoString}; /// Create a new [`Array`] from values. #[macro_export] #[doc(hidden)] macro_rules! __array { ($value:expr; $count:expr) => { - $crate::model::Array::from_vec(vec![$value.into(); $count]) + $crate::model::Array::from_vec($crate::model::eco_vec![$value.into(); $count]) }; ($($value:expr),* $(,)?) => { - $crate::model::Array::from_vec(vec![$($value.into()),*]) + $crate::model::Array::from_vec($crate::model::eco_vec![$($value.into()),*]) }; } #[doc(inline)] pub use crate::__array as array; +#[doc(hidden)] +pub use ecow::eco_vec; /// A reference counted array with value semantics. #[derive(Default, Clone, PartialEq, Hash)] -pub struct Array(Arc<Vec<Value>>); +pub struct Array(EcoVec<Value>); impl Array { /// Create a new, empty array. @@ -33,9 +35,9 @@ impl Array { Self::default() } - /// Create a new array from a vector of values. - pub fn from_vec(vec: Vec<Value>) -> Self { - Self(Arc::new(vec)) + /// Create a new array from an eco vector of values. + pub fn from_vec(vec: EcoVec<Value>) -> Self { + Self(vec) } /// The length of the array. @@ -50,7 +52,7 @@ impl Array { /// Mutably borrow the first value in the array. pub fn first_mut(&mut self) -> StrResult<&mut Value> { - Arc::make_mut(&mut self.0).first_mut().ok_or_else(array_is_empty) + self.0.make_mut().first_mut().ok_or_else(array_is_empty) } /// The last value in the array. @@ -60,7 +62,7 @@ impl Array { /// Mutably borrow the last value in the array. pub fn last_mut(&mut self) -> StrResult<&mut Value> { - Arc::make_mut(&mut self.0).last_mut().ok_or_else(array_is_empty) + self.0.make_mut().last_mut().ok_or_else(array_is_empty) } /// Borrow the value at the given index. @@ -74,18 +76,18 @@ impl Array { pub fn at_mut(&mut self, index: i64) -> StrResult<&mut Value> { let len = self.len(); self.locate(index) - .and_then(move |i| Arc::make_mut(&mut self.0).get_mut(i)) + .and_then(move |i| self.0.make_mut().get_mut(i)) .ok_or_else(|| out_of_bounds(index, len)) } /// Push a value to the end of the array. pub fn push(&mut self, value: Value) { - Arc::make_mut(&mut self.0).push(value); + self.0.push(value); } /// Remove the last value in the array. pub fn pop(&mut self) -> StrResult<Value> { - Arc::make_mut(&mut self.0).pop().ok_or_else(array_is_empty) + self.0.pop().ok_or_else(array_is_empty) } /// Insert a value at the specified index. @@ -96,7 +98,7 @@ impl Array { .filter(|&i| i <= self.0.len()) .ok_or_else(|| out_of_bounds(index, len))?; - Arc::make_mut(&mut self.0).insert(i, value); + self.0.insert(i, value); Ok(()) } @@ -108,7 +110,7 @@ impl Array { .filter(|&i| i < self.0.len()) .ok_or_else(|| out_of_bounds(index, len))?; - Ok(Arc::make_mut(&mut self.0).remove(i)) + Ok(self.0.remove(i)) } /// Extract a contigous subregion of the array. @@ -126,7 +128,7 @@ impl Array { .ok_or_else(|| out_of_bounds(end, len))? .max(start); - Ok(Self::from_vec(self.0[start..end].to_vec())) + Ok(Self::from_vec(self.0[start..end].into())) } /// Whether the array contains a specific value. @@ -170,7 +172,7 @@ impl Array { if func.argc().map_or(false, |count| count != 1) { bail!(func.span(), "function must have exactly one parameter"); } - let mut kept = vec![]; + let mut kept = EcoVec::new(); for item in self.iter() { let args = Args::new(func.span(), [item.clone()]); if func.call(vm, args)?.cast::<bool>().at(func.span())? { @@ -244,7 +246,7 @@ impl Array { /// Return a new array with all items from this and nested arrays. pub fn flatten(&self) -> Self { - let mut flat = Vec::with_capacity(self.0.len()); + let mut flat = EcoVec::with_capacity(self.0.len()); for item in self.iter() { if let Value::Array(nested) = item { flat.extend(nested.flatten().into_iter()); @@ -287,8 +289,8 @@ impl Array { /// Returns an error if two values could not be compared. pub fn sorted(&self) -> StrResult<Self> { let mut result = Ok(()); - let mut vec = (*self.0).clone(); - vec.sort_by(|a, b| { + let mut vec = self.0.clone(); + vec.make_mut().sort_by(|a, b| { a.partial_cmp(b).unwrap_or_else(|| { if result.is_ok() { result = Err(format_eco!( @@ -369,31 +371,28 @@ impl Add for Array { impl AddAssign for Array { fn add_assign(&mut self, rhs: Array) { - match Arc::try_unwrap(rhs.0) { - Ok(vec) => self.extend(vec), - Err(rc) => self.extend(rc.iter().cloned()), - } + self.0.extend(rhs.0); } } impl Extend<Value> for Array { fn extend<T: IntoIterator<Item = Value>>(&mut self, iter: T) { - Arc::make_mut(&mut self.0).extend(iter); + self.0.extend(iter); } } impl FromIterator<Value> for Array { fn from_iter<T: IntoIterator<Item = Value>>(iter: T) -> Self { - Self(Arc::new(iter.into_iter().collect())) + Self(iter.into_iter().collect()) } } impl IntoIterator for Array { type Item = Value; - type IntoIter = std::vec::IntoIter<Value>; + type IntoIter = ecow::IntoIter<Value>; fn into_iter(self) -> Self::IntoIter { - Arc::take(self.0).into_iter() + self.0.into_iter() } } diff --git a/src/model/cast.rs b/src/model/cast.rs index 0da9906f..4c300550 100644 --- a/src/model/cast.rs +++ b/src/model/cast.rs @@ -2,6 +2,8 @@ use std::num::NonZeroUsize; use std::ops::Add; use std::str::FromStr; +use ecow::EcoString; + use super::{ castable, Array, Content, Dict, Func, Label, Regex, Selector, Str, Transform, Value, }; @@ -13,7 +15,6 @@ use crate::geom::{ Rel, Sides, Smart, }; use crate::syntax::Spanned; -use crate::util::EcoString; /// Cast from a value to a specific type. pub trait Cast<V = Value>: Sized { diff --git a/src/model/content.rs b/src/model/content.rs index e6cb6d28..b8047ffa 100644 --- a/src/model/content.rs +++ b/src/model/content.rs @@ -6,8 +6,8 @@ use std::ops::{Add, AddAssign}; use std::sync::Arc; use comemo::Tracked; +use ecow::{EcoString, EcoVec}; use siphasher::sip128::{Hasher128, SipHasher}; -use thin_vec::ThinVec; use typst_macros::node; use super::{ @@ -16,7 +16,7 @@ use super::{ }; use crate::diag::{SourceResult, StrResult}; use crate::syntax::Span; -use crate::util::{EcoString, ReadableTypeId}; +use crate::util::ReadableTypeId; use crate::World; /// Composable representation of styled content. @@ -24,7 +24,7 @@ use crate::World; pub struct Content { obj: Arc<dyn Bounds>, span: Option<Span>, - modifiers: ThinVec<Modifier>, + modifiers: EcoVec<Modifier>, } /// Modifiers that can be attached to content. @@ -67,9 +67,9 @@ impl Content { /// Attach a label to the content. pub fn labelled(mut self, label: Label) -> Self { - for modifier in &mut self.modifiers { - if let Modifier::Label(prev) = modifier { - *prev = label; + for (i, modifier) in self.modifiers.iter().enumerate() { + if matches!(modifier, Modifier::Label(_)) { + self.modifiers.make_mut()[i] = Modifier::Label(label); return self; } } @@ -407,7 +407,7 @@ pub trait Node: 'static + Capable { Content { obj: Arc::new(self), span: None, - modifiers: ThinVec::new(), + modifiers: EcoVec::new(), } } diff --git a/src/model/dict.rs b/src/model/dict.rs index 7165fbbe..b6198b2c 100644 --- a/src/model/dict.rs +++ b/src/model/dict.rs @@ -3,10 +3,12 @@ use std::fmt::{self, Debug, Formatter, Write}; use std::ops::{Add, AddAssign}; use std::sync::Arc; +use ecow::{format_eco, EcoString}; + use super::{array, Array, Str, Value}; use crate::diag::StrResult; use crate::syntax::is_ident; -use crate::util::{format_eco, ArcExt, EcoString}; +use crate::util::ArcExt; /// Create a new [`Dict`] from key-value pairs. #[macro_export] diff --git a/src/model/eval.rs b/src/model/eval.rs index 6e118f8a..225c5e7a 100644 --- a/src/model/eval.rs +++ b/src/model/eval.rs @@ -5,6 +5,7 @@ use std::mem; use std::path::{Path, PathBuf}; use comemo::{Track, Tracked, TrackedMut}; +use ecow::EcoVec; use unicode_segmentation::UnicodeSegmentation; use super::{ @@ -797,7 +798,7 @@ impl Eval for ast::Array { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { let items = self.items(); - let mut vec = Vec::with_capacity(items.size_hint().0); + let mut vec = EcoVec::with_capacity(items.size_hint().0); for item in items { match item { ast::ArrayItem::Pos(expr) => vec.push(expr.eval(vm)?), @@ -1032,7 +1033,7 @@ impl Eval for ast::Args { type Output = Args; fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { - let mut items = Vec::new(); + let mut items = EcoVec::new(); for arg in self.items() { let span = arg.span(); diff --git a/src/model/func.rs b/src/model/func.rs index ec9e70e0..2ba462d3 100644 --- a/src/model/func.rs +++ b/src/model/func.rs @@ -3,6 +3,7 @@ use std::hash::{Hash, Hasher}; use std::sync::Arc; use comemo::{Prehashed, Track, Tracked, TrackedMut}; +use ecow::EcoString; use super::{ Args, CastInfo, Dict, Eval, Flow, Node, NodeId, Route, Scope, Scopes, Selector, @@ -12,7 +13,6 @@ use crate::diag::{bail, SourceResult, StrResult}; use crate::syntax::ast::{self, AstNode, Expr}; use crate::syntax::{SourceId, Span, SyntaxNode}; use crate::util::hash128; -use crate::util::EcoString; use crate::World; /// An evaluatable function. @@ -139,8 +139,8 @@ impl Func { ) } Repr::With(wrapped, applied) => { - args.items.splice(..0, applied.items.iter().cloned()); - wrapped.call(vm, args) + args.items = applied.items.iter().cloned().chain(args.items).collect(); + return wrapped.call(vm, args); } } } diff --git a/src/model/library.rs b/src/model/library.rs index c87ca095..8ef22f10 100644 --- a/src/model/library.rs +++ b/src/model/library.rs @@ -2,13 +2,14 @@ use std::fmt::{self, Debug, Formatter}; use std::hash::{Hash, Hasher}; use std::num::NonZeroUsize; +use ecow::EcoString; use once_cell::sync::OnceCell; use super::{Content, Module, NodeId, StyleChain, StyleMap, Vt}; use crate::diag::SourceResult; use crate::doc::Document; use crate::geom::{Abs, Dir}; -use crate::util::{hash128, EcoString}; +use crate::util::hash128; /// Definition of Typst's standard library. #[derive(Debug, Clone, Hash)] diff --git a/src/model/methods.rs b/src/model/methods.rs index 38ebebda..dcb1ca31 100644 --- a/src/model/methods.rs +++ b/src/model/methods.rs @@ -1,9 +1,10 @@ //! Methods on values. +use ecow::EcoString; + use super::{Args, Str, Value, Vm}; use crate::diag::{At, SourceResult}; use crate::syntax::Span; -use crate::util::EcoString; /// Call a method on a value. pub fn call( diff --git a/src/model/module.rs b/src/model/module.rs index 954a84f0..97c060e3 100644 --- a/src/model/module.rs +++ b/src/model/module.rs @@ -1,9 +1,10 @@ use std::fmt::{self, Debug, Formatter}; use std::sync::Arc; +use ecow::{format_eco, EcoString}; + use super::{Content, Scope, Value}; use crate::diag::StrResult; -use crate::util::{format_eco, EcoString}; /// An evaluated module, ready for importing or typesetting. #[derive(Clone, Hash)] diff --git a/src/model/ops.rs b/src/model/ops.rs index 83137f38..be7892f9 100644 --- a/src/model/ops.rs +++ b/src/model/ops.rs @@ -2,10 +2,11 @@ use std::cmp::Ordering; +use ecow::format_eco; + use super::{format_str, Regex, Value}; use crate::diag::StrResult; use crate::geom::{Axes, Axis, GenAlign, Length, Numeric, PartialStroke, Rel, Smart}; -use crate::util::format_eco; use Value::*; /// Bail with a type mismatch error. diff --git a/src/model/scope.rs b/src/model/scope.rs index 18c75535..f6bd2164 100644 --- a/src/model/scope.rs +++ b/src/model/scope.rs @@ -2,9 +2,10 @@ use std::collections::BTreeMap; use std::fmt::{self, Debug, Formatter}; use std::hash::Hash; +use ecow::EcoString; + use super::{Func, FuncType, Library, Value}; use crate::diag::StrResult; -use crate::util::EcoString; /// A stack of scopes. #[derive(Debug, Default, Clone)] diff --git a/src/model/str.rs b/src/model/str.rs index 8da5b50c..3eee9506 100644 --- a/src/model/str.rs +++ b/src/model/str.rs @@ -3,24 +3,26 @@ use std::fmt::{self, Debug, Display, Formatter, Write}; use std::hash::{Hash, Hasher}; use std::ops::{Add, AddAssign, Deref}; +use ecow::EcoString; use unicode_segmentation::UnicodeSegmentation; use super::{castable, dict, Array, Dict, Value}; use crate::diag::StrResult; use crate::geom::GenAlign; -use crate::util::{format_eco, EcoString}; /// Create a new [`Str`] from a format string. #[macro_export] #[doc(hidden)] macro_rules! __format_str { ($($tts:tt)*) => {{ - $crate::model::Str::from(format_eco!($($tts)*)) + $crate::model::Str::from($crate::model::format_eco!($($tts)*)) }}; } #[doc(inline)] pub use crate::__format_str as format_str; +#[doc(hidden)] +pub use ecow::format_eco; /// An immutable reference counted string. #[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] @@ -415,11 +417,13 @@ impl From<String> for Str { Self(s.into()) } } + impl From<Cow<'_, str>> for Str { fn from(s: Cow<str>) -> Self { Self(s.into()) } } + impl FromIterator<char> for Str { fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self { Self(iter.into_iter().collect()) diff --git a/src/model/symbol.rs b/src/model/symbol.rs index 16ab58af..73c41067 100644 --- a/src/model/symbol.rs +++ b/src/model/symbol.rs @@ -1,10 +1,10 @@ use std::cmp::Reverse; use std::collections::BTreeSet; use std::fmt::{self, Debug, Display, Formatter, Write}; -use std::sync::Arc; + +use ecow::{EcoString, EcoVec}; use crate::diag::StrResult; -use crate::util::EcoString; #[doc(inline)] pub use typst_macros::symbols; @@ -21,7 +21,7 @@ pub struct Symbol { enum Repr { Single(char), Static(&'static [(&'static str, char)]), - Runtime(Arc<Vec<(EcoString, char)>>), + Runtime(EcoVec<(EcoString, char)>), } impl Symbol { @@ -42,10 +42,10 @@ impl Symbol { /// Create a symbol with a runtime variant list. #[track_caller] - pub fn runtime(list: Vec<(EcoString, char)>) -> Self { + pub fn runtime(list: EcoVec<(EcoString, char)>) -> Self { debug_assert!(!list.is_empty()); Self { - repr: Repr::Runtime(Arc::new(list)), + repr: Repr::Runtime(list), modifiers: EcoString::new(), } } diff --git a/src/model/value.rs b/src/model/value.rs index dff27fde..5c0ab618 100644 --- a/src/model/value.rs +++ b/src/model/value.rs @@ -4,6 +4,7 @@ use std::fmt::{self, Debug, Formatter}; use std::hash::{Hash, Hasher}; use std::sync::Arc; +use ecow::{format_eco, EcoString}; use siphasher::sip128::{Hasher128, SipHasher}; use super::{ @@ -13,7 +14,6 @@ use super::{ use crate::diag::StrResult; use crate::geom::{Abs, Angle, Color, Em, Fr, Length, Ratio, Rel, RgbaColor}; use crate::syntax::{ast, Span}; -use crate::util::{format_eco, EcoString}; /// A computational value. #[derive(Clone)] |
