cersei_compression/
ansi.rs1use once_cell::sync::Lazy;
7use regex::Regex;
8
9static ANSI_RE: Lazy<Regex> = Lazy::new(|| {
10 Regex::new(r"\x1b\[[0-9;?]*[a-zA-Z]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)").unwrap()
12});
13
14pub fn strip_ansi(text: &str) -> String {
15 ANSI_RE.replace_all(text, "").into_owned()
16}
17
18pub fn truncate(s: &str, max_len: usize) -> String {
21 let char_count = s.chars().count();
22 if char_count <= max_len {
23 s.to_string()
24 } else if max_len < 3 {
25 "...".to_string()
26 } else {
27 format!("{}...", s.chars().take(max_len - 3).collect::<String>())
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn strip_ansi_basic() {
37 assert_eq!(strip_ansi("\x1b[31mError\x1b[0m"), "Error");
38 assert_eq!(strip_ansi("plain"), "plain");
39 assert_eq!(strip_ansi("\x1b[1m\x1b[32mOK\x1b[0m\x1b[0m"), "OK");
40 }
41
42 #[test]
43 fn truncate_unicode() {
44 assert_eq!(truncate("hello world", 8), "hello...");
45 assert_eq!(truncate("hi", 10), "hi");
46 assert_eq!(truncate("abc", 3), "abc");
47 assert_eq!(truncate("hello world", 3), "...");
48 assert_eq!(truncate("สวัสดีครับ", 5).chars().count(), 5);
50 }
51}