1 use crate::util; 2 3 const SURROGATE_LENGTH: usize = 3; 4 ends_with(string: &[u8], mut suffix: &[u8]) -> bool5pub(crate) fn ends_with(string: &[u8], mut suffix: &[u8]) -> bool { 6 let index = if let Some(index) = string.len().checked_sub(suffix.len()) { 7 index 8 } else { 9 return false; 10 }; 11 if let Some(&byte) = string.get(index) { 12 if util::is_continuation(byte) { 13 let index = expect_encoded!(index.checked_sub(1)); 14 let mut wide_surrogate = 15 if let Some(surrogate) = suffix.get(..SURROGATE_LENGTH) { 16 super::encode_wide(surrogate) 17 } else { 18 return false; 19 }; 20 let surrogate_wchar = wide_surrogate 21 .next() 22 .expect("failed decoding non-empty suffix"); 23 24 if wide_surrogate.next().is_some() 25 || super::encode_wide(&string[index..]) 26 .take_while(Result::is_ok) 27 .nth(1) 28 != Some(surrogate_wchar) 29 { 30 return false; 31 } 32 suffix = &suffix[SURROGATE_LENGTH..]; 33 } 34 } 35 string.ends_with(suffix) 36 } 37 starts_with(string: &[u8], mut prefix: &[u8]) -> bool38pub(crate) fn starts_with(string: &[u8], mut prefix: &[u8]) -> bool { 39 if let Some(&byte) = string.get(prefix.len()) { 40 if util::is_continuation(byte) { 41 let index = if let Some(index) = 42 prefix.len().checked_sub(SURROGATE_LENGTH) 43 { 44 index 45 } else { 46 return false; 47 }; 48 let (substring, surrogate) = prefix.split_at(index); 49 let mut wide_surrogate = super::encode_wide(surrogate); 50 let surrogate_wchar = wide_surrogate 51 .next() 52 .expect("failed decoding non-empty prefix"); 53 54 if surrogate_wchar.is_err() 55 || wide_surrogate.next().is_some() 56 || super::encode_wide(&string[index..]) 57 .next() 58 .expect("failed decoding non-empty substring") 59 != surrogate_wchar 60 { 61 return false; 62 } 63 prefix = substring; 64 } 65 } 66 string.starts_with(prefix) 67 } 68