summaryrefslogtreecommitdiff
path: root/src/eval
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-12-16 14:43:02 +0100
committerLaurenz <laurmaedje@gmail.com>2021-12-16 14:43:02 +0100
commit958f74f77707340f34ee36d09492bdb74523aa2a (patch)
tree4ab59a7a532c8023a5e8bb4c9a6090886cb4e538 /src/eval
parent2a3d0f4b390457174ed09347dd29e97ff9a783e4 (diff)
Set Rules Episode VIII: The First Macro
Diffstat (limited to 'src/eval')
-rw-r--r--src/eval/node.rs7
-rw-r--r--src/eval/styles.rs79
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) => {