1#![warn(missing_docs)]
5
6
7pub struct KeyList<'a> {
9 input: &'a str,
10 start: char,
11 end: char
12}
13
14
15impl<'a> KeyList<'a> {
16 pub fn new(input: &'a str, start: char, end: char) -> Self {
25 Self {
26 input,
27 start,
28 end
29 }
30 }
31}
32
33
34impl<'a> Iterator for KeyList<'a> {
35 type Item = &'a str;
36
37 fn next(&mut self) -> Option<Self::Item> {
38 let mut key = None;
39
40 if let Some(i) = self.input.find(self.start) {
41 self.input = &self.input[i..];
42 let mut first = true;
43
44 let rest = self.input.char_indices()
45 .take_while(|(_, c)| {
46 if first {
47 first = false;
48 return true;
49 }
50
51 *c != self.end
52 })
53 .last()
54 .map(|(idx, c)| idx + c.len_utf8())
55 .unwrap_or_default();
56
57 key = Some(&self.input[..(rest + 1)]);
59 self.input = &self.input[(rest + 1)..];
60 }
61
62 key
63 }
64}
65
66
67
68
69
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn find_keys() {
77 let input = "<black> <red> one two <three>";
78 let key_count = KeyList::new(input, '<', '>').count();
79
80 assert_eq!(key_count, 3);
81 }
82
83 #[test]
84 fn different_start() {
85 let input = "<A/ <B> one two <C/";
86 let key_count = KeyList::new(input, '<', '/').count();
87
88 assert_eq!(key_count, 2);
89 }
90
91 #[test]
92 fn different_character() {
93 let input = "/A/ /B/ one two /C/";
94 let key_count = KeyList::new(input, '/', '/').count();
95
96 assert_eq!(key_count, 3);
97 }
98}