diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-12-02 15:41:39 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-12-02 15:45:18 +0100 |
| commit | 9bc90c371fb41a2d6dc08eb4673e5be15f829514 (patch) | |
| tree | 454a47ce82c2229e79a139a8bdeaed9add1e0a14 /src/model/content.rs | |
| parent | 5110a41de1ca2236739ace2d37a1af912bb029f1 (diff) | |
Introspection
Diffstat (limited to 'src/model/content.rs')
| -rw-r--r-- | src/model/content.rs | 67 |
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(), } } |
