1use 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)]
15pub struct Modify<O> {
16 obj: O,
17}
18
19impl<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)]
93pub struct ModifyList<O, S> {
94 obj: O,
95 modifiers: S,
96}
97
98impl<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
115impl<O, M, R, D, C> TableOption<R, C, D> for ModifyList<O, M>
116where
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