summaryrefslogtreecommitdiff
path: root/src/model/fold.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-10-28 16:49:41 +0200
committerLaurenz <laurmaedje@gmail.com>2022-10-31 08:57:44 +0100
commit66ad023519e5250f88f9066a2607efe5442a7b76 (patch)
treeb858ec6e488edb4cdd639fd4078adab42c00c33f /src/model/fold.rs
parent95e9134a3c7d7a14d8c8928413fdffc665671895 (diff)
Split up some files
Diffstat (limited to 'src/model/fold.rs')
-rw-r--r--src/model/fold.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/model/fold.rs b/src/model/fold.rs
new file mode 100644
index 00000000..bc85be01
--- /dev/null
+++ b/src/model/fold.rs
@@ -0,0 +1,81 @@
+use super::Smart;
+use crate::geom::{Abs, Corners, Length, Rel, Sides};
+
+/// A property that is folded to determine its final value.
+pub trait Fold {
+ /// The type of the folded output.
+ type Output;
+
+ /// Fold this inner value with an outer folded value.
+ fn fold(self, outer: Self::Output) -> Self::Output;
+}
+
+impl<T> Fold for Option<T>
+where
+ T: Fold,
+ T::Output: Default,
+{
+ type Output = Option<T::Output>;
+
+ fn fold(self, outer: Self::Output) -> Self::Output {
+ self.map(|inner| inner.fold(outer.unwrap_or_default()))
+ }
+}
+
+impl<T> Fold for Smart<T>
+where
+ T: Fold,
+ T::Output: Default,
+{
+ type Output = Smart<T::Output>;
+
+ fn fold(self, outer: Self::Output) -> Self::Output {
+ self.map(|inner| inner.fold(outer.unwrap_or_default()))
+ }
+}
+
+impl<T> Fold for Sides<T>
+where
+ T: Fold,
+{
+ type Output = Sides<T::Output>;
+
+ fn fold(self, outer: Self::Output) -> Self::Output {
+ self.zip(outer, |inner, outer| inner.fold(outer))
+ }
+}
+
+impl Fold for Sides<Option<Rel<Abs>>> {
+ type Output = Sides<Rel<Abs>>;
+
+ fn fold(self, outer: Self::Output) -> Self::Output {
+ self.zip(outer, |inner, outer| inner.unwrap_or(outer))
+ }
+}
+
+impl Fold for Sides<Option<Smart<Rel<Length>>>> {
+ type Output = Sides<Smart<Rel<Length>>>;
+
+ fn fold(self, outer: Self::Output) -> Self::Output {
+ self.zip(outer, |inner, outer| inner.unwrap_or(outer))
+ }
+}
+
+impl<T> Fold for Corners<T>
+where
+ T: Fold,
+{
+ type Output = Corners<T::Output>;
+
+ fn fold(self, outer: Self::Output) -> Self::Output {
+ self.zip(outer, |inner, outer| inner.fold(outer))
+ }
+}
+
+impl Fold for Corners<Option<Rel<Abs>>> {
+ type Output = Corners<Rel<Abs>>;
+
+ fn fold(self, outer: Self::Output) -> Self::Output {
+ self.zip(outer, |inner, outer| inner.unwrap_or(outer))
+ }
+}