//! 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 { locator: L, target: PhantomData, } impl Disable { /// 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 Disable { /// 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 TableOption for Disable 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::>(); 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 TableOption for Disable 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::>(); 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 } }