summaryrefslogtreecommitdiff
path: root/src/model/content.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-12-02 15:41:39 +0100
committerLaurenz <laurmaedje@gmail.com>2022-12-02 15:45:18 +0100
commit9bc90c371fb41a2d6dc08eb4673e5be15f829514 (patch)
tree454a47ce82c2229e79a139a8bdeaed9add1e0a14 /src/model/content.rs
parent5110a41de1ca2236739ace2d37a1af912bb029f1 (diff)
Introspection
Diffstat (limited to 'src/model/content.rs')
-rw-r--r--src/model/content.rs67
1 files changed, 46 insertions, 21 deletions
diff --git a/src/model/content.rs b/src/model/content.rs
index 2f7e7671..f261f9b1 100644
--- a/src/model/content.rs
+++ b/src/model/content.rs
@@ -21,14 +21,16 @@ use crate::World;
pub struct Content {
obj: Arc<dyn Bounds>,
span: Option<Span>,
- meta: ThinVec<Meta>,
+ modifiers: ThinVec<Modifier>,
}
-/// Metadata that can be attached to content.
+/// Modifiers that can be attached to content.
#[derive(Debug, Clone, PartialEq, Hash)]
-enum Meta {
+enum Modifier {
+ Prepared,
Guard(Guard),
Label(Label),
+ Field(EcoString, Value),
}
impl Content {
@@ -62,17 +64,22 @@ impl Content {
/// Attach a label to the content.
pub fn labelled(mut self, label: Label) -> Self {
- for meta in &mut self.meta {
- if let Meta::Label(prev) = meta {
+ for modifier in &mut self.modifiers {
+ if let Modifier::Label(prev) = modifier {
*prev = label;
return self;
}
}
- self.meta.push(Meta::Label(label));
+ self.modifiers.push(Modifier::Label(label));
self
}
+ /// Attach a field to the content.
+ pub fn push_field(&mut self, name: impl Into<EcoString>, value: Value) {
+ self.modifiers.push(Modifier::Field(name.into(), value));
+ }
+
/// Style this content with a single style property.
pub fn styled<K: Key>(self, key: K, value: K::Value) -> Self {
self.styled_with_entry(Style::Property(Property::new(key, value)))
@@ -146,8 +153,8 @@ impl Content {
/// The content's label.
pub fn label(&self) -> Option<&Label> {
- self.meta.iter().find_map(|meta| match meta {
- Meta::Label(label) => Some(label),
+ self.modifiers.iter().find_map(|modifier| match modifier {
+ Modifier::Label(label) => Some(label),
_ => None,
})
}
@@ -161,6 +168,14 @@ impl Content {
});
}
+ for modifier in &self.modifiers {
+ if let Modifier::Field(other, value) = modifier {
+ if name == other.as_str() {
+ return Some(value.clone());
+ }
+ }
+ }
+
self.obj.field(name)
}
@@ -201,10 +216,23 @@ impl Content {
/// Disable a show rule recipe.
#[doc(hidden)]
pub fn guarded(mut self, id: Guard) -> Self {
- self.meta.push(Meta::Guard(id));
+ self.modifiers.push(Modifier::Guard(id));
self
}
+ /// Mark this content as prepared.
+ #[doc(hidden)]
+ pub fn prepared(mut self) -> Self {
+ self.modifiers.push(Modifier::Prepared);
+ self
+ }
+
+ /// Whether this node was prepared.
+ #[doc(hidden)]
+ pub fn is_prepared(&self) -> bool {
+ self.modifiers.contains(&Modifier::Prepared)
+ }
+
/// Whether a label can be attached to the content.
pub(super) fn labellable(&self) -> bool {
!self.has::<dyn Unlabellable>()
@@ -212,18 +240,21 @@ impl Content {
/// Whether no show rule was executed for this node so far.
pub(super) fn is_pristine(&self) -> bool {
- !self.meta.iter().any(|meta| matches!(meta, Meta::Guard(_)))
+ !self
+ .modifiers
+ .iter()
+ .any(|modifier| matches!(modifier, Modifier::Guard(_)))
}
/// Check whether a show rule recipe is disabled.
pub(super) fn is_guarded(&self, id: Guard) -> bool {
- self.meta.contains(&Meta::Guard(id))
+ self.modifiers.contains(&Modifier::Guard(id))
}
- /// Copy the metadata from other content.
- pub(super) fn copy_meta(&mut self, from: &Content) {
+ /// Copy the modifiers from another piece of content.
+ pub(super) fn copy_modifiers(&mut self, from: &Content) {
self.span = from.span;
- self.meta = from.meta.clone();
+ self.modifiers = from.modifiers.clone();
}
}
@@ -239,12 +270,6 @@ impl Default for Content {
}
}
-impl PartialEq for Content {
- fn eq(&self, other: &Self) -> bool {
- (*self.obj).hash128() == (*other.obj).hash128()
- }
-}
-
impl Add for Content {
type Output = Self;
@@ -371,7 +396,7 @@ pub trait Node: 'static + Capable {
Content {
obj: Arc::new(self),
span: None,
- meta: ThinVec::new(),
+ modifiers: ThinVec::new(),
}
}