summaryrefslogtreecommitdiffstats
path: root/vendor/tabled/src/settings/panel
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/tabled/src/settings/panel')
-rw-r--r--vendor/tabled/src/settings/panel/footer.rs32
-rw-r--r--vendor/tabled/src/settings/panel/header.rs32
-rw-r--r--vendor/tabled/src/settings/panel/horizontal_panel.rs80
-rw-r--r--vendor/tabled/src/settings/panel/mod.rs127
-rw-r--r--vendor/tabled/src/settings/panel/vertical_panel.rs83
5 files changed, 354 insertions, 0 deletions
diff --git a/vendor/tabled/src/settings/panel/footer.rs b/vendor/tabled/src/settings/panel/footer.rs
new file mode 100644
index 000000000..8d16481cf
--- /dev/null
+++ b/vendor/tabled/src/settings/panel/footer.rs
@@ -0,0 +1,32 @@
+use crate::{
+ grid::config::ColoredConfig,
+ grid::records::{ExactRecords, Records, RecordsMut, Resizable},
+ settings::TableOption,
+};
+
+use super::Panel;
+
+/// Footer renders a [`Panel`] at the bottom.
+/// See [`Panel`].
+#[derive(Debug)]
+pub struct Footer<S>(S);
+
+impl<S> Footer<S> {
+ /// Creates a new object.
+ pub fn new(text: S) -> Self
+ where
+ S: AsRef<str>,
+ {
+ Self(text)
+ }
+}
+
+impl<S, R, D> TableOption<R, D, ColoredConfig> for Footer<S>
+where
+ S: AsRef<str>,
+ R: Records + ExactRecords + Resizable + RecordsMut<String>,
+{
+ fn change(self, records: &mut R, cfg: &mut ColoredConfig, dimension: &mut D) {
+ Panel::horizontal(records.count_rows(), self.0.as_ref()).change(records, cfg, dimension);
+ }
+}
diff --git a/vendor/tabled/src/settings/panel/header.rs b/vendor/tabled/src/settings/panel/header.rs
new file mode 100644
index 000000000..e9d398cb5
--- /dev/null
+++ b/vendor/tabled/src/settings/panel/header.rs
@@ -0,0 +1,32 @@
+use crate::{
+ grid::config::ColoredConfig,
+ grid::records::{ExactRecords, Records, RecordsMut, Resizable},
+ settings::TableOption,
+};
+
+use super::Panel;
+
+/// Header inserts a [`Panel`] at the top.
+/// See [`Panel`].
+#[derive(Debug)]
+pub struct Header<S>(S);
+
+impl<S> Header<S> {
+ /// Creates a new object.
+ pub fn new(text: S) -> Self
+ where
+ S: AsRef<str>,
+ {
+ Self(text)
+ }
+}
+
+impl<S, R, D> TableOption<R, D, ColoredConfig> for Header<S>
+where
+ S: AsRef<str>,
+ R: Records + ExactRecords + Resizable + RecordsMut<String>,
+{
+ fn change(self, records: &mut R, cfg: &mut ColoredConfig, dimension: &mut D) {
+ Panel::horizontal(0, self.0.as_ref()).change(records, cfg, dimension);
+ }
+}
diff --git a/vendor/tabled/src/settings/panel/horizontal_panel.rs b/vendor/tabled/src/settings/panel/horizontal_panel.rs
new file mode 100644
index 000000000..d5871d720
--- /dev/null
+++ b/vendor/tabled/src/settings/panel/horizontal_panel.rs
@@ -0,0 +1,80 @@
+use crate::{
+ grid::config::{ColoredConfig, SpannedConfig},
+ grid::records::{ExactRecords, Records, RecordsMut, Resizable},
+ settings::TableOption,
+};
+
+/// A horizontal/column span from 0 to a count rows.
+#[derive(Debug)]
+pub struct HorizontalPanel<S> {
+ text: S,
+ row: usize,
+}
+
+impl<S> HorizontalPanel<S> {
+ /// Creates a new horizontal panel.
+ pub fn new(row: usize, text: S) -> Self {
+ Self { row, text }
+ }
+}
+
+impl<S, R, D> TableOption<R, D, ColoredConfig> for HorizontalPanel<S>
+where
+ S: AsRef<str>,
+ R: Records + ExactRecords + Resizable + RecordsMut<String>,
+{
+ fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+ let count_rows = records.count_rows();
+ let count_cols = records.count_columns();
+
+ if self.row > count_rows {
+ return;
+ }
+
+ let is_intersect_vertical_span = (0..records.count_columns())
+ .any(|col| cfg.is_cell_covered_by_row_span((self.row, col)));
+ if is_intersect_vertical_span {
+ return;
+ }
+
+ move_rows_aside(records, self.row);
+ move_row_spans(cfg, self.row);
+
+ let text = self.text.as_ref().to_owned();
+ records.set((self.row, 0), text);
+
+ cfg.set_column_span((self.row, 0), count_cols);
+ }
+}
+
+fn move_rows_aside<R: ExactRecords + Resizable>(records: &mut R, row: usize) {
+ records.push_row();
+
+ let count_rows = records.count_rows();
+
+ let shift_count = count_rows - row;
+ for i in 1..shift_count {
+ let row = count_rows - i;
+ records.swap_row(row, row - 1);
+ }
+}
+
+fn move_row_spans(cfg: &mut SpannedConfig, target_row: usize) {
+ for ((row, col), span) in cfg.get_column_spans() {
+ if row < target_row {
+ continue;
+ }
+
+ cfg.set_column_span((row, col), 1);
+ cfg.set_column_span((row + 1, col), span);
+ }
+
+ for ((row, col), span) in cfg.get_row_spans() {
+ if row < target_row {
+ continue;
+ }
+
+ cfg.set_row_span((row, col), 1);
+ cfg.set_row_span((row + 1, col), span);
+ }
+}
diff --git a/vendor/tabled/src/settings/panel/mod.rs b/vendor/tabled/src/settings/panel/mod.rs
new file mode 100644
index 000000000..e4e819b6c
--- /dev/null
+++ b/vendor/tabled/src/settings/panel/mod.rs
@@ -0,0 +1,127 @@
+//! This module contains primitives to create a spread row.
+//! Ultimately it is a cell with a span set to a number of columns on the [`Table`].
+//!
+//! You can use a [`Span`] to set a custom span.
+//!
+//! # Example
+//!
+//! ```
+//! use tabled::{Table, settings::Panel};
+//!
+//! let data = [[1, 2, 3], [4, 5, 6]];
+//!
+//! let table = Table::new(data)
+//! .with(Panel::vertical(1, "S\np\nl\ni\nt"))
+//! .with(Panel::header("Numbers"))
+//! .to_string();
+//!
+//! println!("{}", table);
+//!
+//! assert_eq!(
+//! table,
+//! concat!(
+//! "+---+---+---+---+\n",
+//! "| Numbers |\n",
+//! "+---+---+---+---+\n",
+//! "| 0 | S | 1 | 2 |\n",
+//! "+---+ p +---+---+\n",
+//! "| 1 | l | 2 | 3 |\n",
+//! "+---+ i +---+---+\n",
+//! "| 4 | t | 5 | 6 |\n",
+//! "+---+---+---+---+",
+//! )
+//! )
+//! ```
+//!
+//! [`Table`]: crate::Table
+//! [`Span`]: crate::settings::span::Span
+
+mod footer;
+mod header;
+mod horizontal_panel;
+mod vertical_panel;
+
+pub use footer::Footer;
+pub use header::Header;
+pub use horizontal_panel::HorizontalPanel;
+pub use vertical_panel::VerticalPanel;
+
+/// Panel allows to add a Row which has 1 continues Cell to a [`Table`].
+///
+/// See `examples/panel.rs`.
+///
+/// [`Table`]: crate::Table
+#[derive(Debug)]
+pub struct Panel;
+
+impl Panel {
+ /// Creates an empty vertical row at given index.
+ ///
+ /// ```
+ /// use tabled::{settings::Panel, Table};
+ ///
+ /// let data = [[1, 2, 3], [4, 5, 6]];
+ ///
+ /// let table = Table::new(data)
+ /// .with(Panel::vertical(1, "Tabled Releases"))
+ /// .to_string();
+ ///
+ /// println!("{}", table);
+ ///
+ /// assert_eq!(
+ /// table,
+ /// concat!(
+ /// "+---+-----------------+---+---+\n",
+ /// "| 0 | Tabled Releases | 1 | 2 |\n",
+ /// "+---+ +---+---+\n",
+ /// "| 1 | | 2 | 3 |\n",
+ /// "+---+ +---+---+\n",
+ /// "| 4 | | 5 | 6 |\n",
+ /// "+---+-----------------+---+---+",
+ /// )
+ /// )
+ /// ```
+ pub fn vertical<S: AsRef<str>>(column: usize, text: S) -> VerticalPanel<S> {
+ VerticalPanel::new(column, text)
+ }
+
+ /// Creates an empty horizontal row at given index.
+ ///
+ /// ```
+ /// use tabled::{Table, settings::Panel};
+ ///
+ /// let data = [[1, 2, 3], [4, 5, 6]];
+ ///
+ /// let table = Table::new(data)
+ /// .with(Panel::vertical(1, ""))
+ /// .to_string();
+ ///
+ /// println!("{}", table);
+ ///
+ /// assert_eq!(
+ /// table,
+ /// concat!(
+ /// "+---+--+---+---+\n",
+ /// "| 0 | | 1 | 2 |\n",
+ /// "+---+ +---+---+\n",
+ /// "| 1 | | 2 | 3 |\n",
+ /// "+---+ +---+---+\n",
+ /// "| 4 | | 5 | 6 |\n",
+ /// "+---+--+---+---+",
+ /// )
+ /// )
+ /// ```
+ pub fn horizontal<S: AsRef<str>>(row: usize, text: S) -> HorizontalPanel<S> {
+ HorizontalPanel::new(row, text)
+ }
+
+ /// Creates an horizontal row at first row.
+ pub fn header<S: AsRef<str>>(text: S) -> Header<S> {
+ Header::new(text)
+ }
+
+ /// Creates an horizontal row at last row.
+ pub fn footer<S: AsRef<str>>(text: S) -> Footer<S> {
+ Footer::new(text)
+ }
+}
diff --git a/vendor/tabled/src/settings/panel/vertical_panel.rs b/vendor/tabled/src/settings/panel/vertical_panel.rs
new file mode 100644
index 000000000..ddc0a562b
--- /dev/null
+++ b/vendor/tabled/src/settings/panel/vertical_panel.rs
@@ -0,0 +1,83 @@
+use crate::{
+ grid::config::{ColoredConfig, SpannedConfig},
+ grid::records::{ExactRecords, Records, RecordsMut, Resizable},
+ settings::TableOption,
+};
+
+/// A vertical/row span from 0 to a count columns.
+#[derive(Debug)]
+pub struct VerticalPanel<S> {
+ text: S,
+ col: usize,
+}
+
+impl<S> VerticalPanel<S> {
+ /// Creates a new vertical panel.
+ pub fn new(col: usize, text: S) -> Self
+ where
+ S: AsRef<str>,
+ {
+ Self { text, col }
+ }
+}
+
+impl<S, R, D> TableOption<R, D, ColoredConfig> for VerticalPanel<S>
+where
+ S: AsRef<str>,
+ R: Records + ExactRecords + Resizable + RecordsMut<String>,
+{
+ fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+ let count_rows = records.count_rows();
+ let count_cols = records.count_columns();
+
+ if self.col > count_cols {
+ return;
+ }
+
+ let is_intersect_horizontal_span = (0..=records.count_rows())
+ .any(|row| cfg.is_cell_covered_by_column_span((row, self.col)));
+
+ if is_intersect_horizontal_span {
+ return;
+ }
+
+ move_columns_aside(records, self.col);
+ move_column_spans(cfg, self.col);
+
+ let text = self.text.as_ref().to_owned();
+ records.set((0, self.col), text);
+
+ cfg.set_row_span((0, self.col), count_rows);
+ }
+}
+
+fn move_columns_aside<R: Records + Resizable>(records: &mut R, column: usize) {
+ records.push_column();
+
+ let count_columns = records.count_columns();
+ let shift_count = count_columns - column;
+ for i in 1..shift_count {
+ let col = count_columns - i;
+ records.swap_column(col, col - 1);
+ }
+}
+
+fn move_column_spans(cfg: &mut SpannedConfig, target_column: usize) {
+ for ((row, col), span) in cfg.get_column_spans() {
+ if col < target_column {
+ continue;
+ }
+
+ cfg.set_column_span((row, col), 1);
+ cfg.set_column_span((row, col + 1), span);
+ }
+
+ for ((row, col), span) in cfg.get_row_spans() {
+ if col < target_column {
+ continue;
+ }
+
+ cfg.set_row_span((row, col), 1);
+ cfg.set_row_span((row, col + 1), span);
+ }
+}