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
use core::iter;
enum OnceOrMore<T, I> {
    Once(iter::Once<T>),
    More(I),
}
impl<T, I> Iterator for OnceOrMore<T, I>
where
    I: Iterator<Item = T>,
{
    type Item = T;
    fn next(&mut self) -> Option<T> {
        use OnceOrMore::*;
        match self {
            Once(v) => v.next(),
            More(i) => i.next(),
        }
    }
}
type StaticSliceIterCloned = core::iter::Cloned<core::slice::Iter<'static, char>>;
fn char_prototype(c: char) -> OnceOrMore<char, StaticSliceIterCloned> {
    use crate::tables::confusable_detection::char_confusable_prototype;
    match char_confusable_prototype(c) {
        None => OnceOrMore::Once(iter::once(c)),
        Some(l) => OnceOrMore::More(l.iter().cloned()),
    }
}
pub fn skeleton(s: &str) -> impl Iterator<Item = char> + '_ {
    use unicode_normalization::UnicodeNormalization;
    s.chars().nfd().flat_map(char_prototype).nfd()
}