str_utils/
eq_ignore_ascii_case_multiple.rs

1/// To extend `[u8]` and `str` to have `eq_ignore_ascii_case_multiple`, `eq_ignore_ascii_case_with_lowercase_multiple` and `eq_ignore_ascii_case_with_uppercase_multiple` methods.
2pub trait EqIgnoreAsciiCaseMultiple {
3    /// Returns `Some(usize)` if one of the given string slices case-insensitively matches this string slice.
4    fn eq_ignore_ascii_case_multiple<S: AsRef<[u8]>>(&self, bs: &[S]) -> Option<usize>;
5
6    /// Returns `Some(usize)` if one of the given lowercase string slices case-insensitively matches this string slice.
7    fn eq_ignore_ascii_case_with_lowercase_multiple<S: AsRef<[u8]>>(
8        &self,
9        bs: &[S],
10    ) -> Option<usize>;
11
12    /// Returns `Some(usize)` if one of the given uppercase string slices case-insensitively matches this string slice.
13    fn eq_ignore_ascii_case_with_uppercase_multiple<S: AsRef<[u8]>>(
14        &self,
15        bs: &[S],
16    ) -> Option<usize>;
17}
18
19impl EqIgnoreAsciiCaseMultiple for [u8] {
20    #[inline]
21    fn eq_ignore_ascii_case_multiple<S: AsRef<[u8]>>(&self, bs: &[S]) -> Option<usize> {
22        let a = self;
23
24        bs.iter().position(|b| a.eq_ignore_ascii_case(b.as_ref()))
25    }
26
27    #[inline]
28    fn eq_ignore_ascii_case_with_lowercase_multiple<S: AsRef<[u8]>>(
29        &self,
30        bs: &[S],
31    ) -> Option<usize> {
32        let a = self;
33        let a_length = a.len();
34
35        for (i, b) in bs.iter().enumerate() {
36            let b = b.as_ref();
37
38            debug_assert!(!b.iter().any(|e| e.is_ascii_uppercase()));
39
40            if a_length != b.len() {
41                continue;
42            }
43
44            if !a
45                .iter()
46                .map(|e| e.to_ascii_lowercase())
47                .zip(b.iter().copied())
48                .any(|(ac, bc)| ac != bc)
49            {
50                return Some(i);
51            }
52        }
53
54        None
55    }
56
57    #[inline]
58    fn eq_ignore_ascii_case_with_uppercase_multiple<S: AsRef<[u8]>>(
59        &self,
60        bs: &[S],
61    ) -> Option<usize> {
62        let a = self;
63        let a_length = a.len();
64
65        for (i, b) in bs.iter().enumerate() {
66            let b = b.as_ref();
67
68            debug_assert!(!b.iter().any(|e| e.is_ascii_lowercase()));
69
70            if a_length != b.len() {
71                continue;
72            }
73
74            if !a
75                .iter()
76                .map(|e| e.to_ascii_uppercase())
77                .zip(b.iter().copied())
78                .any(|(ac, bc)| ac != bc)
79            {
80                return Some(i);
81            }
82        }
83
84        None
85    }
86}
87
88impl EqIgnoreAsciiCaseMultiple for str {
89    #[inline]
90    fn eq_ignore_ascii_case_multiple<S: AsRef<[u8]>>(&self, bs: &[S]) -> Option<usize> {
91        self.as_bytes().eq_ignore_ascii_case_multiple(bs)
92    }
93
94    #[inline]
95    fn eq_ignore_ascii_case_with_lowercase_multiple<S: AsRef<[u8]>>(
96        &self,
97        bs: &[S],
98    ) -> Option<usize> {
99        self.as_bytes().eq_ignore_ascii_case_with_lowercase_multiple(bs)
100    }
101
102    #[inline]
103    fn eq_ignore_ascii_case_with_uppercase_multiple<S: AsRef<[u8]>>(
104        &self,
105        bs: &[S],
106    ) -> Option<usize> {
107        self.as_bytes().eq_ignore_ascii_case_with_uppercase_multiple(bs)
108    }
109}