tabled/settings/
modify.rs

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