| 1 | use crate::{grid::config::Entity, settings::TableOption}; |
| 2 | |
| 3 | #[cfg (feature = "std" )] |
| 4 | use crate::settings::CellOption; |
| 5 | |
| 6 | /// Settings is a combinator of [`TableOption`]s. |
| 7 | #[derive (Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] |
| 8 | pub struct Settings<A = EmptySettings, B = EmptySettings>(A, B); |
| 9 | |
| 10 | impl Default for Settings<EmptySettings, EmptySettings> { |
| 11 | fn default() -> Self { |
| 12 | Self(EmptySettings, EmptySettings) |
| 13 | } |
| 14 | } |
| 15 | |
| 16 | impl Settings<(), ()> { |
| 17 | /// Creates an empty list. |
| 18 | pub const fn empty() -> Settings<EmptySettings, EmptySettings> { |
| 19 | Settings(EmptySettings, EmptySettings) |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | impl<A, B> Settings<A, B> { |
| 24 | /// Creates a new combinator. |
| 25 | pub const fn new(settings1: A, settings2: B) -> Settings<A, B> { |
| 26 | Settings(settings1, settings2) |
| 27 | } |
| 28 | |
| 29 | /// Add an option to a combinator. |
| 30 | pub const fn with<C>(self, settings: C) -> Settings<Self, C> { |
| 31 | Settings(self, settings) |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | #[cfg (feature = "std" )] |
| 36 | impl<R, C, A, B> CellOption<R, C> for Settings<A, B> |
| 37 | where |
| 38 | A: CellOption<R, C>, |
| 39 | B: CellOption<R, C>, |
| 40 | { |
| 41 | fn change(self, records: &mut R, cfg: &mut C, entity: Entity) { |
| 42 | self.0.change(records, cfg, entity); |
| 43 | self.1.change(records, cfg, entity); |
| 44 | } |
| 45 | |
| 46 | fn hint_change(&self) -> Option<Entity> { |
| 47 | match (self.0.hint_change(), self.1.hint_change()) { |
| 48 | (None, None) => None, |
| 49 | (Some(a: Entity), Some(b: Entity)) => Some(combine_entity(x1:a, x2:b)), |
| 50 | (None, value: Option) => value, |
| 51 | (value: Option, None) => value, |
| 52 | } |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | impl<R, D, C, A, B> TableOption<R, C, D> for Settings<A, B> |
| 57 | where |
| 58 | A: TableOption<R, C, D>, |
| 59 | B: TableOption<R, C, D>, |
| 60 | { |
| 61 | fn change(self, records: &mut R, cfg: &mut C, dims: &mut D) { |
| 62 | self.0.change(records, cfg, dimension:dims); |
| 63 | self.1.change(records, cfg, dimension:dims); |
| 64 | } |
| 65 | |
| 66 | fn hint_change(&self) -> Option<Entity> { |
| 67 | match (self.0.hint_change(), self.1.hint_change()) { |
| 68 | (None, None) => None, |
| 69 | (Some(a: Entity), Some(b: Entity)) => Some(combine_entity(x1:a, x2:b)), |
| 70 | (None, value: Option) => value, |
| 71 | (value: Option, None) => value, |
| 72 | } |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | /// A marker structure to be able to create an empty [`Settings`]. |
| 77 | #[derive (Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] |
| 78 | pub struct EmptySettings; |
| 79 | |
| 80 | #[cfg (feature = "std" )] |
| 81 | impl<R, C> CellOption<R, C> for EmptySettings { |
| 82 | fn change(self, _: &mut R, _: &mut C, _: Entity) {} |
| 83 | } |
| 84 | |
| 85 | impl<R, D, C> TableOption<R, C, D> for EmptySettings { |
| 86 | fn change(self, _: &mut R, _: &mut C, _: &mut D) {} |
| 87 | } |
| 88 | |
| 89 | fn combine_entity(x1: Entity, x2: Entity) -> Entity { |
| 90 | use Entity::*; |
| 91 | match (x1, x2) { |
| 92 | (_, Global) => Global, |
| 93 | (Global, _) => Global, |
| 94 | (Column(_), Row(_)) => Global, |
| 95 | (Column(a: usize), Column(_)) => Column(a), |
| 96 | (Column(a: usize), Cell(_, _)) => Column(a), |
| 97 | (Row(_), Column(_)) => Global, |
| 98 | (Row(a: usize), Row(_)) => Row(a), |
| 99 | (Row(a: usize), Cell(_, _)) => Row(a), |
| 100 | (Cell(_, _), Column(a: usize)) => Column(a), |
| 101 | (Cell(_, _), Row(a: usize)) => Row(a), |
| 102 | (Cell(a: usize, b: usize), Cell(_, _)) => Cell(a, b), |
| 103 | } |
| 104 | } |
| 105 | |