use crate::util; const SURROGATE_LENGTH: usize = 3; pub(crate) fn ends_with(string: &[u8], mut suffix: &[u8]) -> bool { let index = if let Some(index) = string.len().checked_sub(suffix.len()) { index } else { return false; }; if let Some(&byte) = string.get(index) { if util::is_continuation(byte) { let index = expect_encoded!(index.checked_sub(1)); let mut wide_surrogate = if let Some(surrogate) = suffix.get(..SURROGATE_LENGTH) { super::encode_wide(surrogate) } else { return false; }; let surrogate_wchar = wide_surrogate .next() .expect("failed decoding non-empty suffix"); if wide_surrogate.next().is_some() || super::encode_wide(&string[index..]) .take_while(Result::is_ok) .nth(1) != Some(surrogate_wchar) { return false; } suffix = &suffix[SURROGATE_LENGTH..]; } } string.ends_with(suffix) } pub(crate) fn starts_with(string: &[u8], mut prefix: &[u8]) -> bool { if let Some(&byte) = string.get(prefix.len()) { if util::is_continuation(byte) { let index = if let Some(index) = prefix.len().checked_sub(SURROGATE_LENGTH) { index } else { return false; }; let (substring, surrogate) = prefix.split_at(index); let mut wide_surrogate = super::encode_wide(surrogate); let surrogate_wchar = wide_surrogate .next() .expect("failed decoding non-empty prefix"); if surrogate_wchar.is_err() || wide_surrogate.next().is_some() || super::encode_wide(&string[index..]) .next() .expect("failed decoding non-empty substring") != surrogate_wchar { return false; } prefix = substring; } } string.starts_with(prefix) }