tabled/settings/width/
justify.rs

1//! This module contains [`Justify`] structure, used to set an exact width to each column.
2
3use crate::{
4    grid::{
5        config::{ColoredConfig, Entity},
6        records::{ExactRecords, IntoRecords, PeekableRecords, Records, RecordsMut},
7    },
8    settings::{
9        measurement::{Max, Measurement, Min},
10        CellOption, TableOption, Width,
11    },
12};
13
14/// Justify sets all columns widths to the set value.
15///
16/// Be aware that it doesn't consider padding.
17/// So if you want to set a exact width you might need to use [`Padding`] to set it to 0.
18///
19/// ## Examples
20///
21/// ```
22/// use tabled::{Table, settings::{Width, Style, object::Segment, Padding, Modify}};
23///
24/// let data = ["Hello", "World", "!"];
25///
26/// let table = Table::new(&data)
27///     .with(Style::markdown())
28///     .with(Modify::new(Segment::all()).with(Padding::zero()))
29///     .with(Width::justify(3));
30/// ```
31///
32/// [`Max`] usage to justify by a max column width.
33///
34/// ```
35/// use tabled::{Table, settings::{width::Justify, Style}};
36///
37/// let data = ["Hello", "World", "!"];
38///
39/// let table = Table::new(&data)
40///     .with(Style::markdown())
41///     .with(Justify::max());
42/// ```
43///
44/// [`Padding`]: crate::settings::Padding
45#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
46pub struct Justify<W> {
47    width: W,
48}
49
50impl<W> Justify<W>
51where
52    W: Measurement<Width>,
53{
54    /// Creates a new [`Justify`] instance.
55    ///
56    /// Be aware that [`Padding`] is not considered when comparing the width.
57    ///
58    /// [`Padding`]: crate::settings::Padding
59    pub fn new(width: W) -> Self {
60        Self { width }
61    }
62}
63
64impl Justify<Max> {
65    /// Creates a new Justify instance with a Max width used as a value.
66    pub fn max() -> Self {
67        Self { width: Max }
68    }
69}
70
71impl Justify<Min> {
72    /// Creates a new Justify instance with a Min width used as a value.
73    pub fn min() -> Self {
74        Self { width: Min }
75    }
76}
77
78impl<R, D, W> TableOption<R, ColoredConfig, D> for Justify<W>
79where
80    W: Measurement<Width>,
81    R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
82    for<'a> &'a R: Records,
83    for<'a> <<&'a R as Records>::Iter as IntoRecords>::Cell: AsRef<str>,
84{
85    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
86        let width = self.width.measure(&*records, cfg);
87
88        let count_rows = records.count_rows();
89        let count_columns = records.count_columns();
90
91        for row in 0..count_rows {
92            for col in 0..count_columns {
93                let pos = Entity::Cell(row, col);
94                CellOption::change(Width::increase(width), records, cfg, pos);
95                CellOption::change(Width::truncate(width), records, cfg, pos);
96            }
97        }
98    }
99}
100
101// TODO: explore whether it's actually usefull
102//       Maybe rework it?