diff --git a/RELEASES.md b/RELEASES.md
index d8d05efe5..f1eee4e22 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -22,6 +22,7 @@
- fixed rounding of fractional values to follow latest Chrome - values are now rounded the same regardless of their position
- fixed computing free space when using both `flex-grow` and a minimum size
- padding is now only subtracted when determining the available space if the node size is unspecified, following [section 9.2.2 of the flexbox spec](https://www.w3.org/TR/css-flexbox-1/#line-sizing)
+- `MeasureFunc` (and hence `NodeData` and hence `Forest` and hence the public `Taffy` type) are now `Send` and `Sync`, enabling their use in async and parallel applications
### 0.2.0 Removed
diff --git a/src/node.rs b/src/node.rs
index 502f16e9c..c5429f6ae 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -11,13 +11,20 @@ use crate::sys::Box;
use crate::sys::{new_map_with_capacity, ChildrenVec, Map, Vec};
use core::sync::atomic::{AtomicUsize, Ordering};
-/// A function that can be applied to a `Size<Option<f32>>` to obtain a `Size<f32>`
+/// A function type that can be used in a [`MeasureFunc`]
+///
+/// This trait is automatically implemented for all types (including closures) that define a function with the appropriate type signature.
+pub trait Measurable: Send + Sync + Fn(Size<Option<f32>>) -> Size<f32> {}
+
+impl<F: Send + Sync + Fn(Size<Option<f32>>) -> Size<f32>> Measurable for F {}
+
+/// A function that can be used to compute the intrinsic size of a node
pub enum MeasureFunc {
/// Stores an unboxed function
Raw(fn(Size<Option<f32>>) -> Size<f32>),
/// Stores a boxed function
#[cfg(any(feature = "std", feature = "alloc"))]
- Boxed(Box<dyn Fn(Size<Option<f32>>) -> Size<f32>>),
+ Boxed(Box<dyn Measurable>),
}
/// Global taffy instance id allocator.
@@ -320,3 +327,14 @@ impl Allocator {
Id(self.last_id.fetch_add(1, Ordering::Relaxed))
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn measure_func_is_send_and_sync() {
+ fn is_send_and_sync<T: Sync>() {}
+ is_send_and_sync::<MeasureFunc>();
+ }
+}