string-width
Accurate Unicode string width calculation for terminal applications. This library correctly handles:
- Emoji sequences (π¨βπ©βπ§βπ¦, πΊπΈ, 1οΈβ£)
- East Asian characters (δ½ ε₯½, γγγ«γ‘γ―, μλ νμΈμ)
- Combining marks and diacritics (Γ©, Γ±, ΓΌ)
- Zero-width characters (ZWJ, ZWNJ, format characters)
- ANSI escape sequences (colors, cursor movement)
- Ambiguous width characters (Β±, Γ, Γ·)
Features
- π― Accurate: Implements Unicode Standard recommendations for character width
- π Fast: Optimized for performance with minimal allocations
- π§ Configurable: Handle ambiguous characters and ANSI codes as needed
- π¦ Zero-config: Works out of the box with sensible defaults
- π§ͺ Well-tested: Comprehensive test suite with 160+ test cases
Quick Start
Add this to your Cargo.toml:
[]
= "0.1.0"
Minimum Supported Rust Version (MSRV): 1.85
Usage
Basic Usage
use string_width;
// ASCII text
assert_eq!;
// East Asian characters (full-width)
assert_eq!;
// Emoji
assert_eq!;
assert_eq!; // Flag
assert_eq!; // Keycap sequence
// Mixed content
assert_eq!;
// ANSI escape sequences are ignored by default
assert_eq!;
Advanced Configuration
use ;
// Direct configuration
let options = StringWidthOptions ;
assert_eq!; // Ambiguous chars as wide
assert_eq!; // Count ANSI
// Using the builder pattern (recommended)
let options = builder
.count_ansi
.ambiguous_as_wide
.build;
assert_eq!;
Configuration Builder Pattern
use ;
// Fluent builder API for easy configuration
let options = builder
.count_ansi
.ambiguous_as_wide
.build;
let text = "\x1b[31mΒ±ΓΓ·\x1b[0m";
assert_eq!; // ANSI + wide ambiguous
// Convenience methods for common configurations
let narrow_options = builder
.ambiguous_as_narrow
.build;
let wide_options = builder
.ambiguous_as_wide
.build;
// Equivalent to direct construction but more readable
let manual_options = StringWidthOptions ;
Using the DisplayWidth Trait
use ;
let text = "Hello π";
println!;
// With custom options using builder pattern
let options = builder
.count_ansi
.ambiguous_as_narrow
.build;
println!;
// Works with both &str and String
let owned_string = Stringfrom;
println!;
Terminal Applications
Perfect for building CLI tools that need proper text alignment:
Text Alignment
use DisplayWidth;
// Works correctly with Unicode content
println!; // βHello β
println!; // βδ½ ε₯½ β
println!; // βπΊπΈ USA β
Table Formatting
use DisplayWidth;
let data = vec!;
// Calculate column widths
let widths: =
.map
.collect;
// Print aligned table
for in data
Examples
The library includes comprehensive examples demonstrating various use cases:
# Basic usage examples - demonstrates core functionality
# Terminal formatting and alignment - shows real-world usage
# CLI tool for measuring text width - interactive width analysis
|
Key Example Features
- Basic Usage: ASCII, Unicode, emoji, and mixed content width calculation
- Terminal Formatting: Text alignment, table formatting, and progress bars
- CLI Tool: Interactive analysis with detailed character breakdown and formatting examples
Supported Unicode Features
| Feature | Example | Width |
|---|---|---|
| ASCII | "Hello" |
5 |
| East Asian | "δ½ ε₯½" |
4 |
| Emoji | "π" |
2 |
| Emoji sequences | "π¨βπ©βπ§βπ¦" |
2 |
| Keycap sequences | "1οΈβ£" |
2 |
| Flag sequences | "πΊπΈ" |
2 |
| Combining marks | "Γ©" (e + Β΄) |
1 |
| Zero-width chars | "a\u{200B}b" |
2 |
| ANSI codes | "\x1b[31mRed\x1b[0m" |
3 |
Architecture
The library is designed with a modular architecture:
width_calculation: Core width calculation logic and public APIcharacter_classification: Unicode character categorization and analysisemoji: Emoji sequence detection and handlingoptions: Configuration types and builder patternunicode_constants: Precomputed Unicode property tables
Performance
The library is optimized for performance:
- Minimal allocations during width calculation
- Efficient Unicode property lookups using precomputed tables
- Compiled regex patterns for zero-width detection
- Single-pass processing for most cases
- Optimized grapheme cluster processing
API Overview
The library provides multiple ways to calculate string width:
| Function/Trait | Use Case | Example |
|---|---|---|
string_width() |
Simple width calculation | string_width("Hello") |
DisplayWidth |
Ergonomic trait-based API | "Hello".display_width() |
StringWidthInput |
Legacy compatibility | "Hello".calculate_width() |
| Builder Pattern | Complex configuration | StringWidthOptions::builder().build() |
Comparison with Other Libraries
| Library | Emoji Support | East Asian | ANSI Handling | Combining Marks | Builder API |
|---|---|---|---|---|---|
| string-width | β Full | β Yes | β Configurable | β Yes | β Yes |
| unicode-width | β Basic | β Yes | β No | β Yes | β No |
| textwrap | β No | β Yes | β No | β Yes | β No |
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
License
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Acknowledgments
- Unicode Consortium for the Unicode Standard
- East Asian Width property implementation
- Terminal emulator developers for width handling insights