diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-12-16 14:43:02 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-12-16 14:43:02 +0100 |
| commit | 958f74f77707340f34ee36d09492bdb74523aa2a (patch) | |
| tree | 4ab59a7a532c8023a5e8bb4c9a6090886cb4e538 /src/eval | |
| parent | 2a3d0f4b390457174ed09347dd29e97ff9a783e4 (diff) | |
Set Rules Episode VIII: The First Macro
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/node.rs | 7 | ||||
| -rw-r--r-- | src/eval/styles.rs | 79 |
2 files changed, 15 insertions, 71 deletions
diff --git a/src/eval/node.rs b/src/eval/node.rs index a04fe84b..acdf4ed6 100644 --- a/src/eval/node.rs +++ b/src/eval/node.rs @@ -1,6 +1,7 @@ use std::convert::TryFrom; use std::fmt::Debug; use std::hash::Hash; +use std::iter::Sum; use std::mem; use std::ops::{Add, AddAssign}; @@ -127,6 +128,12 @@ impl AddAssign for Node { } } +impl Sum for Node { + fn sum<I: Iterator<Item = Self>>(iter: I) -> Self { + Self::Sequence(iter.map(|n| (n, Styles::new())).collect()) + } +} + /// Packs a [`Node`] into a flow or whole document. struct Packer { /// Whether this packer produces the top-level document. diff --git a/src/eval/styles.rs b/src/eval/styles.rs index 555c2a61..2396646f 100644 --- a/src/eval/styles.rs +++ b/src/eval/styles.rs @@ -68,7 +68,9 @@ impl Styles { where P::Value: Copy, { - self.get_direct(key).copied().unwrap_or_else(P::default) + self.get_direct(key) + .map(|&v| P::combine(v, P::default())) + .unwrap_or_else(P::default) } /// Get a reference to a style property. @@ -249,9 +251,6 @@ pub trait Property: Copy + 'static { /// The name of the property, used for debug printing. const NAME: &'static str; - /// Combine the property with an outer value. - fn combine(inner: Self::Value, outer: Self::Value) -> Self::Value; - /// The default value of the property. fn default() -> Self::Value; @@ -261,6 +260,11 @@ pub trait Property: Copy + 'static { /// `properties!` macro. This way, expensive defaults don't need to be /// recreated all the time. fn default_ref() -> &'static Self::Value; + + /// Combine the property with an outer value. + fn combine(inner: Self::Value, _: Self::Value) -> Self::Value { + inner + } } /// A unique identifier for a style property. @@ -274,73 +278,6 @@ impl StyleId { } } -/// Generate the property keys for a node. -macro_rules! properties { - ($node:ty, $( - $(#[doc = $doc:expr])* - $(#[fold($combine:expr)])? - $name:ident: $type:ty = $default:expr - ),* $(,)?) => { - // TODO(set): Fix possible name clash. - mod properties { - use std::marker::PhantomData; - use $crate::eval::{Property, StyleId}; - use super::*; - - $(#[allow(non_snake_case)] mod $name { - use once_cell::sync::Lazy; - use super::*; - - pub struct Key<T>(pub PhantomData<T>); - - impl<T> Copy for Key<T> {} - impl<T> Clone for Key<T> { - fn clone(&self) -> Self { - *self - } - } - - impl Property for Key<$type> { - type Value = $type; - - const NAME: &'static str = concat!( - stringify!($node), "::", stringify!($name) - ); - - #[allow(unused_mut, unused_variables)] - fn combine(mut inner: Self::Value, outer: Self::Value) -> Self::Value { - $( - let combine: fn(Self::Value, Self::Value) -> Self::Value = $combine; - inner = combine(inner, outer); - )? - inner - } - - fn default() -> Self::Value { - $default - } - - fn default_ref() -> &'static Self::Value { - static LAZY: Lazy<$type> = Lazy::new(|| $default); - &*LAZY - } - } - })* - - impl $node { - /// Check whether the property with the given type id belongs to - /// `Self`. - pub fn has_property(id: StyleId) -> bool { - false || $(id == StyleId::of::<$name::Key<$type>>())||* - } - - $($(#[doc = $doc])* pub const $name: $name::Key<$type> - = $name::Key(PhantomData);)* - } - } - }; -} - /// Set a style property to a value if the value is `Some`. macro_rules! set { ($styles:expr, $target:expr => $value:expr) => { |
