1pub fn truncate_str(s: &str, max: usize) -> String {
17 if s.len() <= max {
18 s.to_string()
19 } else {
20 let target = max.saturating_sub(3);
21 let mut end = target;
22 while end > 0 && !s.is_char_boundary(end) {
23 end -= 1;
24 }
25 format!("{}...", &s[..end])
26 }
27}
28
29pub fn truncate_path(s: &str, max: usize) -> String {
41 if s.len() <= max {
42 s.to_string()
43 } else {
44 let target = s.len() - max + 3;
45 let mut start = target;
46 while start < s.len() && !s.is_char_boundary(start) {
47 start += 1;
48 }
49 format!("...{}", &s[start..])
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn test_truncate_str_ascii() {
59 assert_eq!(truncate_str("hello", 10), "hello");
61 assert_eq!(truncate_str("hello", 5), "hello");
62
63 assert_eq!(truncate_str("hello world", 8), "hello...");
65 assert_eq!(truncate_str("abcdefghij", 7), "abcd...");
66 }
67
68 #[test]
69 fn test_truncate_str_unicode() {
70 let box_line = "┌────────────────────┐";
72 let result = truncate_str(box_line, 10);
73 assert!(result.ends_with("..."));
74 let emoji = "Hello 🎉🎊🎁 World";
78 let result = truncate_str(emoji, 10);
79 assert!(result.ends_with("..."));
80
81 let chinese = "你好世界测试";
83 let result = truncate_str(chinese, 8);
84 assert!(result.ends_with("..."));
85 }
86
87 #[test]
88 fn test_truncate_path_ascii() {
89 assert_eq!(truncate_path("src/main.rs", 20), "src/main.rs");
91
92 let result = truncate_path("/very/long/path/to/file.rs", 15);
94 assert!(result.starts_with("..."));
95 assert!(result.contains("file.rs"));
96 }
97
98 #[test]
99 fn test_truncate_path_unicode() {
100 let path = "/home/用户/项目/文件.rs";
102 let result = truncate_path(path, 15);
103 assert!(result.starts_with("..."));
104 let path = "/home/📁/🎉/file.rs";
108 let result = truncate_path(path, 12);
109 assert!(result.starts_with("..."));
110 }
111
112 #[test]
113 fn test_truncate_edge_cases() {
114 assert_eq!(truncate_str("hello", 3), "...");
116 assert_eq!(truncate_str("hi", 3), "hi");
117
118 assert_eq!(truncate_str("", 10), "");
120 assert_eq!(truncate_path("", 10), "");
121 }
122}