From a1d47695a2af5afa466c21ad812a1a8212780293 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Thu, 23 Feb 2023 12:15:38 +0100 Subject: Switch to ecow --- src/model/array.rs | 55 ++++++++++++++++++++++++++-------------------------- src/model/cast.rs | 3 ++- src/model/content.rs | 3 ++- src/model/dict.rs | 4 +++- src/model/eval.rs | 3 ++- src/model/func.rs | 2 +- src/model/library.rs | 3 ++- src/model/methods.rs | 3 ++- src/model/module.rs | 3 ++- src/model/ops.rs | 3 ++- src/model/scope.rs | 3 ++- src/model/str.rs | 8 ++++++-- src/model/symbol.rs | 3 ++- src/model/value.rs | 2 +- 14 files changed, 56 insertions(+), 42 deletions(-) (limited to 'src/model') 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>); +pub struct Array(EcoVec); 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) -> Self { - Self(Arc::new(vec)) + /// Create a new array from an eco vector of values. + pub fn from_vec(vec: EcoVec) -> 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 { - 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::().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 { 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 for Array { fn extend>(&mut self, iter: T) { - Arc::make_mut(&mut self.0).extend(iter); + self.0.extend(iter); } } impl FromIterator for Array { fn from_iter>(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; + type IntoIter = ecow::IntoIter; 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: Sized { diff --git a/src/model/content.rs b/src/model/content.rs index e6cb6d28..fde0a5cd 100644 --- a/src/model/content.rs +++ b/src/model/content.rs @@ -6,6 +6,7 @@ use std::ops::{Add, AddAssign}; use std::sync::Arc; use comemo::Tracked; +use ecow::EcoString; use siphasher::sip128::{Hasher128, SipHasher}; use thin_vec::ThinVec; use typst_macros::node; @@ -16,7 +17,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. 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..7d48b598 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 { 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)?), diff --git a/src/model/func.rs b/src/model/func.rs index c5bab64c..216ee806 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::{Track, Tracked, TrackedMut}; +use ecow::EcoString; use super::{ Args, CastInfo, Dict, Eval, Flow, Node, NodeId, Route, Scope, Scopes, Selector, @@ -11,7 +12,6 @@ use super::{ use crate::diag::{bail, SourceResult, StrResult}; use crate::syntax::ast::{self, AstNode, Expr}; use crate::syntax::{SourceId, Span, SyntaxNode}; -use crate::util::EcoString; use crate::World; /// An evaluatable function. 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 c0b63669..40e99de4 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 6bfbcebd..228943dc 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)] @@ -407,11 +409,13 @@ impl From for Str { Self(s.into()) } } + impl From> for Str { fn from(s: Cow) -> Self { Self(s.into()) } } + impl FromIterator for Str { fn from_iter>(iter: T) -> Self { Self(iter.into_iter().collect()) diff --git a/src/model/symbol.rs b/src/model/symbol.rs index 16ab58af..fafebd99 100644 --- a/src/model/symbol.rs +++ b/src/model/symbol.rs @@ -3,8 +3,9 @@ use std::collections::BTreeSet; use std::fmt::{self, Debug, Display, Formatter, Write}; use std::sync::Arc; +use ecow::EcoString; + use crate::diag::StrResult; -use crate::util::EcoString; #[doc(inline)] pub use typst_macros::symbols; diff --git a/src/model/value.rs b/src/model/value.rs index b860a3f6..e8cc42bc 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)] -- cgit v1.2.3 From 457ce954366f3a81989fee788c85a5b20a96ce96 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Thu, 23 Feb 2023 14:36:40 +0100 Subject: More EcoVec usage Frame unfortunately can't use it because splice is missing. --- src/model/args.rs | 4 +++- src/model/content.rs | 13 ++++++------- src/model/eval.rs | 2 +- src/model/func.rs | 2 +- src/model/symbol.rs | 9 ++++----- 5 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src/model') 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, + pub items: EcoVec, } /// An argument to a function call: `12` or `draw: false`. diff --git a/src/model/content.rs b/src/model/content.rs index fde0a5cd..b8047ffa 100644 --- a/src/model/content.rs +++ b/src/model/content.rs @@ -6,9 +6,8 @@ use std::ops::{Add, AddAssign}; use std::sync::Arc; use comemo::Tracked; -use ecow::EcoString; +use ecow::{EcoString, EcoVec}; use siphasher::sip128::{Hasher128, SipHasher}; -use thin_vec::ThinVec; use typst_macros::node; use super::{ @@ -25,7 +24,7 @@ use crate::World; pub struct Content { obj: Arc, span: Option, - modifiers: ThinVec, + modifiers: EcoVec, } /// Modifiers that can be attached to content. @@ -68,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; } } @@ -408,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/eval.rs b/src/model/eval.rs index 7d48b598..225c5e7a 100644 --- a/src/model/eval.rs +++ b/src/model/eval.rs @@ -1033,7 +1033,7 @@ impl Eval for ast::Args { type Output = Args; fn eval(&self, vm: &mut Vm) -> SourceResult { - 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 216ee806..654b7e65 100644 --- a/src/model/func.rs +++ b/src/model/func.rs @@ -115,7 +115,7 @@ impl Func { Repr::Native(native) => (native.func)(vm, &mut args)?, Repr::Closure(closure) => closure.call(vm, self, &mut args)?, Repr::With(wrapped, applied) => { - args.items.splice(..0, applied.items.iter().cloned()); + args.items = applied.items.iter().cloned().chain(args.items).collect(); return wrapped.call(vm, args); } }; diff --git a/src/model/symbol.rs b/src/model/symbol.rs index fafebd99..73c41067 100644 --- a/src/model/symbol.rs +++ b/src/model/symbol.rs @@ -1,9 +1,8 @@ use std::cmp::Reverse; use std::collections::BTreeSet; use std::fmt::{self, Debug, Display, Formatter, Write}; -use std::sync::Arc; -use ecow::EcoString; +use ecow::{EcoString, EcoVec}; use crate::diag::StrResult; @@ -22,7 +21,7 @@ pub struct Symbol { enum Repr { Single(char), Static(&'static [(&'static str, char)]), - Runtime(Arc>), + Runtime(EcoVec<(EcoString, char)>), } impl Symbol { @@ -43,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(), } } -- cgit v1.2.3