string_width_with_options

Function string_width_with_options 

Source
pub fn string_width_with_options(
    input: &str,
    options: StringWidthOptions,
) -> usize
Expand description

Main function that calculates the display width of a string

This is the core width calculation function that processes a string grapheme by grapheme, handling:

  • ANSI escape sequences (optionally)
  • Zero-width character clusters
  • Emoji sequences
  • East Asian character widths
  • Combining characters and modifiers

Β§Arguments

  • input - The string to measure
  • options - Configuration options for the calculation

Β§Returns

The display width of the string in terminal columns

Β§Examples

use string_width::{string_width_with_options, StringWidthOptions};

let options = StringWidthOptions::default();
assert_eq!(string_width_with_options("Hello", options.clone()), 5);
assert_eq!(string_width_with_options("πŸ˜€", options), 2);
Examples found in repository?
examples/basic_usage.rs (line 57)
8fn main() {
9    println!("=== Basic String Width Examples ===\n");
10
11    // Basic ASCII text
12    let text = "Hello, World!";
13    println!("Text: '{}'", text);
14    println!("Width: {}\n", string_width(text));
15
16    // East Asian characters (full-width)
17    let text = "δ½ ε₯½δΈ–η•Œ";
18    println!("Text: '{}'", text);
19    println!("Width: {}\n", string_width(text));
20
21    // Mixed content
22    let text = "Hello δΈ–η•Œ!";
23    println!("Text: '{}'", text);
24    println!("Width: {}\n", string_width(text));
25
26    // Emoji examples
27    let text = "Hello πŸ‘‹ World 🌍";
28    println!("Text: '{}'", text);
29    println!("Width: {}\n", string_width(text));
30
31    // Complex emoji sequences
32    let text = "Family: πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦";
33    println!("Text: '{}'", text);
34    println!("Width: {}\n", string_width(text));
35
36    // Keycap sequences
37    let text = "Numbers: 1️⃣ 2️⃣ 3️⃣";
38    println!("Text: '{}'", text);
39    println!("Width: {}\n", string_width(text));
40
41    // Flag sequences
42    let text = "Flags: πŸ‡ΊπŸ‡Έ πŸ‡―πŸ‡΅ πŸ‡¬πŸ‡§";
43    println!("Text: '{}'", text);
44    println!("Width: {}\n", string_width(text));
45
46    // ANSI escape sequences (stripped by default)
47    let text = "\x1b[31mRed text\x1b[0m";
48    println!("Text with ANSI: '{}'", text);
49    println!("Width (ANSI stripped): {}", string_width(text));
50
51    let options = StringWidthOptions {
52        count_ansi: true,
53        ambiguous_width: AmbiguousWidthTreatment::Narrow,
54    };
55    println!(
56        "Width (ANSI counted): {}\n",
57        string_width_with_options(text, options)
58    );
59
60    // Ambiguous width characters
61    let text = "Β±Γ—Γ·";
62    println!("Text: '{}'", text);
63    println!("Width (narrow): {}", string_width(text));
64
65    let options = StringWidthOptions {
66        count_ansi: false,
67        ambiguous_width: AmbiguousWidthTreatment::Wide,
68    };
69    println!(
70        "Width (wide): {}\n",
71        string_width_with_options(text, options)
72    );
73
74    // Zero-width characters
75    let text = "a\u{200B}b\u{200C}c";
76    println!("Text with zero-width chars: 'a\\u{{200B}}b\\u{{200C}}c'");
77    println!("Width: {}\n", string_width(text));
78
79    // Combining characters
80    let text = "e\u{0301}"; // e with acute accent
81    println!("Text with combining: 'e\\u{{0301}}'");
82    println!("Width: {}\n", string_width(text));
83}
More examples
Hide additional examples
examples/cli_tool.rs (line 89)
12fn main() {
13    let args: Vec<String> = env::args().collect();
14
15    let input = if args.len() > 1 {
16        // Use command line argument
17        args[1..].join(" ")
18    } else {
19        // Read from stdin
20        let mut buffer = String::new();
21        match io::stdin().read_to_string(&mut buffer) {
22            Ok(_) => buffer.trim_end().to_string(),
23            Err(e) => {
24                eprintln!("Error reading from stdin: {}", e);
25                std::process::exit(1);
26            }
27        }
28    };
29
30    if input.is_empty() {
31        eprintln!("Usage: {} <text> or echo <text> | {}", args[0], args[0]);
32        eprintln!("       Measures the display width of Unicode text");
33        std::process::exit(1);
34    }
35
36    println!("Text analysis for: '{}'", input);
37    println!("{}", "─".repeat(50));
38
39    // Basic width
40    let width = input.display_width();
41    println!("Display width: {} characters", width);
42
43    // Character count vs display width
44    let char_count = input.chars().count();
45    let byte_count = input.len();
46    println!("Character count: {}", char_count);
47    println!("Byte count: {}", byte_count);
48
49    if width != char_count {
50        println!("Note: Display width differs from character count");
51        if width > char_count {
52            println!("  β†’ Contains wide characters (CJK, emoji)");
53        } else {
54            println!("  β†’ Contains zero-width or combining characters");
55        }
56    }
57
58    // Detailed analysis
59    println!("\nDetailed breakdown:");
60    for (i, ch) in input.chars().enumerate() {
61        let ch_width = string_width(ch.to_string().as_str());
62        let code_point = ch as u32;
63
64        let char_type = match ch_width {
65            0 => "zero-width",
66            1 => "narrow",
67            2 => "wide",
68            _ => "unknown",
69        };
70
71        println!(
72            "  {}: '{}' (U+{:04X}) - {} width",
73            i + 1,
74            ch,
75            code_point,
76            char_type
77        );
78    }
79
80    // Different width calculation options
81    println!("\nWidth with different options:");
82
83    let narrow_ambiguous = StringWidthOptions {
84        count_ansi: false,
85        ambiguous_width: AmbiguousWidthTreatment::Narrow,
86    };
87    println!(
88        "  Ambiguous as narrow: {}",
89        string_width_with_options(input.as_str(), narrow_ambiguous)
90    );
91
92    let wide_ambiguous = StringWidthOptions {
93        count_ansi: false,
94        ambiguous_width: AmbiguousWidthTreatment::Wide,
95    };
96    println!(
97        "  Ambiguous as wide: {}",
98        string_width_with_options(input.as_str(), wide_ambiguous)
99    );
100
101    let count_ansi = StringWidthOptions {
102        count_ansi: true,
103        ambiguous_width: AmbiguousWidthTreatment::Narrow,
104    };
105    println!(
106        "  Counting ANSI codes: {}",
107        string_width_with_options(input.as_str(), count_ansi)
108    );
109
110    // Terminal formatting example
111    println!("\nTerminal formatting examples:");
112    let box_width = 40;
113    let content_width = input.display_width();
114
115    if content_width <= box_width - 4 {
116        let padding = box_width - content_width - 4;
117        let left_pad = padding / 2;
118        let right_pad = padding - left_pad;
119
120        println!("β”Œ{}┐", "─".repeat(box_width - 2));
121        println!(
122            "β”‚{}{}{}β”‚",
123            " ".repeat(left_pad + 1),
124            input,
125            " ".repeat(right_pad + 1)
126        );
127        println!("β””{}β”˜", "─".repeat(box_width - 2));
128    } else {
129        println!(
130            "Text too wide for box (width: {}, box: {})",
131            content_width,
132            box_width - 4
133        );
134    }
135}