summaryrefslogtreecommitdiffstats
path: root/vendor/tabled/src/settings/measurement
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/tabled/src/settings/measurement')
-rw-r--r--vendor/tabled/src/settings/measurement/mod.rs161
1 files changed, 161 insertions, 0 deletions
diff --git a/vendor/tabled/src/settings/measurement/mod.rs b/vendor/tabled/src/settings/measurement/mod.rs
new file mode 100644
index 000000000..f93cc6b4e
--- /dev/null
+++ b/vendor/tabled/src/settings/measurement/mod.rs
@@ -0,0 +1,161 @@
+//! The module contains [`Measurement`] trait and its implementations to be used in [`Height`] and [`Width`].;
+
+use crate::{
+ grid::config::SpannedConfig,
+ grid::dimension::SpannedGridDimension,
+ grid::records::{ExactRecords, PeekableRecords, Records},
+ grid::util::string::{self, string_width_multiline},
+ settings::{Height, Width},
+};
+
+/// A width value which can be obtained on behalf of [`Table`].
+///
+/// [`Table`]: crate::Table
+pub trait Measurement<Attribute> {
+ /// Returns a measurement value.
+ fn measure<R: Records + ExactRecords + PeekableRecords>(
+ &self,
+ records: R,
+ cfg: &SpannedConfig,
+ ) -> usize;
+}
+
+impl<T> Measurement<T> for usize {
+ fn measure<R>(&self, _: R, _: &SpannedConfig) -> usize {
+ *self
+ }
+}
+
+/// Max width value.
+#[derive(Debug)]
+pub struct Max;
+
+impl Measurement<Width> for Max {
+ fn measure<R: Records + ExactRecords + PeekableRecords>(
+ &self,
+ records: R,
+ _: &SpannedConfig,
+ ) -> usize {
+ grid_widths(&records)
+ .map(|r| r.max().unwrap_or(0))
+ .max()
+ .unwrap_or(0)
+ }
+}
+
+impl Measurement<Height> for Max {
+ fn measure<R: Records + ExactRecords + PeekableRecords>(
+ &self,
+ records: R,
+ _: &SpannedConfig,
+ ) -> usize {
+ records_heights(&records)
+ .map(|r| r.max().unwrap_or(0))
+ .max()
+ .unwrap_or(0)
+ }
+}
+
+/// Min width value.
+#[derive(Debug)]
+pub struct Min;
+
+impl Measurement<Width> for Min {
+ fn measure<R: Records + ExactRecords + PeekableRecords>(
+ &self,
+ records: R,
+ _: &SpannedConfig,
+ ) -> usize {
+ grid_widths(&records)
+ .map(|r| r.min().unwrap_or(0))
+ .max()
+ .unwrap_or(0)
+ }
+}
+
+impl Measurement<Height> for Min {
+ fn measure<R: Records + ExactRecords + PeekableRecords>(
+ &self,
+ records: R,
+ _: &SpannedConfig,
+ ) -> usize {
+ records_heights(&records)
+ .map(|r| r.max().unwrap_or(0))
+ .min()
+ .unwrap_or(0)
+ }
+}
+
+/// Percent from a total table width.
+#[derive(Debug)]
+pub struct Percent(pub usize);
+
+impl Measurement<Width> for Percent {
+ fn measure<R>(&self, records: R, cfg: &SpannedConfig) -> usize
+ where
+ R: Records,
+ {
+ let (_, total) = get_table_widths_with_total(records, cfg);
+ (total * self.0) / 100
+ }
+}
+
+impl Measurement<Height> for Percent {
+ fn measure<R>(&self, records: R, cfg: &SpannedConfig) -> usize
+ where
+ R: Records + ExactRecords,
+ {
+ let (_, total) = get_table_heights_width_total(records, cfg);
+ (total * self.0) / 100
+ }
+}
+
+fn grid_widths<R: Records + ExactRecords + PeekableRecords>(
+ records: &R,
+) -> impl Iterator<Item = impl Iterator<Item = usize> + '_> + '_ {
+ let (count_rows, count_cols) = (records.count_rows(), records.count_columns());
+ (0..count_rows).map(move |row| {
+ (0..count_cols).map(move |col| string_width_multiline(records.get_text((row, col))))
+ })
+}
+
+fn get_table_widths_with_total<R>(records: R, cfg: &SpannedConfig) -> (Vec<usize>, usize)
+where
+ R: Records,
+{
+ let widths = SpannedGridDimension::width(records, cfg);
+ let total_width = get_table_total_width(&widths, cfg);
+ (widths, total_width)
+}
+
+fn get_table_total_width(list: &[usize], cfg: &SpannedConfig) -> usize {
+ let total = list.iter().sum::<usize>();
+
+ total + cfg.count_vertical(list.len())
+}
+
+fn records_heights<R>(records: &R) -> impl Iterator<Item = impl Iterator<Item = usize> + '_> + '_
+where
+ R: Records + ExactRecords + PeekableRecords,
+{
+ (0..records.count_rows()).map(move |row| {
+ (0..records.count_columns())
+ .map(move |col| string::count_lines(records.get_text((row, col))))
+ })
+}
+
+fn get_table_heights_width_total<R>(records: R, cfg: &SpannedConfig) -> (Vec<usize>, usize)
+where
+ R: Records,
+{
+ let list = SpannedGridDimension::height(records, cfg);
+ let total = get_table_total_height(&list, cfg);
+ (list, total)
+}
+
+fn get_table_total_height(list: &[usize], cfg: &SpannedConfig) -> usize {
+ let total = list.iter().sum::<usize>();
+ let counth = cfg.count_horizontal(list.len());
+
+ total + counth
+}