use crate::fast_str_tools::*;
pub(crate) fn str_chars_to_bytes(s: &str, char_pos: usize) -> usize {
char_to_byte_idx(s, char_pos)
}
pub(crate) fn str_chars_to_bytes_rev(s: &str, char_len: usize) -> usize {
if char_len == 0 { return 0; }
let mut chars_remaining = char_len;
for (i, byte) in s.as_bytes().iter().rev().enumerate() {
if (*byte & 0b11_00_0000) != 0b10_00_0000 {
chars_remaining -= 1;
if chars_remaining == 0 { return i+1; }
}
}
panic!("Insufficient characters in string");
}
#[cfg(feature = "line_conversion")]
pub(crate) fn count_lines(s: &str) -> usize {
s.as_bytes().iter().filter(|b| **b == ('\n' as u8)).count()
}
#[cfg(test)]
mod tests {
use crate::utils::*;
fn check_counts(s: &str) {
let num_chars = s.chars().count();
assert_eq!(count_chars(s), num_chars);
for i in 0..=num_chars {
let byte_offset = str_chars_to_bytes(s, i);
assert_eq!(count_chars(&s[..byte_offset]), i);
let end_offset = str_chars_to_bytes_rev(s, num_chars - i);
assert_eq!(end_offset, s.len() - byte_offset);
}
}
#[test]
fn backwards_smoke_tests() {
check_counts("hi there");
check_counts("κό𝕐𝕆😘σμε");
}
#[test]
#[cfg(feature = "line_conversion")]
fn count_lines_tests() {
assert_eq!(count_lines(""), 0);
assert_eq!(count_lines("\n"), 1);
assert_eq!(count_lines("fop\n\n"), 2);
}
}