• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download

find_words_ascii_space(line: &str) -> impl Iterator<Item = &'_ str> + '_1 pub(crate) fn find_words_ascii_space(line: &str) -> impl Iterator<Item = &'_ str> + '_ {
2     let mut start = 0;
3     let mut in_whitespace = false;
4     let mut char_indices = line.char_indices();
5 
6     std::iter::from_fn(move || {
7         for (idx, ch) in char_indices.by_ref() {
8             if in_whitespace && ch != ' ' {
9                 let word = &line[start..idx];
10                 start = idx;
11                 in_whitespace = ch == ' ';
12                 return Some(word);
13             }
14 
15             in_whitespace = ch == ' ';
16         }
17 
18         if start < line.len() {
19             let word = &line[start..];
20             start = line.len();
21             return Some(word);
22         }
23 
24         None
25     })
26 }
27 
28 #[cfg(test)]
29 mod tests {
30     use super::*;
31 
32     macro_rules! test_find_words {
33         ($ascii_name:ident,
34          $([ $line:expr, $ascii_words:expr ]),+) => {
35             #[test]
36             fn $ascii_name() {
37                 $(
38                     let expected_words: Vec<&str> = $ascii_words.to_vec();
39                     let actual_words = find_words_ascii_space($line)
40                         .collect::<Vec<_>>();
41                     assert_eq!(actual_words, expected_words, "Line: {:?}", $line);
42                 )+
43             }
44         };
45     }
46 
47     test_find_words!(ascii_space_empty, ["", []]);
48 
49     test_find_words!(ascii_single_word, ["foo", ["foo"]]);
50 
51     test_find_words!(ascii_two_words, ["foo bar", ["foo ", "bar"]]);
52 
53     test_find_words!(
54         ascii_multiple_words,
55         ["foo bar", ["foo ", "bar"]],
56         ["x y z", ["x ", "y ", "z"]]
57     );
58 
59     test_find_words!(ascii_only_whitespace, [" ", [" "]], ["    ", ["    "]]);
60 
61     test_find_words!(
62         ascii_inter_word_whitespace,
63         ["foo   bar", ["foo   ", "bar"]]
64     );
65 
66     test_find_words!(ascii_trailing_whitespace, ["foo   ", ["foo   "]]);
67 
68     test_find_words!(ascii_leading_whitespace, ["   foo", ["   ", "foo"]]);
69 
70     test_find_words!(
71         ascii_multi_column_char,
72         ["\u{1f920}", ["\u{1f920}"]] // cowboy emoji ��
73     );
74 
75     test_find_words!(
76         ascii_hyphens,
77         ["foo-bar", ["foo-bar"]],
78         ["foo- bar", ["foo- ", "bar"]],
79         ["foo - bar", ["foo ", "- ", "bar"]],
80         ["foo -bar", ["foo ", "-bar"]]
81     );
82 
83     test_find_words!(ascii_newline, ["foo\nbar", ["foo\nbar"]]);
84 
85     test_find_words!(ascii_tab, ["foo\tbar", ["foo\tbar"]]);
86 
87     test_find_words!(
88         ascii_non_breaking_space,
89         ["foo\u{00A0}bar", ["foo\u{00A0}bar"]]
90     );
91 }
92