1 | use crate::{ |
2 | grid::{ |
3 | config::Entity, |
4 | records::{ExactRecords, Records}, |
5 | }, |
6 | settings::{object::Object, CellOption, Settings, TableOption}, |
7 | }; |
8 | |
9 | /// Modify structure provide an abstraction, to be able to apply |
10 | /// a set of [`CellOption`]s to the same object. |
11 | /// |
12 | /// Be aware that the settings are applied all to a cell at a time. |
13 | /// So sometimes you may need to make a several calls of [`Modify`] in order to achieve the desired affect. |
14 | #[derive (Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] |
15 | pub struct Modify<O> { |
16 | obj: O, |
17 | } |
18 | |
19 | impl<O> Modify<O> { |
20 | /// Creates a new [`Modify`] without any options. |
21 | pub const fn new(obj: O) -> Self { |
22 | Self { obj } |
23 | } |
24 | |
25 | /// A function which combines together [`Modify::new`] and [`Modify::with`] calls. |
26 | /// |
27 | /// ``` |
28 | /// use tabled::{Table, settings::{Modify, Padding, object::Rows}}; |
29 | /// |
30 | /// let table = Table::new(&["Year" , "2021" ]) |
31 | /// .with(Modify::list(Rows::first(), Padding::new(1, 1, 1, 1))) |
32 | /// .to_string(); |
33 | /// |
34 | /// assert_eq!( |
35 | /// table, |
36 | /// "+------+ \n\ |
37 | /// | | \n\ |
38 | /// | &str | \n\ |
39 | /// | | \n\ |
40 | /// +------+ \n\ |
41 | /// | Year | \n\ |
42 | /// +------+ \n\ |
43 | /// | 2021 | \n\ |
44 | /// +------+" |
45 | /// ) |
46 | /// ``` |
47 | pub const fn list<M>(obj: O, next: M) -> ModifyList<O, M> { |
48 | ModifyList { |
49 | obj, |
50 | modifiers: next, |
51 | } |
52 | } |
53 | |
54 | /// It's a generic function which stores a [`CellOption`]. |
55 | /// |
56 | /// IMPORTANT: |
57 | /// The function *doesn't* changes a [`Table`]. |
58 | /// [`Table`] will be changed only after passing [`Modify`] object to [`Table::with`]. |
59 | /// |
60 | /// ``` |
61 | /// use tabled::{Table, settings::{Modify, Padding, object::Rows}}; |
62 | /// |
63 | /// let table = Table::new(&["Year" , "2021" ]) |
64 | /// .with(Modify::new(Rows::first()).with(Padding::new(1, 1, 1, 1))) |
65 | /// .to_string(); |
66 | /// |
67 | /// assert_eq!( |
68 | /// table, |
69 | /// "+------+ \n\ |
70 | /// | | \n\ |
71 | /// | &str | \n\ |
72 | /// | | \n\ |
73 | /// +------+ \n\ |
74 | /// | Year | \n\ |
75 | /// +------+ \n\ |
76 | /// | 2021 | \n\ |
77 | /// +------+" |
78 | /// ) |
79 | /// ``` |
80 | /// |
81 | /// [`Table`]: crate::Table |
82 | /// [`Table::with`]: crate::Table::with |
83 | pub fn with<M>(self, next: M) -> ModifyList<O, M> { |
84 | ModifyList { |
85 | obj: self.obj, |
86 | modifiers: next, |
87 | } |
88 | } |
89 | } |
90 | |
91 | /// This is a container of [`CellOption`]s which are applied to a set [`Object`]. |
92 | #[derive (Debug)] |
93 | pub struct ModifyList<O, S> { |
94 | obj: O, |
95 | modifiers: S, |
96 | } |
97 | |
98 | impl<O, M1> ModifyList<O, M1> { |
99 | /// With a generic function which stores a [`CellOption`]. |
100 | /// |
101 | /// IMPORTANT: |
102 | /// The function *doesn't* changes a [`Table`]. |
103 | /// [`Table`] will be changed only after passing [`Modify`] object to [`Table::with`]. |
104 | /// |
105 | /// [`Table`]: crate::Table |
106 | /// [`Table::with`]: crate::Table::with |
107 | pub fn with<M2>(self, next: M2) -> ModifyList<O, Settings<M1, M2>> { |
108 | ModifyList { |
109 | obj: self.obj, |
110 | modifiers: Settings::new(self.modifiers, settings2:next), |
111 | } |
112 | } |
113 | } |
114 | |
115 | impl<O, M, R, D, C> TableOption<R, C, D> for ModifyList<O, M> |
116 | where |
117 | O: Object<R>, |
118 | M: CellOption<R, C> + Clone, |
119 | R: Records + ExactRecords, |
120 | { |
121 | fn change(self, records: &mut R, cfg: &mut C, _: &mut D) { |
122 | for entity: Entity in self.obj.cells(records) { |
123 | self.modifiers.clone().change(records, cfg, entity); |
124 | } |
125 | } |
126 | |
127 | fn hint_change(&self) -> Option<Entity> { |
128 | self.modifiers.hint_change() |
129 | } |
130 | } |
131 | |