taco_display_utils/
lib.rs1use std::fmt::Display;
5
6pub const TAB_SIZE: usize = 4;
8
9pub fn join_iterator<T: ToString + Sized, U: Iterator<Item = T>, S: Into<String>>(
24 list: U,
25 sep: S,
26) -> String {
27 list.map(|x| x.to_string())
28 .collect::<Vec<_>>()
29 .join(sep.into().as_str())
30}
31
32pub fn join_iterator_and_add_back<T: ToString + Sized, U: Iterator<Item = T>, S: Into<String>>(
52 list: U,
53 sep: S,
54) -> String {
55 let sep = sep.into();
56
57 let res = join_iterator(list, &sep);
58
59 if res.is_empty() {
60 return res;
61 }
62
63 res + &sep
64}
65
66pub fn display_iterator_stable_order<T: Display>(set: impl IntoIterator<Item = T>) -> String {
77 let mut sorted_set = set.into_iter().collect::<Vec<_>>();
78 sorted_set.sort_by_key(|a| a.to_string());
79 join_iterator(sorted_set.iter(), ", ")
80}
81
82pub fn indent_all<S>(input: S) -> String
93where
94 S: Into<String>,
95{
96 let tab = " ".repeat(TAB_SIZE);
97 let input: String = input.into();
98 let input_n_lines = input.lines().count();
99
100 let mut output = String::with_capacity(input.len() + input_n_lines * TAB_SIZE);
101
102 for (i, line) in input.lines().enumerate() {
103 if !line.is_empty() {
104 output.push_str(&tab);
105 }
106
107 output.push_str(line);
108
109 if i != input_n_lines - 1 {
110 output.push('\n');
111 }
112 }
113
114 if input.ends_with('\n') {
115 output.push('\n');
116 }
117
118 output
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[test]
126 fn test_join_iterator() {
127 let list = ["a", "b", "c"];
128 assert_eq!(join_iterator(list.iter(), ", "), "a, b, c");
129 }
130
131 #[test]
132 fn test_join_iterator_and_add_back() {
133 let list = ["a", "b", "c"];
134 assert_eq!(join_iterator_and_add_back(list.iter(), ", "), "a, b, c, ");
135
136 let list: Vec<&str> = vec![];
137 assert_eq!(join_iterator_and_add_back(list.iter(), ", "), "");
138 }
139
140 #[test]
141 fn test_display_iterator_stable_order() {
142 let list = ["c", "a", "b"];
143 assert_eq!(display_iterator_stable_order(list.iter()), "a, b, c");
144 }
145
146 #[test]
147 fn test_indent_all() {
148 let input = "a\nb\nc";
149 assert_eq!(indent_all(input), " a\n b\n c");
150
151 let input = "a\nb\nc\n";
152 assert_eq!(indent_all(input), " a\n b\n c\n");
153 }
154}