1use crate::{
2 grid::records::{ExactRecords, PeekableRecords, Records, RecordsMut},
3 settings::TableOption,
4};
5
6/// Set a tab size.
7///
8/// The size is used in order to calculate width correctly.
9///
10/// Default value is 4 (basically 1 '\t' equals 4 spaces).
11///
12/// IMPORTANT: The tab character might be not present in output,
13/// it might be replaced by spaces.
14///
15/// # Example
16///
17/// ```
18/// use tabled::{Table, settings::formatting::TabSize};
19///
20/// let text = "Some\ttext\t\twith \\tabs";
21///
22/// let mut table = Table::new([text]);
23/// table.with(TabSize::new(4));
24///
25/// assert_eq!(
26/// table.to_string(),
27/// "+--------------------------------+\n\
28/// | &str |\n\
29/// +--------------------------------+\n\
30/// | Some text with \\tabs |\n\
31/// +--------------------------------+"
32/// )
33/// ```
34#[derive(Debug, Default, Clone)]
35pub struct TabSize(usize);
36
37impl TabSize {
38 /// Creates new [`TabSize`] object.
39 pub fn new(size: usize) -> Self {
40 Self(size)
41 }
42}
43
44impl<R, D, C> TableOption<R, C, D> for TabSize
45where
46 R: Records + ExactRecords + RecordsMut<String> + PeekableRecords,
47{
48 fn change(self, records: &mut R, _: &mut C, _: &mut D) {
49 let tab_size: usize = self.0;
50
51 for row: usize in 0..records.count_rows() {
52 for col: usize in 0..records.count_columns() {
53 let pos: (usize, usize) = (row, col);
54 let text: &str = records.get_text(pos);
55 let text: String = text.replace(from:'\t', &" ".repeat(tab_size));
56 records.set(pos, text);
57 }
58 }
59 }
60}
61