summaryrefslogtreecommitdiff
path: root/src
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 /src
parent36490f7f7bbe450b12faa24eba500909ccda3f85 (diff)
Make content a bit more compact
Diffstat (limited to 'src')
-rw-r--r--src/model/content.rs39
1 files changed, 27 insertions, 12 deletions
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(),
}
}