| 1 | use core::cmp::Ordering; |
| 2 | |
| 3 | /// Decodes the next UTF-8 encoded codepoint from the given byte slice. |
| 4 | /// |
| 5 | /// If no valid encoding of a codepoint exists at the beginning of the given |
| 6 | /// byte slice, then the first byte is returned instead. |
| 7 | /// |
| 8 | /// This returns `None` if and only if `bytes` is empty. |
| 9 | /// |
| 10 | /// This never panics. |
| 11 | /// |
| 12 | /// *WARNING*: This is not designed for performance. If you're looking for a |
| 13 | /// fast UTF-8 decoder, this is not it. If you feel like you need one in this |
| 14 | /// crate, then please file an issue and discuss your use case. |
| 15 | pub(crate) fn decode(bytes: &[u8]) -> Option<Result<char, u8>> { |
| 16 | crate::shared::util::utf8::decode(bytes) |
| 17 | } |
| 18 | |
| 19 | /// Like std's `eq_ignore_ascii_case`, but returns a full `Ordering`. |
| 20 | #[inline ] |
| 21 | pub(crate) fn cmp_ignore_ascii_case(s1: &str, s2: &str) -> Ordering { |
| 22 | cmp_ignore_ascii_case_bytes(s1.as_bytes(), s2.as_bytes()) |
| 23 | } |
| 24 | |
| 25 | /// Like std's `eq_ignore_ascii_case`, but returns a full `Ordering` on |
| 26 | /// `&[u8]`. |
| 27 | #[inline ] |
| 28 | pub(crate) fn cmp_ignore_ascii_case_bytes(s1: &[u8], s2: &[u8]) -> Ordering { |
| 29 | // This function used to look like this: |
| 30 | // |
| 31 | // let it1 = s1.iter().map(|&b| b.to_ascii_lowercase()); |
| 32 | // let it2 = s2.iter().map(|&b| b.to_ascii_lowercase()); |
| 33 | // it1.cmp(it2) |
| 34 | // |
| 35 | // But the code below seems to do better in microbenchmarks. |
| 36 | let mut i: usize = 0; |
| 37 | loop { |
| 38 | let b1: Option = s1.get(index:i).copied().map(|b: u8| b.to_ascii_lowercase()); |
| 39 | let b2: Option = s2.get(index:i).copied().map(|b: u8| b.to_ascii_lowercase()); |
| 40 | match (b1, b2) { |
| 41 | (None, None) => return Ordering::Equal, |
| 42 | (Some(_), None) => return Ordering::Greater, |
| 43 | (None, Some(_)) => return Ordering::Less, |
| 44 | (Some(b1: u8), Some(b2: u8)) if b1 == b2 => i += 1, |
| 45 | (Some(b1: u8), Some(b2: u8)) => return b1.cmp(&b2), |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | |