str_utils/
eq_ignore_ascii_case.rs

1/// To extend `[u8]` and `str` to have `eq_ignore_ascii_case_with_lowercase` and `eq_ignore_ascii_case_with_uppercase` methods.
2///
3/// These methods are slightly faster than `eq_ignore_ascii_case`.
4pub trait EqIgnoreAsciiCase {
5    /// Returns `true` if the given lowercase string slice case-insensitively (only ignoring ASCII case) matches this string slice.
6    fn eq_ignore_ascii_case_with_lowercase<S: AsRef<[u8]>>(&self, b: S) -> bool;
7    /// Returns `true` if the given uppercase string slice case-insensitively (only ignoring ASCII case) matches this string slice.
8    fn eq_ignore_ascii_case_with_uppercase<S: AsRef<[u8]>>(&self, b: S) -> bool;
9}
10
11impl EqIgnoreAsciiCase for [u8] {
12    #[inline]
13    fn eq_ignore_ascii_case_with_lowercase<S: AsRef<[u8]>>(&self, b: S) -> bool {
14        let b = b.as_ref();
15
16        debug_assert!(!b.iter().any(|e| e.is_ascii_uppercase()));
17
18        let a = self;
19
20        if a.len() != b.len() {
21            return false;
22        }
23
24        !a.iter().map(|e| e.to_ascii_lowercase()).zip(b.iter().copied()).any(|(ac, bc)| ac != bc)
25    }
26
27    #[inline]
28    fn eq_ignore_ascii_case_with_uppercase<S: AsRef<[u8]>>(&self, b: S) -> bool {
29        let b = b.as_ref();
30
31        debug_assert!(!b.iter().any(|e| e.is_ascii_lowercase()));
32
33        let a = self;
34
35        if a.len() != b.len() {
36            return false;
37        }
38
39        !a.iter().map(|e| e.to_ascii_uppercase()).zip(b.iter().copied()).any(|(ac, bc)| ac != bc)
40    }
41}
42
43impl EqIgnoreAsciiCase for str {
44    #[inline]
45    fn eq_ignore_ascii_case_with_lowercase<S: AsRef<[u8]>>(&self, b: S) -> bool {
46        self.as_bytes().eq_ignore_ascii_case_with_lowercase(b)
47    }
48
49    #[inline]
50    fn eq_ignore_ascii_case_with_uppercase<S: AsRef<[u8]>>(&self, b: S) -> bool {
51        self.as_bytes().eq_ignore_ascii_case_with_uppercase(b)
52    }
53}