runefix_core/
ext.rs

1//! Extension trait for ergonomic width measurement.
2//!
3//! This module defines [`RuneDisplayWidth`], a trait implemented for both `char` and `str`,
4//! providing convenient methods like `.width()`, `.rune_width()`, and `.display_widths()`.
5//!
6//! These methods offer a unified interface for querying terminal display width,
7//! automatically applying grapheme segmentation where appropriate.
8//!
9//! See also:
10//! - [`display_width`](crate::grapheme::display_width)
11//! - [`WidthPolicy`](crate::policy::WidthPolicy) for configurable strategies
12
13/// Extension trait for measuring the display width of runes, graphemes, and strings.
14///
15/// This trait provides unified access to terminal display width calculations
16/// for both `char` and `&str`. It supports:
17///
18/// - Single runes (`char`)
19/// - Full Unicode strings with grapheme segmentation (`&str`)
20///
21/// All widths are measured in terminal columns, respecting East Asian widths,
22/// emoji sequences, and control characters.
23///
24/// # Examples
25///
26/// ```rust
27/// use runefix_core::RuneDisplayWidth;
28///
29/// assert_eq!('語'.rune_width(), 2);
30/// assert_eq!("你👋a".display_widths(), vec![2, 2, 1]);
31/// assert_eq!("Hi👋".display_width(), 4);
32/// assert_eq!("👋".width(), 2);
33/// ```
34pub trait RuneDisplayWidth {
35    /// Returns the display width of a single rune or grapheme.
36    ///
37    /// For `char`, this is the width of the character.
38    /// For `&str`, this assumes the string is a single grapheme cluster.
39    fn rune_width(&self) -> usize;
40
41    /// Returns the total display width in terminal columns.
42    ///
43    /// Equivalent to summing the result of `display_widths()`.
44    fn display_width(&self) -> usize;
45
46    /// Returns the display width of each grapheme cluster in the value.
47    ///
48    /// For `&str`, this segments the string using Unicode grapheme rules.
49    /// For `char`, returns a single-item vector.
50    fn display_widths(&self) -> Vec<usize>;
51
52    /// Returns the total display width in terminal columns
53    /// (alias of `display_width()`).
54    fn width(&self) -> usize {
55        self.display_width()
56    }
57}
58
59impl RuneDisplayWidth for str {
60    fn rune_width(&self) -> usize {
61        crate::width::get_display_width(self)
62    }
63
64    fn display_width(&self) -> usize {
65        crate::grapheme::display_width(self)
66    }
67
68    fn display_widths(&self) -> Vec<usize> {
69        crate::grapheme::display_widths(self)
70    }
71}
72
73impl RuneDisplayWidth for char {
74    fn rune_width(&self) -> usize {
75        crate::width::get_display_width(&self.to_string())
76    }
77
78    fn display_width(&self) -> usize {
79        self.rune_width()
80    }
81
82    fn display_widths(&self) -> Vec<usize> {
83        vec![self.rune_width()]
84    }
85}