1use papergrid::{
2 config::Entity,
3 records::{ExactRecords, PeekableRecords},
4};
5
6use crate::{
7 grid::records::{Records, RecordsMut},
8 settings::{CellOption, TableOption},
9};
10
11/// A structure to handle special chars.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
13pub struct Charset;
14
15impl Charset {
16 /// Returns [`CleanCharset`] which removes all `\t` and `\r` occurences.
17 ///
18 /// Notice that tab is just removed rather then being replaced with spaces.
19 /// You might be better call [`TabSize`] first if you not expect such behavior.
20 ///
21 /// # Example
22 ///
23 /// ```
24 /// use tabled::{Table, settings::formatting::Charset};
25 ///
26 /// let text = "Some\ttext\t\twith \\tabs";
27 ///
28 /// let mut table = Table::new([text]);
29 /// table.with(Charset::clean());
30 ///
31 /// assert_eq!(
32 /// table.to_string(),
33 /// "+--------------------+\n\
34 /// | &str |\n\
35 /// +--------------------+\n\
36 /// | Sometextwith \\tabs |\n\
37 /// +--------------------+"
38 /// )
39 /// ```
40 ///
41 /// [`TabSize`]: crate::settings::formatting::TabSize
42 pub fn clean() -> CleanCharset {
43 CleanCharset
44 }
45}
46
47/// [`CleanCharset`] removes all `\t` and `\r` occurences.
48///
49/// # Example
50///
51/// ```
52/// use tabled::{Table, settings::formatting::Charset};
53///
54/// let text = "Some text which was created on windows \r\n yes they use this \\r\\n";
55///
56/// let mut builder = Table::builder([text]);
57/// builder.set_header(["win. text"]);
58///
59/// let mut table = builder.build();
60/// table.with(Charset::clean());
61///
62/// assert_eq!(
63/// table.to_string(),
64/// "+-----------------------------------------+\n\
65/// | win. text |\n\
66/// +-----------------------------------------+\n\
67/// | Some text which was created on windows |\n\
68/// | yes they use this \\r\\n |\n\
69/// +-----------------------------------------+"
70/// )
71/// ```
72#[derive(Debug, Default, Clone)]
73pub struct CleanCharset;
74
75impl<R, D, C> TableOption<R, D, C> for CleanCharset
76where
77 for<'a> &'a R: Records,
78 R: RecordsMut<String>,
79{
80 fn change(self, records: &mut R, _: &mut C, _: &mut D) {
81 let mut list: Vec<(({unknown}, {unknown}), …)> = vec![];
82 for (row, cells) in records.iter_rows().into_iter().enumerate() {
83 for (col, text) in cells.into_iter().enumerate() {
84 let text = text.as_ref().replace(['\t', '\r'], "");
85 list.push(((row, col), text));
86 }
87 }
88
89 for (pos: (usize, usize), text: String) in list {
90 records.set(pos, text);
91 }
92 }
93}
94
95impl<R, C> CellOption<R, C> for CleanCharset
96where
97 R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
98{
99 fn change(self, records: &mut R, _: &mut C, entity: Entity) {
100 let count_rows: usize = records.count_rows();
101 let count_cols: usize = records.count_columns();
102 for pos: (usize, usize) in entity.iter(count_rows, count_cols) {
103 let text: &str = records.get_text(pos);
104 let text: String = text.replace(['\t', '\r'], to:"");
105 records.set(pos, text);
106 }
107 }
108}
109