Repository: zhiburt/tabled
Pull request #368 (2023-10-31 20:25:48)

tabled/ Add Table::modify method


Patch:
diff --git a/tabled/examples/target_content.rs b/tabled/examples/target_content.rs
index 3bb3fc2..fcbea2a 100644
--- a/tabled/examples/target_content.rs
+++ b/tabled/examples/target_content.rs
@@ -7,7 +7,7 @@
 //! specifications. This is helpful for organizing extensive [`Table`] configurations.
 
 use tabled::{
-    settings::{location::ByContent, style::Style, Color, Modify},
+    settings::{location::Locator, style::Style, Color},
     Table, Tabled,
 };
 
@@ -48,14 +48,14 @@ fn main() {
         Job::new("Kernel Developer", JobStatus::Open),
     ];
 
-    let color_open_jobs = Color::BG_WHITE | Color::FG_BLACK;
-    let color_closed_jobs = Color::BG_GREEN | Color::FG_BLACK;
-
     let mut table = Table::new(data);
     table
         .with(Style::empty())
-        .with(Modify::list(ByContent::new("open"), color_open_jobs))
-        .with(Modify::list(ByContent::new("closed"), color_closed_jobs));
+        .modify(Locator::content("open"), Color::BG_WHITE | Color::FG_BLACK)
+        .modify(
+            Locator::content("closed"),
+            Color::BG_GREEN | Color::FG_BLACK,
+        );
 
     println!("{table}");
 }
diff --git a/tabled/src/lib.rs b/tabled/src/lib.rs
index 84591ba..5170be2 100644
--- a/tabled/src/lib.rs
+++ b/tabled/src/lib.rs
@@ -252,6 +252,7 @@
 //! [`fmt::Write`]: core::fmt::Write
 //! [`row!`]: crate::row
 //! [`col!`]: crate::col
+//! [`tabled::settings`]: crate::settings
 
 #![cfg_attr(not(any(feature = "std", test)), no_std)]
 #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git a/tabled/src/settings/cell_option.rs b/tabled/src/settings/cell_option.rs
