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