| //! This module contains a [`Disable`] structure which helps to |
| //! remove an etheir column or row from a [`Table`]. |
| //! |
| //! # Example |
| //! |
| //! ```rust,no_run |
| //! # use tabled::{Table, settings::{Disable, object::Rows}}; |
| //! # let data: Vec<&'static str> = Vec::new(); |
| //! let table = Table::new(&data).with(Disable::row(Rows::first())); |
| //! ``` |
| //! |
| //! [`Table`]: crate::Table |
| |
| use std::marker::PhantomData; |
| |
| use crate::{ |
| grid::records::{ExactRecords, Records, Resizable}, |
| settings::{locator::Locator, TableOption}, |
| }; |
| |
| /// Disable removes particular rows/columns from a [`Table`]. |
| /// |
| /// It tries to keeps track of style changes which may occur. |
| /// But it's not guaranteed will be the way you would expect it to be. |
| /// |
| /// Generally you should avoid use of [`Disable`] because it's a slow function and modifies the underlying records. |
| /// Providing correct data right away is better. |
| /// |
| /// # Example |
| /// |
| /// ``` |
| /// use tabled::{Table, settings::{Disable, object::Rows}}; |
| /// |
| /// let data = vec!["Hello", "World", "!!!"]; |
| /// |
| /// let table = Table::new(data).with(Disable::row(Rows::new(1..2))).to_string(); |
| /// |
| /// assert_eq!( |
| /// table, |
| /// "+-------+\n\ |
| /// | &str |\n\ |
| /// +-------+\n\ |
| /// | World |\n\ |
| /// +-------+\n\ |
| /// | !!! |\n\ |
| /// +-------+" |
| /// ); |
| /// |
| /// ``` |
| /// [`Table`]: crate::Table |
| #[derive(Debug)] |
| pub struct Disable<L, Target> { |
| locator: L, |
| target: PhantomData<Target>, |
| } |
| |
| impl<L> Disable<L, TargetColumn> { |
| /// Disable columns. |
| /// |
| /// Available locators are: |
| /// |
| /// - [`Columns`] |
| /// - [`Column`] |
| /// - [`FirstColumn`] |
| /// - [`LastColumn`] |
| /// - [`ByColumnName`] |
| /// |
| /// ```rust |
| /// use tabled::{builder::Builder, settings::{Disable, locator::ByColumnName, object::Columns}}; |
| /// |
| /// let mut builder = Builder::default(); |
| /// |
| /// builder.push_record(["col1", "col2", "col3"]); |
| /// builder.push_record(["Hello", "World", "1"]); |
| /// |
| /// let table = builder.build() |
| /// .with(Disable::column(ByColumnName::new("col3"))) |
| /// .to_string(); |
| /// |
| /// assert_eq!( |
| /// table, |
| /// "+-------+-------+\n\ |
| /// | col1 | col2 |\n\ |
| /// +-------+-------+\n\ |
| /// | Hello | World |\n\ |
| /// +-------+-------+" |
| /// ); |
| /// ``` |
| /// |
| /// [`Columns`]: crate::settings::object::Columns |
| /// [`Column`]: crate::settings::object::Column |
| /// [`FirstColumn`]: crate::settings::object::FirstColumn |
| /// [`LastColumn`]: crate::settings::object::LastColumn |
| /// [`ByColumnName`]: crate::settings::locator::ByColumnName |
| pub fn column(locator: L) -> Self { |
| Self { |
| locator, |
| target: PhantomData, |
| } |
| } |
| } |
| |
| impl<L> Disable<L, TargetRow> { |
| /// Disable rows. |
| /// |
| /// Available locators are: |
| /// |
| /// - [`Rows`] |
| /// - [`Row`] |
| /// - [`FirstRow`] |
| /// - [`LastRow`] |
| /// |
| /// ```rust |
| /// use tabled::{settings::{Disable, object::Rows}, builder::Builder}; |
| /// |
| /// let mut builder = Builder::default(); |
| /// builder.push_record(["col1", "col2", "col3"]); |
| /// builder.push_record(["Hello", "World", "1"]); |
| /// |
| /// let table = builder.build() |
| /// .with(Disable::row(Rows::first())) |
| /// .to_string(); |
| /// |
| /// assert_eq!( |
| /// table, |
| /// "+-------+-------+---+\n\ |
| /// | Hello | World | 1 |\n\ |
| /// +-------+-------+---+" |
| /// ); |
| /// ``` |
| /// |
| /// [`Rows`]: crate::settings::object::Rows |
| /// [`Row`]: crate::settings::object::Row |
| /// [`FirstRow`]: crate::settings::object::FirstRow |
| /// [`LastRow`]: crate::settings::object::LastRow |
| pub fn row(locator: L) -> Self { |
| Self { |
| locator, |
| target: PhantomData, |
| } |
| } |
| } |
| |
| /// A marker struct for [`Disable`]. |
| #[derive(Debug)] |
| pub struct TargetRow; |
| |
| /// A marker struct for [`Disable`]. |
| #[derive(Debug)] |
| pub struct TargetColumn; |
| |
| impl<L, R, D, C> TableOption<R, D, C> for Disable<L, TargetColumn> |
| where |
| for<'a> L: Locator<&'a R, Coordinate = usize>, |
| R: Records + Resizable, |
| { |
| fn change(mut self, records: &mut R, _: &mut C, _: &mut D) { |
| let columns = self.locator.locate(records).into_iter().collect::<Vec<_>>(); |
| |
| let mut shift = 0; |
| for col in columns.into_iter() { |
| if col - shift > records.count_columns() { |
| continue; |
| } |
| |
| records.remove_column(col - shift); |
| shift += 1; |
| } |
| |
| // fixme: I am pretty sure that we violate span constrains by removing rows/cols |
| // Because span may be bigger then the max number of rows/cols |
| } |
| } |
| |
| impl<L, R, D, C> TableOption<R, D, C> for Disable<L, TargetRow> |
| where |
| for<'a> L: Locator<&'a R, Coordinate = usize>, |
| R: ExactRecords + Resizable, |
| { |
| fn change(mut self, records: &mut R, _: &mut C, _: &mut D) { |
| let rows = self.locator.locate(records).into_iter().collect::<Vec<_>>(); |
| |
| let mut shift = 0; |
| for row in rows.into_iter() { |
| if row - shift > records.count_rows() { |
| continue; |
| } |
| |
| records.remove_row(row - shift); |
| shift += 1; |
| } |
| |
| // fixme: I am pretty sure that we violate span constrains by removing rows/cols |
| // Because span may be bigger then the max number of rows/cols |
| } |
| } |