1 | //! This module contains a [`Disable`] structure which helps to |
2 | //! remove an etheir column or row from a [`Table`]. |
3 | //! |
4 | //! # Example |
5 | //! |
6 | //! ```rust,no_run |
7 | //! # use tabled::{Table, settings::{Disable, object::Rows}}; |
8 | //! # let data: Vec<&'static str> = Vec::new(); |
9 | //! let table = Table::new(&data).with(Disable::row(Rows::first())); |
10 | //! ``` |
11 | //! |
12 | //! [`Table`]: crate::Table |
13 | |
14 | use std::marker::PhantomData; |
15 | |
16 | use crate::{ |
17 | grid::records::{ExactRecords, Records, Resizable}, |
18 | settings::{location::Location, TableOption}, |
19 | }; |
20 | |
21 | /// Disable removes particular rows/columns from a [`Table`]. |
22 | /// |
23 | /// It tries to keeps track of style changes which may occur. |
24 | /// But it's not guaranteed will be the way you would expect it to be. |
25 | /// |
26 | /// Generally you should avoid use of [`Disable`] because it's a slow function and modifies the underlying records. |
27 | /// Providing correct data right away is better. |
28 | /// |
29 | /// # Example |
30 | /// |
31 | /// ``` |
32 | /// use tabled::{Table, settings::{Disable, object::Rows}}; |
33 | /// |
34 | /// let data = vec!["Hello" , "World" , "!!!" ]; |
35 | /// |
36 | /// let table = Table::new(data).with(Disable::row(Rows::new(1..2))).to_string(); |
37 | /// |
38 | /// assert_eq!( |
39 | /// table, |
40 | /// "+-------+ \n\ |
41 | /// | &str | \n\ |
42 | /// +-------+ \n\ |
43 | /// | World | \n\ |
44 | /// +-------+ \n\ |
45 | /// | !!! | \n\ |
46 | /// +-------+" |
47 | /// ); |
48 | /// |
49 | /// ``` |
50 | /// [`Table`]: crate::Table |
51 | #[derive (Debug)] |
52 | pub struct Disable<L, Target> { |
53 | locator: L, |
54 | target: PhantomData<Target>, |
55 | } |
56 | |
57 | impl<L> Disable<L, TargetColumn> { |
58 | /// Disable columns. |
59 | /// |
60 | /// Available locators are: |
61 | /// |
62 | /// - [`Columns`] |
63 | /// - [`Column`] |
64 | /// - [`FirstColumn`] |
65 | /// - [`LastColumn`] |
66 | /// - [`ByColumnName`] |
67 | /// |
68 | /// ```rust |
69 | /// use tabled::{builder::Builder, settings::{Disable, location::ByColumnName, object::Columns}}; |
70 | /// |
71 | /// let mut builder = Builder::default(); |
72 | /// builder.push_record(["col1" , "col2" , "col3" ]); |
73 | /// builder.push_record(["Hello" , "World" , "1" ]); |
74 | /// |
75 | /// let table = builder.build() |
76 | /// .with(Disable::column(ByColumnName::new("col3" ))) |
77 | /// .to_string(); |
78 | /// |
79 | /// assert_eq!( |
80 | /// table, |
81 | /// "+-------+-------+ \n\ |
82 | /// | col1 | col2 | \n\ |
83 | /// +-------+-------+ \n\ |
84 | /// | Hello | World | \n\ |
85 | /// +-------+-------+" |
86 | /// ); |
87 | /// ``` |
88 | /// |
89 | /// [`Columns`]: crate::settings::object::Columns |
90 | /// [`Column`]: crate::settings::object::Column |
91 | /// [`FirstColumn`]: crate::settings::object::FirstColumn |
92 | /// [`LastColumn`]: crate::settings::object::LastColumn |
93 | /// [`ByColumnName`]: crate::settings::location::ByColumnName |
94 | pub fn column(locator: L) -> Self { |
95 | Self { |
96 | locator, |
97 | target: PhantomData, |
98 | } |
99 | } |
100 | } |
101 | |
102 | impl<L> Disable<L, TargetRow> { |
103 | /// Disable rows. |
104 | /// |
105 | /// Available locators are: |
106 | /// |
107 | /// - [`Rows`] |
108 | /// - [`Row`] |
109 | /// - [`FirstRow`] |
110 | /// - [`LastRow`] |
111 | /// |
112 | /// ```rust |
113 | /// use tabled::{settings::{Disable, object::Rows}, builder::Builder}; |
114 | /// |
115 | /// let mut builder = Builder::default(); |
116 | /// builder.push_record(["col1" , "col2" , "col3" ]); |
117 | /// builder.push_record(["Hello" , "World" , "1" ]); |
118 | /// |
119 | /// let table = builder.build() |
120 | /// .with(Disable::row(Rows::first())) |
121 | /// .to_string(); |
122 | /// |
123 | /// assert_eq!( |
124 | /// table, |
125 | /// "+-------+-------+---+ \n\ |
126 | /// | Hello | World | 1 | \n\ |
127 | /// +-------+-------+---+" |
128 | /// ); |
129 | /// ``` |
130 | /// |
131 | /// [`Rows`]: crate::settings::object::Rows |
132 | /// [`Row`]: crate::settings::object::Row |
133 | /// [`FirstRow`]: crate::settings::object::FirstRow |
134 | /// [`LastRow`]: crate::settings::object::LastRow |
135 | pub fn row(locator: L) -> Self { |
136 | Self { |
137 | locator, |
138 | target: PhantomData, |
139 | } |
140 | } |
141 | } |
142 | |
143 | /// A marker struct for [`Disable`]. |
144 | #[derive (Debug)] |
145 | pub struct TargetRow; |
146 | |
147 | /// A marker struct for [`Disable`]. |
148 | #[derive (Debug)] |
149 | pub struct TargetColumn; |
150 | |
151 | impl<L, R, D, C> TableOption<R, C, D> for Disable<L, TargetColumn> |
152 | where |
153 | L: Location<R, Coordinate = usize>, |
154 | R: Records + Resizable, |
155 | { |
156 | fn change(mut self, records: &mut R, _: &mut C, _: &mut D) { |
157 | let columns: Vec<{unknown}> = self.locator.locate(records).into_iter().collect::<Vec<_>>(); |
158 | |
159 | let mut shift: i32 = 0; |
160 | for col in columns.into_iter() { |
161 | if col - shift > records.count_columns() { |
162 | continue; |
163 | } |
164 | |
165 | records.remove_column(col - shift); |
166 | shift += 1; |
167 | } |
168 | |
169 | // fixme: I am pretty sure that we violate span constrains by removing rows/cols |
170 | // Because span may be bigger then the max number of rows/cols |
171 | } |
172 | } |
173 | |
174 | impl<L, R, D, C> TableOption<R, C, D> for Disable<L, TargetRow> |
175 | where |
176 | L: Location<R, Coordinate = usize>, |
177 | R: ExactRecords + Resizable, |
178 | { |
179 | fn change(mut self, records: &mut R, _: &mut C, _: &mut D) { |
180 | let rows: Vec = self.locator.locate(records).into_iter().collect::<Vec<_>>(); |
181 | |
182 | let mut shift: usize = 0; |
183 | for row: usize in rows.into_iter() { |
184 | if row - shift > records.count_rows() { |
185 | continue; |
186 | } |
187 | |
188 | records.remove_row(row - shift); |
189 | shift += 1; |
190 | } |
191 | |
192 | // fixme: I am pretty sure that we violate span constrains by removing rows/cols |
193 | // Because span may be bigger then the max number of rows/cols |
194 | } |
195 | } |
196 | |