oxi-tui 0.14.0

Terminal UI widgets and theme system for oxi, built on ratatui
Documentation
//! Text rendering utilities for TUI widgets.

use unicode_width::UnicodeWidthChar;

/// Truncate a string to fit within `max_width` terminal columns.
///
/// Appends `…` (U+2026) if the string was truncated.
/// Returns an empty string if `max_width` is 0.
pub fn truncate_to_width(s: &str, max_width: usize) -> String {
    if max_width == 0 {
        return String::new();
    }
    let mut width = 0usize;
    let mut end = 0usize;
    for (i, ch) in s.char_indices() {
        let cw = UnicodeWidthChar::width(ch).unwrap_or(0);
        if width + cw > max_width {
            // Not enough room for ellipsis either
            return s[..end].to_string();
        }
        if width + cw > max_width.saturating_sub(1) {
            // Would overflow if we add ellipsis
            return format!("{}\u{2026}", &s[..end]);
        }
        width += cw;
        end = i + ch.len_utf8();
    }
    s.to_string()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_truncate_to_width() {
        let text = "hello world";
        assert_eq!(truncate_to_width(text, 100), "hello world");
        assert_eq!(truncate_to_width(text, 5), "hell…");
        assert_eq!(truncate_to_width(text, 0), "");
    }
}