codump/process/
summarize_lines.rs

1//! Logic and tests for converting body lines to summary view
2
3/// Convert lines to summary view
4///
5/// Consecutive lines or starts with a space or a tab will be replaced with `...` with the
6/// specified indent. Empty lines inside indented region will be ignored while empty lines
7/// outside of indented region will be preserved.
8///
9/// If exclude range is set, the lines in that range will be untouched.
10///
11/// If indent is 0, this returns the vector as is
12///
13/// The exclude range has inclusive start and exclusive end.
14pub fn summarize_lines(
15    lines: &[String],
16    indent: usize,
17    exclude: Option<(usize, usize)>,
18) -> Vec<String> {
19    let mut output = vec![];
20    let mut is_in_indent = false;
21    for (i, line) in lines.iter().enumerate() {
22        if line.is_empty() && is_in_indent {
23            continue;
24        }
25        let should_ellipsize = line.starts_with(super::is_indent_char)
26            && match exclude {
27                Some((start, end)) => i < start || i >= end,
28                None => true,
29            };
30        if should_ellipsize {
31            if !is_in_indent {
32                output.push(super::indent_string("...", indent));
33                is_in_indent = true;
34            }
35        } else {
36            output.push(line.clone());
37            is_in_indent = false;
38        }
39    }
40
41    output
42}
43
44/// Tests for summarize_lines
45#[cfg(test)]
46mod ut {
47    use super::*;
48
49    #[test]
50    fn test_empty() {
51        let expected: Vec<String> = vec![];
52        assert_eq!(summarize_lines(&[], 0, None), expected);
53    }
54
55    #[test]
56    fn test_no_indent() {
57        let input = vec!["abc".to_string(), "bcd".to_string(), "cde".to_string()];
58        assert_eq!(summarize_lines(&input, 0, None), input);
59    }
60
61    #[test]
62    fn test_indent_single_begin() {
63        let input = vec![" abc".to_string(), "bcd".to_string(), "cde".to_string()];
64        let expected = vec!["    ...".to_string(), "bcd".to_string(), "cde".to_string()];
65        assert_eq!(summarize_lines(&input, 4, None), expected);
66    }
67
68    #[test]
69    fn test_indent_single_middle() {
70        let input = vec!["bcd".to_string(), " abc".to_string(), "cde".to_string()];
71        let expected = vec!["bcd".to_string(), "    ...".to_string(), "cde".to_string()];
72        assert_eq!(summarize_lines(&input, 4, None), expected);
73    }
74
75    #[test]
76    fn test_indent_single_end() {
77        let input = vec!["bcd".to_string(), "cde".to_string(), " abc".to_string()];
78        let expected = vec!["bcd".to_string(), "cde".to_string(), "    ...".to_string()];
79        assert_eq!(summarize_lines(&input, 4, None), expected);
80    }
81
82    #[test]
83    fn test_indent_multi_begin() {
84        let input = vec![
85            " abc".to_string(),
86            "  abc".to_string(),
87            "bcd".to_string(),
88            "cde".to_string(),
89        ];
90        let expected = vec!["    ...".to_string(), "bcd".to_string(), "cde".to_string()];
91        assert_eq!(summarize_lines(&input, 4, None), expected);
92    }
93
94    #[test]
95    fn test_indent_multi_middle() {
96        let input = vec![
97            "bcd".to_string(),
98            " abc".to_string(),
99            "  abc".to_string(),
100            "cde".to_string(),
101        ];
102        let expected = vec!["bcd".to_string(), "    ...".to_string(), "cde".to_string()];
103        assert_eq!(summarize_lines(&input, 4, None), expected);
104    }
105
106    #[test]
107    fn test_indent_multi_end() {
108        let input = vec![
109            "bcd".to_string(),
110            "cde".to_string(),
111            " abc".to_string(),
112            "  abc".to_string(),
113        ];
114        let expected = vec!["bcd".to_string(), "cde".to_string(), "    ...".to_string()];
115        assert_eq!(summarize_lines(&input, 4, None), expected);
116    }
117
118    #[test]
119    fn test_indent_multi_many1() {
120        let input = vec![
121            " abc".to_string(),
122            "  abc".to_string(),
123            "bcd".to_string(),
124            "        abc".to_string(),
125            "cde".to_string(),
126            " abc".to_string(),
127            "  abc".to_string(),
128        ];
129        let expected = vec![
130            "    ...".to_string(),
131            "bcd".to_string(),
132            "    ...".to_string(),
133            "cde".to_string(),
134            "    ...".to_string(),
135        ];
136        assert_eq!(summarize_lines(&input, 4, None), expected);
137    }
138
139    #[test]
140    fn test_indent_multi_many2() {
141        let input = vec![
142            "bcd".to_string(),
143            " abc".to_string(),
144            "  abc".to_string(),
145            "cde".to_string(),
146            "     abc".to_string(),
147        ];
148        let expected = vec![
149            "bcd".to_string(),
150            "    ...".to_string(),
151            "cde".to_string(),
152            "    ...".to_string(),
153        ];
154        assert_eq!(summarize_lines(&input, 4, None), expected);
155    }
156
157    #[test]
158    fn test_indent_multi_many3() {
159        let input = vec![
160            "  abc".to_string(),
161            "bcd".to_string(),
162            " abc".to_string(),
163            " abc".to_string(),
164            "cde".to_string(),
165        ];
166        let expected = vec![
167            "    ...".to_string(),
168            "bcd".to_string(),
169            "    ...".to_string(),
170            "cde".to_string(),
171        ];
172        assert_eq!(summarize_lines(&input, 4, None), expected);
173    }
174
175    #[test]
176    fn test_exclude_unindent_to_indent() {
177        let input = vec![
178            "abc".to_string(),
179            "bcd".to_string(),
180            " abc".to_string(),
181            " abc".to_string(),
182            " abc".to_string(),
183            "cde".to_string(),
184        ];
185        let expected = vec![
186            "abc".to_string(),
187            "bcd".to_string(),
188            " abc".to_string(),
189            " abc".to_string(),
190            "  ...".to_string(),
191            "cde".to_string(),
192        ];
193        assert_eq!(summarize_lines(&input, 2, Some((2, 4))), expected);
194    }
195
196    #[test]
197    fn test_exclude_indent_to_indent() {
198        let input = vec![
199            "abc".to_string(),
200            "bcd".to_string(),
201            " abc".to_string(),
202            " abc".to_string(),
203            " abc".to_string(),
204            " abc".to_string(),
205            "cde".to_string(),
206        ];
207        let expected = vec![
208            "abc".to_string(),
209            "bcd".to_string(),
210            "  ...".to_string(),
211            " abc".to_string(),
212            " abc".to_string(),
213            "  ...".to_string(),
214            "cde".to_string(),
215        ];
216        assert_eq!(summarize_lines(&input, 2, Some((3, 5))), expected);
217    }
218
219    #[test]
220    fn test_exclude_indent_to_unindent() {
221        let input = vec![
222            "abc".to_string(),
223            "bcd".to_string(),
224            " abc".to_string(),
225            " abc".to_string(),
226            " abc".to_string(),
227            " abc".to_string(),
228            " abc".to_string(),
229            "cde".to_string(),
230        ];
231        let expected = vec![
232            "abc".to_string(),
233            "bcd".to_string(),
234            "  ...".to_string(),
235            " abc".to_string(),
236            " abc".to_string(),
237            " abc".to_string(),
238            "cde".to_string(),
239        ];
240        assert_eq!(summarize_lines(&input, 2, Some((4, 7))), expected);
241    }
242
243    #[test]
244    fn test_exclude_unindent_to_unindent() {
245        let input = vec![
246            " abc".to_string(),
247            "bcd".to_string(),
248            "bcd".to_string(),
249            " cde".to_string(),
250        ];
251        let expected = vec![
252            "  ...".to_string(),
253            "bcd".to_string(),
254            "bcd".to_string(),
255            "  ...".to_string(),
256        ];
257        assert_eq!(summarize_lines(&input, 2, Some((1, 2))), expected);
258    }
259
260    #[test]
261    fn test_empty_line() {
262        let input = vec![
263            " abc".to_string(),
264            "".to_string(),
265            "bcd".to_string(),
266            " cde".to_string(),
267        ];
268        let expected = vec!["  ...".to_string(), "bcd".to_string(), "  ...".to_string()];
269        assert_eq!(summarize_lines(&input, 2, None), expected);
270    }
271
272    #[test]
273    fn test_empty_line_noindent() {
274        let input = vec![
275            "abc".to_string(),
276            "".to_string(),
277            "bcd".to_string(),
278            " cde".to_string(),
279        ];
280        let expected = vec![
281            "abc".to_string(),
282            "".to_string(),
283            "bcd".to_string(),
284            "  ...".to_string(),
285        ];
286        assert_eq!(summarize_lines(&input, 2, None), expected);
287    }
288}