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