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::{locator::Locator, 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, locator::ByColumnName, object::Columns}}; |
70 | /// |
71 | /// let mut builder = Builder::default(); |
72 | /// |
73 | /// builder.push_record(["col1" , "col2" , "col3" ]); |
74 | /// builder.push_record(["Hello" , "World" , "1" ]); |
75 | /// |
76 | /// let table = builder.build() |
77 | /// .with(Disable::column(ByColumnName::new("col3" ))) |
78 | /// .to_string(); |
79 | /// |
80 | /// assert_eq!( |
81 | /// table, |
82 | /// "+-------+-------+ \n\ |
83 | /// | col1 | col2 | \n\ |
84 | /// +-------+-------+ \n\ |
85 | /// | Hello | World | \n\ |
86 | /// +-------+-------+" |
87 | /// ); |
88 | /// ``` |
89 | /// |
90 | /// [`Columns`]: crate::settings::object::Columns |
91 | /// [`Column`]: crate::settings::object::Column |
92 | /// [`FirstColumn`]: crate::settings::object::FirstColumn |
93 | /// [`LastColumn`]: crate::settings::object::LastColumn |
94 | /// [`ByColumnName`]: crate::settings::locator::ByColumnName |
95 | pub fn column(locator: L) -> Self { |
96 | Self { |
97 | locator, |
98 | target: PhantomData, |
99 | } |
100 | } |
101 | } |
102 | |
103 | impl<L> Disable<L, TargetRow> { |
104 | /// Disable rows. |
105 | /// |
106 | /// Available locators are: |
107 | /// |
108 | /// - [`Rows`] |
109 | /// - [`Row`] |
110 | /// - [`FirstRow`] |
111 | /// - [`LastRow`] |
112 | /// |
113 | /// ```rust |
114 | /// use tabled::{settings::{Disable, object::Rows}, builder::Builder}; |
115 | /// |
116 | /// let mut builder = Builder::default(); |
117 | /// builder.push_record(["col1" , "col2" , "col3" ]); |
118 | /// builder.push_record(["Hello" , "World" , "1" ]); |
119 | /// |
120 | /// let table = builder.build() |
121 | /// .with(Disable::row(Rows::first())) |
122 | /// .to_string(); |
123 | /// |
124 | /// assert_eq!( |
125 | /// table, |
126 | /// "+-------+-------+---+ \n\ |
127 | /// | Hello | World | 1 | \n\ |
128 | /// +-------+-------+---+" |
129 | /// ); |
130 | /// ``` |
131 | /// |
132 | /// [`Rows`]: crate::settings::object::Rows |
133 | /// [`Row`]: crate::settings::object::Row |
134 | /// [`FirstRow`]: crate::settings::object::FirstRow |
135 | /// [`LastRow`]: crate::settings::object::LastRow |
136 | pub fn row(locator: L) -> Self { |
137 | Self { |
138 | locator, |
139 | target: PhantomData, |
140 | } |
141 | } |
142 | } |
143 | |
144 | /// A marker struct for [`Disable`]. |
145 | #[derive (Debug)] |
146 | pub struct TargetRow; |
147 | |
148 | /// A marker struct for [`Disable`]. |
149 | #[derive (Debug)] |
150 | pub struct TargetColumn; |
151 | |
152 | impl<L, R, D, C> TableOption<R, D, C> for Disable<L, TargetColumn> |
153 | where |
154 | for<'a> L: Locator<&'a R, Coordinate = usize>, |
155 | R: Records + Resizable, |
156 | { |
157 | fn change(mut self, records: &mut R, _: &mut C, _: &mut D) { |
158 | let columns: Vec<{unknown}> = self.locator.locate(records).into_iter().collect::<Vec<_>>(); |
159 | |
160 | let mut shift: i32 = 0; |
161 | for col in columns.into_iter() { |
162 | if col - shift > records.count_columns() { |
163 | continue; |
164 | } |
165 | |
166 | records.remove_column(col - shift); |
167 | shift += 1; |
168 | } |
169 | |
170 | // fixme: I am pretty sure that we violate span constrains by removing rows/cols |
171 | // Because span may be bigger then the max number of rows/cols |
172 | } |
173 | } |
174 | |
175 | impl<L, R, D, C> TableOption<R, D, C> for Disable<L, TargetRow> |
176 | where |
177 | for<'a> L: Locator<&'a R, Coordinate = usize>, |
178 | R: ExactRecords + Resizable, |
179 | { |
180 | fn change(mut self, records: &mut R, _: &mut C, _: &mut D) { |
181 | let rows: Vec = self.locator.locate(records).into_iter().collect::<Vec<_>>(); |
182 | |
183 | let mut shift: usize = 0; |
184 | for row: usize in rows.into_iter() { |
185 | if row - shift > records.count_rows() { |
186 | continue; |
187 | } |
188 | |
189 | records.remove_row(row - shift); |
190 | shift += 1; |
191 | } |
192 | |
193 | // fixme: I am pretty sure that we violate span constrains by removing rows/cols |
194 | // Because span may be bigger then the max number of rows/cols |
195 | } |
196 | } |
197 | |