Skip to content

Commit d8a8a34

Browse files
committed
fix(exec): truncate output on utf8 boundaries
1 parent 7954d02 commit d8a8a34

1 file changed

Lines changed: 44 additions & 1 deletion

File tree

src/cortex-exec/src/output.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,14 @@ fn truncate(s: &str, max_len: usize) -> String {
169169
if s.len() <= max_len {
170170
s.to_string()
171171
} else {
172-
format!("{}...", &s[..max_len])
172+
let end = s
173+
.char_indices()
174+
.map(|(idx, _)| idx)
175+
.take_while(|idx| *idx <= max_len)
176+
.last()
177+
.unwrap_or(0);
178+
179+
format!("{}...", &s[..end])
173180
}
174181
}
175182

@@ -178,3 +185,39 @@ impl Default for OutputWriter {
178185
Self::new(OutputFormat::Text)
179186
}
180187
}
188+
189+
#[cfg(test)]
190+
mod tests {
191+
use super::truncate;
192+
193+
#[test]
194+
fn truncate_leaves_short_text_unchanged() {
195+
assert_eq!(truncate("short", 100), "short");
196+
}
197+
198+
#[test]
199+
fn truncate_ascii_text() {
200+
assert_eq!(truncate("hello world", 5), "hello...");
201+
}
202+
203+
#[test]
204+
fn truncate_multibyte_text_on_char_boundary() {
205+
assert_eq!(
206+
truncate(
207+
"\u{65e5}\u{672c}\u{8a9e}\u{30d5}\u{30a1}\u{30a4}\u{30eb}",
208+
10
209+
),
210+
"\u{65e5}\u{672c}\u{8a9e}..."
211+
);
212+
}
213+
214+
#[test]
215+
fn truncate_multibyte_text_before_first_char_boundary() {
216+
assert_eq!(truncate("\u{65e5}\u{672c}\u{8a9e}", 1), "...");
217+
}
218+
219+
#[test]
220+
fn truncate_emoji_text_on_char_boundary() {
221+
assert_eq!(truncate("abcd\u{1f600}efgh", 6), "abcd...");
222+
}
223+
}

0 commit comments

Comments
 (0)