1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use crate::string_iterator::StringIterator;

pub trait StrExt {
    fn units(&self) -> StringIterator;
    fn records(&self) -> StringIterator;
    fn groups(&self) -> StringIterator;
    fn files(&self) -> StringIterator;
}

impl StrExt for str {

    fn units(&self) -> StringIterator {
        StringIterator {
            chars: self.chars(),
            c: '␟',
        }
    }

    fn records(&self) -> StringIterator {
        StringIterator {
            chars: self.chars(),
            c: '␞',
        }
    }

    fn groups(&self) -> StringIterator {
        StringIterator {
            chars: self.chars(),
            c: '␝',
        }
    }

    fn files(&self) -> StringIterator {
        StringIterator {
            chars: self.chars(),
            c: '␜',
        }
    }

}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn units() {
        let input = "a␟b␟";
        let actual: Vec<String> = input.units().collect();
        assert_eq!(
            actual,
            vec![
                String::from("a"),
                String::from("b"),
            ]
        );
    }

    #[test]
    fn records() {
        let input =  "a␟b␟␞c␟d␟␞";
        let actual: Vec<String> = input.records().collect();
        assert_eq!(
            actual,
            vec![
                String::from("a␟b␟"),
                String::from("c␟d␟"),
            ]
        );
    }

    #[test]
    fn groups() {
        let input = "a␟b␟␞c␟d␟␞␝e␟f␟␞g␟h␟␞␝";
        let actual: Vec<String> = input.groups().collect();
        assert_eq!(
            actual,
            vec![
                String::from("a␟b␟␞c␟d␟␞"),
                String::from("e␟f␟␞g␟h␟␞"),
            ]
        );
    }

    #[test]
    fn files() {
        let input = "a␟b␟␞c␟d␟␞␝e␟f␟␞g␟h␟␞␝␜i␟j␟␞k␟l␟␞␝m␟n␟␞o␟p␟␞␝␜";
        let actual: Vec<String> = input.files().collect();
        assert_eq!(
            actual,
            vec![
                String::from("a␟b␟␞c␟d␟␞␝e␟f␟␞g␟h␟␞␝"),
                String::from("i␟j␟␞k␟l␟␞␝m␟n␟␞o␟p␟␞␝"),
            ]
        );
    }
}