index a6456f6..bbbf5d2 100644
--- a/tabled/src/settings/cell_option.rs
+++ b/tabled/src/settings/cell_option.rs
@@ -28,6 +28,8 @@ pub trait CellOption<R, C> {
     ///
     /// This methods primarily is used as an optimization,
     /// to not make unnessary calculations if they're not needed, after using the [`TableOption`].
+    ///
+    /// [`TableOption`]: crate::settings::TableOption
     fn hint_change(&self) -> Option<Entity> {
         Some(Entity::Global)
     }
diff --git a/tabled/src/settings/disable/mod.rs b/tabled/src/settings/disable/mod.rs
index 45ffe31..6b4806a 100644
--- a/tabled/src/settings/disable/mod.rs
+++ b/tabled/src/settings/disable/mod.rs
@@ -91,7 +91,7 @@ impl<L> Disable<L, TargetColumn> {
     /// [`Column`]: crate::settings::object::Column
     /// [`FirstColumn`]: crate::settings::object::FirstColumn
     /// [`LastColumn`]: crate::settings::object::LastColumn
-    /// [`ByColumnName`]: crate::settings::locator::ByColumnName
+    /// [`ByColumnName`]: crate::settings::location::ByColumnName
     pub fn column(locator: L) -> Self {
         Self {
             locator,
diff --git a/tabled/src/settings/location/by_column_name.rs b/tabled/src/settings/location/by_column_name.rs
index 64f18f8..eafb828 100644
--- a/tabled/src/settings/location/by_column_name.rs
+++ b/tabled/src/settings/location/by_column_name.rs
@@ -5,7 +5,7 @@ use crate::{
     settings::object::Object,
 };
 
-/// The structure is an implementation of [`Locator`] to search for a column by it's name.
+/// The structure is an implementation of [`Location`] to search for a column by it's name.
 /// A name is considered be a value in a first row.
 ///
 /// So even if in reality there's no header, the first row will be considered to be one.
diff --git a/tabled/src/settings/location/by_condition.rs b/tabled/src/settings/location/by_condition.rs
index de8492a..f37a0ea 100644
--- a/tabled/src/settings/location/by_condition.rs
+++ b/tabled/src/settings/location/by_condition.rs
@@ -8,7 +8,7 @@ use crate::{
     settings::object::Object,
 };
 
-/// The structure is an implementation of [`Locator`] to search for cells with a specified condition.
+/// The structure is an implementation of [`Location`] to search for cells with a specified condition.
 #[derive(Debug, Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
 pub struct ByCondition<F>(F);
 
diff --git a/tabled/src/settings/location/by_content.rs b/tabled/src/settings/location/by_content.rs
index a339bba..df990e3 100644
--- a/tabled/src/settings/location/by_content.rs
+++ b/tabled/src/settings/location/by_content.rs
@@ -8,7 +8,7 @@ use crate::{
     settings::object::Object,
 };
 
-/// The structure is an implementation of [`Locator`] to search for cells with a given content.
+/// The structure is an implementation of [`Location`] to search for cells with a given content.
 #[derive(Debug, Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
 pub struct ByContent<S>(S);
 
diff --git a/tabled/src/settings/style/builder.rs b/tabled/src/settings/style/builder.rs
index 0cde2c7..f0dbadb 100644
--- a/tabled/src/settings/style/builder.rs
+++ b/tabled/src/settings/style/builder.rs
@@ -295,7 +295,7 @@ impl Style<(), (), (), (), (), (), (), ()> {
         )
     }
 
-    /// This style looks like a [`Style::round`] but with horizontal lines.
+    /// This style looks like a [`Style::modern_round`] but with horizontal lines.
     ///
     /// Beware: It uses UTF-8 characters.
     ///
diff --git a/tabled/src/tables/table.rs b/tabled/src/tables/table.rs
index 9eb365e..789a85f 100644
--- a/tabled/src/tables/table.rs
+++ b/tabled/src/tables/table.rs
@@ -18,7 +18,7 @@ use crate::{
         },
         PeekableGrid,
     },
-    settings::{Style, TableOption},
+    settings::{object::Object, CellOption, Style, TableOption},
     Tabled,
 };
 
@@ -172,7 +172,7 @@ impl Table {
         b
     }
 
-    /// With is a generic function which applies options to the [`Table`].
+    /// It's a generic function which applies options to the [`Table`].
     ///
     /// It applies settings immediately.
     pub fn with<O>(&mut self, option: O) -> &mut Self
@@ -194,6 +194,30 @@ impl Table {
         self
     }
 
+    /// It's a generic function which applies options to a particalar cells on the [`Table`].
+    /// Target cells using [`Object`]s such as [`Cell`], [`Rows`], [`Location`] and more.
+    ///
+    /// It applies settings immediately.
+    ///
+    /// [`Cell`]: crate::settings::object::Cell
+    /// [`Rows`]: crate::settings::object::Rows
+    /// [`Location`]: crate::settings::location::Locator
+    pub fn modify<T, O>(&mut self, target: T, option: O) -> &mut Self
+    where
+        T: Object<VecRecords<CellInfo<String>>>,
+        O: CellOption<VecRecords<CellInfo<String>>, ColoredConfig> + Clone,
+    {
+        for entity in target.cells(&self.records) {
+            let opt = option.clone();
+            opt.change(&mut self.records, &mut self.config, entity);
+        }
+
+        let reastimation_hint = option.hint_change();
+        dimension_reastimate_likely(&mut self.dimension, reastimation_hint);
+
+        self
+    }
+
     /// Returns a table shape (count rows, count columns).
     pub fn shape(&self) -> (usize, usize) {
         (self.count_rows(), self.count_columns())
@@ -526,3 +550,21 @@ fn dims_set_heights(dims: &mut CompleteDimensionVecRecords<'_>, list: Option<Vec
         }
     }
 }
+
+fn dimension_reastimate_likely(dims: &mut CompleteDimensionVecRecords<'_>, hint: Option<Entity>) {
+    let hint = match hint {
+        Some(hint) => hint,
+        None => return,
+    };
+
+    match hint {
+        Entity::Global | Entity::Cell(_, _) => {
+            dims.clear_width();
+            dims.clear_height()
+        }
+        Entity::Column(_) => {
+            dims.clear_width();
+        }
+        Entity::Row(_) => dims.clear_height(),
+    }
+}


Test patch:
diff --git a/tabled/tests/core/table_test.rs b/tabled/tests/core/table_test.rs
index b949626..5b97063 100644
--- a/tabled/tests/core/table_test.rs
+++ b/tabled/tests/core/table_test.rs
@@ -845,3 +845,16 @@ test_table!(
     "├┼┤"
     "└┴┘"
 );
+
+test_table!(
+    table_modify_test,
+    Matrix::new(3, 3)
+        .with(Style::markdown())
+        .modify((1, 0), "Hello World")
+        .modify((0, 1), "Hello World 2"),
+    "|      N      | Hello World 2 | column 1 | column 2 |"
+    "|-------------|---------------|----------|----------|"
+    "| Hello World |      0-0      |   0-1    |   0-2    |"
+    "|      1      |      1-0      |   1-1    |   1-2    |"
+    "|      2      |      2-0      |   2-1    |   2-2    |"
+);