Skip to content

Commit

Permalink
fix truncation on ascii chars (with bad asymptotic complexity)
Browse files Browse the repository at this point in the history
  • Loading branch information
remi-dupre committed Feb 7, 2024
1 parent 44618a8 commit ebb9956
Showing 1 changed file with 30 additions and 13 deletions.
43 changes: 30 additions & 13 deletions src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,27 @@ impl<'a> fmt::Display for RepeatedStringDisplay<'a> {
}
}

fn truncate_to_fit(text: &str, align: Alignment, target_width: usize) -> Option<&str> {
let mut start = 0;
let mut end = text.len();
let mut left_priority = true;

// Iter next truncation positions from left or right
let mut char_pos_from_left = text.char_indices().map(|(idx, _)| idx).skip(1);
let mut char_pos_from_right = text.char_indices().map(|(idx, _)| idx).rev();

while measure_text_width(text.get(start..end).unwrap_or("")) > target_width {
match (align, left_priority) {
(Alignment::Left, _) | (Alignment::Center, true) => end = char_pos_from_right.next()?,
_ => start = char_pos_from_left.next()?,
}

left_priority = !left_priority;
}

text.get(start..end)
}

struct PaddedStringDisplay<'a> {
str: &'a str,
width: usize,
Expand All @@ -694,20 +715,10 @@ struct PaddedStringDisplay<'a> {
impl<'a> fmt::Display for PaddedStringDisplay<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let cols = measure_text_width(self.str);
let excess = cols.saturating_sub(self.width);
if excess > 0 && !self.truncate {
return f.write_str(self.str);
} else if excess > 0 {
let (start, end) = match self.align {
Alignment::Left => (0, self.str.len() - excess),
Alignment::Right => (excess, self.str.len()),
Alignment::Center => (
excess / 2,
self.str.len() - excess.saturating_sub(excess / 2),
),
};

return f.write_str(self.str.get(start..end).unwrap_or(self.str));
if cols > self.width && self.truncate {
return f
.write_str(truncate_to_fit(self.str, self.align, self.width).unwrap_or(self.str));
}

let diff = self.width.saturating_sub(cols);
Expand Down Expand Up @@ -918,6 +929,12 @@ mod tests {
state.message = TabExpandedString::NoTabs("abcdefghijklmnopqrst".into());
style.format_state(&state, &mut buf, WIDTH);
assert_eq!(&buf[0], "fghijklmno");

buf.clear();
let style = ProgressStyle::with_template("{wide_msg}").unwrap();
state.message = TabExpandedString::NoTabs("\x1b[31mabcdefghijklmnopqrst\x1b[0m".into());
style.format_state(&state, &mut buf, WIDTH);
assert_eq!(&buf[0], "\x1b[31mabcdefghij");
}

#[test]
Expand Down

0 comments on commit ebb9956

Please sign in to comment.