str_utils/
ends_with_ignore_ascii_case.rs1pub trait EndsWithIgnoreAsciiCase {
3 fn ends_with_ignore_ascii_case<S: AsRef<[u8]>>(&self, b: S) -> bool;
5
6 fn ends_with_ignore_ascii_case_with_lowercase<S: AsRef<[u8]>>(&self, b: S) -> bool;
8
9 fn ends_with_ignore_ascii_case_with_uppercase<S: AsRef<[u8]>>(&self, b: S) -> bool;
11}
12
13impl<T: AsRef<[u8]>> EndsWithIgnoreAsciiCase for T {
14 #[inline]
15 fn ends_with_ignore_ascii_case<S: AsRef<[u8]>>(&self, b: S) -> bool {
16 let b = b.as_ref();
17
18 let b_length = b.len();
19
20 if b_length == 0 {
21 return true;
22 }
23
24 let a = self.as_ref();
25
26 let a_length = a.len();
27
28 if a_length >= b_length {
29 unsafe { a.get_unchecked((a_length - b_length)..) }.eq_ignore_ascii_case(b)
30 } else {
31 false
32 }
33 }
34
35 #[inline]
36 fn ends_with_ignore_ascii_case_with_lowercase<S: AsRef<[u8]>>(&self, b: S) -> bool {
37 let b = b.as_ref();
38
39 debug_assert!(!b.iter().any(|e| e.is_ascii_uppercase()));
40
41 let b_length = b.len();
42
43 if b_length == 0 {
44 return true;
45 }
46
47 let a = self.as_ref();
48
49 let a_length = a.len();
50
51 if a_length >= b_length {
52 !unsafe { a.get_unchecked((a_length - b_length)..) }
53 .iter()
54 .map(|e| e.to_ascii_lowercase())
55 .zip(b.iter().copied())
56 .any(|(ac, bc)| ac != bc)
57 } else {
58 false
59 }
60 }
61
62 #[inline]
63 fn ends_with_ignore_ascii_case_with_uppercase<S: AsRef<[u8]>>(&self, b: S) -> bool {
64 let b = b.as_ref();
65
66 debug_assert!(!b.iter().any(|e| e.is_ascii_lowercase()));
67
68 let b_length = b.len();
69
70 if b_length == 0 {
71 return true;
72 }
73
74 let a = self.as_ref();
75
76 let a_length = a.len();
77
78 if a_length >= b_length {
79 !unsafe { a.get_unchecked((a_length - b_length)..) }
80 .iter()
81 .map(|e| e.to_ascii_uppercase())
82 .zip(b.iter().copied())
83 .any(|(ac, bc)| ac != bc)
84 } else {
85 false
86 }
87 }
88}