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 | |