Skip to content

Commit 3d9295a

Browse files
committed
Implement measure_text_width with no allocation
I implemented that while working on optimizing something I don't remember, it might still be useful.
1 parent d0907e9 commit 3d9295a

3 files changed

Lines changed: 30 additions & 10 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ ansi-parsing = []
1919

2020
[dependencies]
2121
libc = "0.2.99"
22-
once_cell = "1.8"
22+
once_cell = "1.8,<1.21" # version 1.21 requires Rust >= 1.70
2323
unicode-width = { version = "0.2", optional = true }
2424

2525
[target.'cfg(windows)'.dependencies]

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ test:
1414
@cargo test
1515
@cargo test --all-features
1616
@cargo test --no-default-features
17+
@cargo test --no-default-features -F ansi-parsing
18+
@cargo test --no-default-features -F unicode-width
1719

1820
check-minver:
1921
@echo "MINVER CHECK"

src/utils.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,7 @@ use once_cell::sync::Lazy;
99
use crate::term::{wants_emoji, Term};
1010

1111
#[cfg(feature = "ansi-parsing")]
12-
use crate::ansi::{strip_ansi_codes, AnsiCodeIterator};
13-
14-
#[cfg(not(feature = "ansi-parsing"))]
15-
fn strip_ansi_codes(s: &str) -> &str {
16-
s
17-
}
12+
use crate::ansi::AnsiCodeIterator;
1813

1914
fn default_colors_enabled(out: &Term) -> bool {
2015
(out.features().colors_supported()
@@ -71,7 +66,18 @@ pub fn set_colors_enabled_stderr(val: bool) {
7166

7267
/// Measure the width of a string in terminal characters.
7368
pub fn measure_text_width(s: &str) -> usize {
74-
str_width(&strip_ansi_codes(s))
69+
dbg!(&s);
70+
#[cfg(feature = "ansi-parsing")]
71+
{
72+
AnsiCodeIterator::new(s)
73+
.filter(|(_, is_ansi)| !is_ansi)
74+
.map(|(sub, _)| str_width(sub))
75+
.sum()
76+
}
77+
#[cfg(not(feature = "ansi-parsing"))]
78+
{
79+
str_width(s)
80+
}
7581
}
7682

7783
/// A terminal color.
@@ -937,16 +943,28 @@ fn test_text_width() {
937943
.bold()
938944
.force_styling(true)
939945
.to_string();
946+
940947
assert_eq!(
941948
measure_text_width(&s),
942949
if cfg!(feature = "ansi-parsing") {
943950
3
944-
} else if cfg!(feature = "unicode-width") {
945-
17
946951
} else {
947952
21
948953
}
949954
);
955+
956+
assert_eq!(
957+
measure_text_width(&dbg!(style("🐶 <3").red()).to_string()),
958+
match (
959+
cfg!(feature = "ansi-parsing"),
960+
cfg!(feature = "unicode-width")
961+
) {
962+
(true, true) => 5, // "🐶 <3"
963+
(true, false) => 4, // "🐶 <3", no unicode-aware width
964+
(false, true) => 14, // full string
965+
(false, false) => 13, // full string, no unicode-aware width
966+
}
967+
);
950968
}
951969

952970
#[test]

0 commit comments

Comments
 (0)