pub fn string_width_with_options(
input: &str,
options: StringWidthOptions,
) -> usizeExpand 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 measureoptions- 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
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}