// src/components/utils/text.rs use unicode_width::UnicodeWidthStr; use unicode_segmentation::UnicodeSegmentation; /// Truncates a string to a maximum width, adding an ellipsis if truncated. /// Considers unicode character widths. pub fn truncate_string(s: &str, max_width: usize) -> String { if UnicodeWidthStr::width(s) <= max_width { s.to_string() } else { let ellipsis = "…"; let ellipsis_width = UnicodeWidthStr::width(ellipsis); let mut truncated_width = 0; let mut end_byte_index = 0; // Iterate over graphemes to handle multi-byte characters correctly for (i, g) in s.grapheme_indices(true) { let char_width = UnicodeWidthStr::width(g); if truncated_width + char_width + ellipsis_width > max_width { break; } truncated_width += char_width; end_byte_index = i + g.len(); } format!("{}{}", &s[..end_byte_index], ellipsis) } }