paris/formatter/keys/
key_list.rs1use super::Key;
2
3pub struct KeyList<'a> {
4 input: &'a str,
5}
6
7impl<'a> KeyList<'a> {
8 pub fn new(input: &'a str) -> Self {
9 Self { input }
10 }
11
12 fn fetch_next_key(&mut self) -> Option<(Key<'a>, bool)> {
13 let mut key = None;
14
15 if let Some(i) = self.input.find('<') {
16 self.input = &self.input[i..];
17
18 let mut omit = false;
19
20 let rest = self
21 .input
22 .char_indices()
23 .take_while(|(idx, c)| {
24 if *idx == 0 && *c == '<' {
25 return true;
26 }
27
28 if *c == '<' {
29 omit = true;
30 return false;
31 }
32
33 *c != '>'
34 })
35 .last()
36 .map(|(idx, c)| idx + c.len_utf8())
37 .unwrap_or_default();
38
39 let adder = if omit || self.input[..rest].len() == self.input.len() {
42 0
44 } else {
45 1
46 };
47
48 key = Some((Key::new(&self.input[..(rest + adder)]), omit));
49 self.input = &self.input[(rest + adder)..];
50 }
51
52 key
53 }
54}
55
56impl<'a> Iterator for KeyList<'a> {
57 type Item = Key<'a>;
58
59 fn next(&mut self) -> Option<Self::Item> {
60 loop {
61 let key = self.fetch_next_key();
62
63 if key.is_none() {
64 break;
65 }
66
67 let (key, omit) = key.unwrap();
68
69 if omit {
72 continue;
73 }
74
75 return Some(key);
76 }
77
78 None
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn find_keys() {
88 let input = "<black> <red> one two <three>";
89 let key_count = KeyList::new(&input).count();
90
91 assert_eq!(key_count, 3);
92 }
93
94 #[test]
95 fn ignore_fake_keys() {
96 let input = "<black><-------------------- some text <some random opening here, <and another here </>";
97 let key_count = KeyList::new(&input).count();
98
99 assert_eq!(key_count, 2);
100 }
101
102 #[test]
103 fn mess_around() {
104 let input = "<< powering on 'TV' (0)";
105 let _keys = KeyList::new(&input).count();
106
107 let input = "<< something that doesn't end after weird patterns < alksdfa < ngi2oueng <<ikdoqlksmads <black></>";
108 let keys = KeyList::new(&input).count();
109
110 assert_eq!(keys, 2);
111 }
112}