#[must_use]
pub(crate) fn utf16_len(text: &str) -> usize {
text.chars().map(char::len_utf16).sum()
}
#[must_use]
pub(crate) fn utf16_len_rtrimmed(text: &str) -> usize {
utf16_len(text.trim_end())
}
#[cfg(test)]
mod tests {
use super::{utf16_len, utf16_len_rtrimmed};
#[test]
fn ascii_counts_one_per_character() {
let expected: usize = 5;
let actual: usize = utf16_len("hello");
assert_eq!(expected, actual);
}
#[test]
fn basic_multilingual_plane_counts_one_per_character() {
let expected: usize = 2;
let actual: usize = utf16_len("é中");
assert_eq!(expected, actual);
}
#[test]
fn astral_plane_characters_count_two() {
let expected: usize = 2;
let actual: usize = utf16_len("🎨");
assert_eq!(expected, actual);
}
#[test]
fn mixed_text_sums_correctly() {
let expected: usize = 6;
let actual: usize = utf16_len("🎨 New");
assert_eq!(expected, actual);
}
#[test]
fn empty_string_is_zero() {
let expected: usize = 0;
let actual: usize = utf16_len("");
assert_eq!(expected, actual);
}
#[test]
fn rtrimmed_excludes_trailing_whitespace() {
let expected: usize = 6;
let actual: usize = utf16_len_rtrimmed("Header\n\t ");
assert_eq!(expected, actual);
}
#[test]
fn rtrimmed_keeps_leading_whitespace() {
let expected: usize = 8;
let actual: usize = utf16_len_rtrimmed(" Header");
assert_eq!(expected, actual);
}
#[test]
fn rtrimmed_of_only_whitespace_is_zero() {
let expected: usize = 0;
let actual: usize = utf16_len_rtrimmed(" \n\t");
assert_eq!(expected, actual);
}
}