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