Skip to content

Commit dfc5b30

Browse files
committed
Add width() function.
1 parent 04b2cd5 commit dfc5b30

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ name = "unicode-columns"
33
version = "0.1.0"
44
edition = "2021"
55

6-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
76

87
[dependencies]
98
unicode-width = "0.1"

src/lib.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,53 @@
11
use unicode_width::UnicodeWidthChar;
22

3+
const ZWJ: u32 = 0x200d;
4+
5+
/// Get the column width of a string
6+
pub fn width(string: &str) -> usize {
7+
let mut cw = 0;
8+
let mut iter = string.chars();
9+
while let Some(c) = iter.next() {
10+
if u32::from(c) == ZWJ {
11+
iter.next();
12+
continue;
13+
}
14+
cw += c.width().unwrap_or(0);
15+
}
16+
cw
17+
}
18+
319
/// Truncate a string to a specific column width
420
pub fn truncate(string: &str, width: usize) -> &str {
521
let mut cw = 0;
622
let mut iter = string.char_indices();
723
while let Some((i, c)) = iter.next() {
8-
if u32::from(c) == /* ZWJ */ 0x200d {
24+
if u32::from(c) == ZWJ {
925
iter.next();
1026
continue;
1127
}
12-
let nw = cw + c.width().unwrap_or(0);
13-
if nw > width {
28+
cw += c.width().unwrap_or(0);
29+
if cw > width {
1430
return &string[..i];
1531
}
16-
cw = nw;
1732
}
1833
string
1934
}
2035

2136
#[cfg(test)]
2237
mod tests {
23-
use crate::truncate;
38+
use super::*;
39+
40+
#[test]
41+
fn test_width() {
42+
// basic tests
43+
assert_eq!(width("teststring"), 10);
44+
// full-width (2 column) characters test
45+
assert_eq!(width("잘라야"), 6);
46+
// combining characters (zalgo text) test
47+
assert_eq!(width("ę̵̡̛̮̹̼̝̲͓̳̣͉̞͔̳̥̝͍̩̣̹͙̘̼̥̗̼͈̯͎̮̥̤̪̻̮͕̩̮͓͔̟͈͇͎̣͉͇̦͔̝̣͎͎͔͇̭͈̌̂̈̄̈́̾͑̀̈̓̂͗̾̉͊͒̆̽͊̽͘̕͜͜͝͠ :width"), 8);
48+
// zero-width-joiner (emoji) test
49+
assert_eq!(width("👨‍👩‍👦:width"), 8);
50+
}
2451

2552
#[test]
2653
fn test_truncation() {

0 commit comments

Comments
 (0)