use crate::{encoding::Encoding, grapheme::next_cluster, simd::plain_prefix, utf8::Utf8};
#[inline]
pub fn truncate<E: Encoding>(input: &[E::Unit], max_width: usize) -> &[E::Unit] {
let mut width = 0usize;
let mut pos = 0usize;
loop {
if pos == input.len() {
return input;
}
if !E::FOREIGN {
let remaining = &input[pos..];
let budget = max_width - width;
let window = remaining.len().min(budget.saturating_add(1));
let run = plain_prefix(&remaining[..window]);
if run > 0 {
let safe = if pos + run < input.len() {
run - 1
} else {
run
};
let take = safe.min(budget);
pos += take;
width += take;
if take < safe {
return &input[..pos];
}
if pos == input.len() {
return input;
}
}
}
let scan = next_cluster::<E>(&input[pos..]);
if width + scan.width > max_width {
return &input[..pos];
}
pos += scan.units;
width += scan.width;
}
}
#[inline]
pub fn truncate_str(input: &str, max_width: usize) -> &str {
unsafe { core::str::from_utf8_unchecked(truncate::<Utf8>(input.as_bytes(), max_width)) }
}