diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-10-28 16:49:41 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-10-31 08:57:44 +0100 |
| commit | 66ad023519e5250f88f9066a2607efe5442a7b76 (patch) | |
| tree | b858ec6e488edb4cdd639fd4078adab42c00c33f /src/model/fold.rs | |
| parent | 95e9134a3c7d7a14d8c8928413fdffc665671895 (diff) | |
Split up some files
Diffstat (limited to 'src/model/fold.rs')
| -rw-r--r-- | src/model/fold.rs | 81 |
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)) + } +} |
