buup/transformers/
line_sorter.rs

1use crate::{Transform, TransformError, TransformerCategory};
2
3/// Sorts lines of text alphabetically.
4#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
5pub struct LineSorter;
6
7impl Transform for LineSorter {
8    fn name(&self) -> &'static str {
9        "Line Sorter"
10    }
11
12    fn id(&self) -> &'static str {
13        "linesorter"
14    }
15
16    fn description(&self) -> &'static str {
17        "Sorts lines alphabetically."
18    }
19
20    fn category(&self) -> TransformerCategory {
21        TransformerCategory::Other // Could also be Formatter
22    }
23
24    fn default_test_input(&self) -> &'static str {
25        "banana\napple\norange\ngrape"
26    }
27
28    fn transform(&self, input: &str) -> Result<String, TransformError> {
29        if input.is_empty() {
30            return Ok(String::new());
31        }
32
33        let mut lines: Vec<&str> = input.lines().collect();
34
35        // Perform standard lexicographical sort
36        lines.sort_unstable();
37
38        Ok(lines.join("\n"))
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn test_line_sorter_empty() {
48        let transformer = LineSorter;
49        assert_eq!(transformer.transform("").unwrap(), "");
50    }
51
52    #[test]
53    fn test_line_sorter_single_line() {
54        let transformer = LineSorter;
55        assert_eq!(transformer.transform("hello").unwrap(), "hello");
56    }
57
58    #[test]
59    fn test_line_sorter_basic_sort() {
60        let transformer = LineSorter;
61        let input = transformer.default_test_input();
62        let expected = "apple\nbanana\ngrape\norange";
63        assert_eq!(transformer.transform(input).unwrap(), expected);
64
65        let input_abc = "c\nb\na";
66        let expected_abc = "a\nb\nc";
67        assert_eq!(transformer.transform(input_abc).unwrap(), expected_abc);
68    }
69
70    #[test]
71    fn test_line_sorter_with_duplicates() {
72        let transformer = LineSorter;
73        let input = "c\nb\na\nc\nb";
74        let expected = "a\nb\nb\nc\nc";
75        assert_eq!(transformer.transform(input).unwrap(), expected);
76    }
77
78    #[test]
79    fn test_line_sorter_trailing_newline() {
80        let transformer = LineSorter;
81        let input = "c\nb\na\n";
82        let expected = "a\nb\nc"; // Trailing newline is ignored by .lines(), preserved by join
83        assert_eq!(transformer.transform(input).unwrap(), expected);
84    }
85
86    #[test]
87    fn test_line_sorter_blank_lines() {
88        let transformer = LineSorter;
89        let input = "c\n\na\nb";
90        let expected = "\na\nb\nc"; // Blank lines are sorted too
91        assert_eq!(transformer.transform(input).unwrap(), expected);
92    }
93
94    #[test]
95    fn test_line_sorter_case_sensitivity() {
96        let transformer = LineSorter;
97        let input = "C\nb\nA";
98        let expected = "A\nC\nb"; // Uppercase comes before lowercase
99        assert_eq!(transformer.transform(input).unwrap(), expected);
100    }
101}