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