summaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-02-23 14:38:37 +0100
committerLaurenz <laurmaedje@gmail.com>2023-02-23 14:38:45 +0100
commitaffb3534538385056cfb60328f6dba6bd852229a (patch)
treea0a1b4844d459a66c3d32e0ad0dacf3f47c3966b /src/model
parent090831c9cb08c9b3c14ee30b423bb61275d70eb4 (diff)
parent457ce954366f3a81989fee788c85a5b20a96ce96 (diff)
Merge main back
Diffstat (limited to 'src/model')
-rw-r--r--src/model/args.rs4
-rw-r--r--src/model/array.rs55
-rw-r--r--src/model/cast.rs3
-rw-r--r--src/model/content.rs14
-rw-r--r--src/model/dict.rs4
-rw-r--r--src/model/eval.rs5
-rw-r--r--src/model/func.rs6
-rw-r--r--src/model/library.rs3
-rw-r--r--src/model/methods.rs3
-rw-r--r--src/model/module.rs3
-rw-r--r--src/model/ops.rs3
-rw-r--r--src/model/scope.rs3
-rw-r--r--src/model/str.rs8
-rw-r--r--src/model/symbol.rs10
-rw-r--r--src/model/value.rs2
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)]