summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-11-26 15:34:02 +0100
committerLaurenz <laurmaedje@gmail.com>2022-11-26 15:34:02 +0100
commit9db6e533cd8a1d925a7daad92e1b99e6f98ac773 (patch)
treeb7abf4afe13c2c1b14b54472ebef3b359567c9d8
parent36490f7f7bbe450b12faa24eba500909ccda3f85 (diff)
Make content a bit more compact
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rw-r--r--src/model/content.rs39
3 files changed, 35 insertions, 12 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 23e40dfe..a043bea2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1053,6 +1053,12 @@ dependencies = [
]
[[package]]
+name = "thin-vec"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ceb05e71730d396f960f8f3901cdb41be2d339b303e9d7d3a07c5ff0536e671b"
+
+[[package]]
name = "thiserror"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1127,6 +1133,7 @@ dependencies = [
"subsetter",
"svg2pdf",
"syntect",
+ "thin-vec",
"tiny-skia",
"ttf-parser 0.17.1",
"typst-macros",
diff --git a/Cargo.toml b/Cargo.toml
index fba8f5b3..d0b7a026 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -32,6 +32,7 @@ siphasher = "0.3"
subsetter = "0.1"
svg2pdf = "0.4"
syntect = { version = "5", default-features = false, features = ["default-syntaxes", "regex-fancy"] }
+thin-vec = "0.2"
tiny-skia = "0.6.2"
ttf-parser = "0.17"
unicode-segmentation = "1"
diff --git a/src/model/content.rs b/src/model/content.rs
index a7161798..2f7e7671 100644
--- a/src/model/content.rs
+++ b/src/model/content.rs
@@ -7,6 +7,7 @@ use std::sync::Arc;
use comemo::Tracked;
use siphasher::sip128::{Hasher128, SipHasher};
+use thin_vec::ThinVec;
use typst_macros::node;
use super::{capability, Args, Guard, Key, Property, Recipe, Style, StyleMap, Value, Vm};
@@ -19,9 +20,15 @@ use crate::World;
#[derive(Clone, Hash)]
pub struct Content {
obj: Arc<dyn Bounds>,
- guards: Vec<Guard>,
span: Option<Span>,
- label: Option<Label>,
+ meta: ThinVec<Meta>,
+}
+
+/// Metadata that can be attached to content.
+#[derive(Debug, Clone, PartialEq, Hash)]
+enum Meta {
+ Guard(Guard),
+ Label(Label),
}
impl Content {
@@ -55,7 +62,14 @@ impl Content {
/// Attach a label to the content.
pub fn labelled(mut self, label: Label) -> Self {
- self.label = Some(label);
+ for meta in &mut self.meta {
+ if let Meta::Label(prev) = meta {
+ *prev = label;
+ return self;
+ }
+ }
+
+ self.meta.push(Meta::Label(label));
self
}
@@ -132,13 +146,16 @@ impl Content {
/// The content's label.
pub fn label(&self) -> Option<&Label> {
- self.label.as_ref()
+ self.meta.iter().find_map(|meta| match meta {
+ Meta::Label(label) => Some(label),
+ _ => None,
+ })
}
/// Access a field on this content.
pub fn field(&self, name: &str) -> Option<Value> {
if name == "label" {
- return Some(match &self.label {
+ return Some(match self.label() {
Some(label) => Value::Label(label.clone()),
None => Value::None,
});
@@ -184,7 +201,7 @@ impl Content {
/// Disable a show rule recipe.
#[doc(hidden)]
pub fn guarded(mut self, id: Guard) -> Self {
- self.guards.push(id);
+ self.meta.push(Meta::Guard(id));
self
}
@@ -195,19 +212,18 @@ impl Content {
/// Whether no show rule was executed for this node so far.
pub(super) fn is_pristine(&self) -> bool {
- self.guards.is_empty()
+ !self.meta.iter().any(|meta| matches!(meta, Meta::Guard(_)))
}
/// Check whether a show rule recipe is disabled.
pub(super) fn is_guarded(&self, id: Guard) -> bool {
- self.guards.contains(&id)
+ self.meta.contains(&Meta::Guard(id))
}
/// Copy the metadata from other content.
pub(super) fn copy_meta(&mut self, from: &Content) {
- self.guards = from.guards.clone();
self.span = from.span;
- self.label = from.label.clone();
+ self.meta = from.meta.clone();
}
}
@@ -354,9 +370,8 @@ pub trait Node: 'static + Capable {
{
Content {
obj: Arc::new(self),
- guards: vec![],
span: None,
- label: None,
+ meta: ThinVec::new(),
}
}