tabled/
modify.rs

1use papergrid::{records::Records, Entity};
2
3use crate::{object::Object, CellOption, Table, TableOption};
4
5/// Modify structure provide an abstraction, to be able to apply
6/// a set of [`CellOption`]s to the same object.
7///
8/// Be aware that the settings are applied all to a cell at a time.
9/// So sometimes you may need to make a several calls of [`Modify`] in order to achieve the desired affect.
10#[derive(Debug)]
11pub struct Modify<O> {
12    obj: O,
13}
14
15impl<O> Modify<O>
16where
17    O: Object,
18{
19    /// Creates a new [`Modify`] without any options.
20    pub fn new(obj: O) -> Self {
21        Self { obj }
22    }
23
24    /// It's a generic function which stores a [`CellOption`].
25    ///
26    /// IMPORTANT:
27    ///     The function *doesn't* changes a [`Table`].
28    ///     [`Table`] will be changed only after passing [`Modify`] object to [`Table::with`].
29    ///
30    /// [`Table`]: crate::Table
31    /// [`Table::with`]: crate::Table::with
32    pub fn with<M>(self, s: M) -> ModifyList<O, M> {
33        ModifyList {
34            obj: self.obj,
35            modifiers: s,
36        }
37    }
38}
39
40/// This is a container of [`CellOption`]s which are applied to a set [`Object`].
41#[derive(Debug)]
42pub struct ModifyList<O, S> {
43    obj: O,
44    modifiers: S,
45}
46
47impl<O, M1> ModifyList<O, M1>
48where
49    O: Object,
50{
51    /// With a generic function which stores a [`CellOption`].
52    ///
53    /// IMPORTANT:
54    ///     The function *doesn't* changes a [`Table`].
55    ///     [`Table`] will be changed only after passing [`Modify`] object to [`Table::with`].
56    ///
57    /// [`Table`]: crate::Table
58    /// [`Table::with`]: crate::Table::with
59    pub fn with<M2>(self, s: M2) -> ModifyList<O, CellSettingsList<M1, M2>> {
60        ModifyList {
61            obj: self.obj,
62            modifiers: CellSettingsList {
63                s1: self.modifiers,
64                s2: s,
65            },
66        }
67    }
68}
69
70impl<O, M, R> TableOption<R> for ModifyList<O, M>
71where
72    O: Object,
73    M: CellOption<R>,
74    R: Records,
75{
76    fn change(&mut self, table: &mut Table<R>) {
77        for entity in self.obj.cells(table) {
78            self.modifiers.change_cell(table, entity);
79        }
80    }
81}
82
83/// This is a container of [`CellOption`]s.
84#[derive(Debug)]
85pub struct CellSettingsList<S1, S2> {
86    s1: S1,
87    s2: S2,
88}
89
90impl<M1, M2, R> CellOption<R> for CellSettingsList<M1, M2>
91where
92    M1: CellOption<R>,
93    M2: CellOption<R>,
94{
95    fn change_cell(&mut self, table: &mut Table<R>, entity: Entity) {
96        self.s1.change_cell(table, entity);
97        self.s2.change_cell(table, entity);
98    }
99}
100
101/// An utility trait for a different interface of [`Modify`] creation.
102///
103/// # Example
104///
105/// ```
106/// # use tabled::{object::Cell, Modify, ModifyObject};
107/// // 1st way to create modification container
108/// let m = Modify::new(Cell(1, 1));
109/// // 2nd way to create modification container
110/// let m = Cell(1, 1).modify();
111/// ```
112pub trait ModifyObject: Object {
113    /// Returns a Modify container of [`Object`]
114    fn modify(self) -> Modify<Self> {
115        Modify::new(self)
116    }
117}
118
119impl<O> ModifyObject for O where O: Object {}