pub fn utf16_len(s: &str) -> usize {
s.chars().map(char::len_utf16).sum()
}
pub fn utf16_index(s: &str, byte_idx: usize) -> usize {
utf16_len(&s[..byte_idx])
}
pub fn byte_index(s: &str, u16_idx: usize) -> usize {
let mut u16 = 0usize;
for (byte, c) in s.char_indices() {
if u16 >= u16_idx {
return byte;
}
u16 += c.len_utf16();
}
s.len()
}
pub fn utf16_slice(s: &str, start_u16: usize, end_u16: usize) -> &str {
let start = byte_index(s, start_u16);
let end = byte_index(s, end_u16);
&s[start..end]
}
pub fn java_trim(s: &str) -> &str {
s.trim_matches(|c: char| (c as u32) <= 0x20)
}
pub fn java_strip(s: &str) -> &str {
s.trim_matches(is_java_whitespace)
}
pub fn java_strip_leading(s: &str) -> &str {
s.trim_start_matches(is_java_whitespace)
}
fn is_java_whitespace(c: char) -> bool {
match c {
'\u{00A0}' | '\u{2007}' | '\u{202F}' => false,
'\u{001C}'..='\u{001F}' => true,
_ => c.is_whitespace(),
}
}