1pub const ELLIPSIS: &str = "…";
8
9const HEAD_CHARS: usize = 6;
11
12const TAIL_CHARS: usize = 4;
14
15pub fn abbreviate(id: &str) -> String {
19 let chars: Vec<char> = id.chars().collect();
20 if chars.len() <= HEAD_CHARS + TAIL_CHARS + 1 {
21 return id.to_string();
22 }
23 let head: String = chars[..HEAD_CHARS].iter().collect();
24 let tail: String = chars[chars.len() - TAIL_CHARS..].iter().collect();
25 format!("{head}{ELLIPSIS}{tail}")
26}
27
28#[cfg(test)]
29mod tests {
30 use super::*;
31
32 #[test]
33 fn test_abbreviate_keeps_head_and_tail() {
34 assert_eq!(
35 abbreviate("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
36 "0xA0b8…eB48"
37 );
38 }
39
40 #[test]
41 fn test_short_ids_stay_whole() {
42 assert_eq!(abbreviate(""), "");
43 assert_eq!(abbreviate("0x12345678a"), "0x12345678a");
44 assert_eq!(abbreviate("0x12345678ab"), "0x1234…78ab");
45 }
46
47 #[test]
48 fn test_non_ascii_ids_do_not_panic() {
49 assert_eq!(abbreviate("ünïcødé-ädrèss-ñame"), "ünïcød…ñame");
51 assert_eq!(
52 abbreviate("日本語のアドレス文字列です"),
53 "日本語のアド…字列です"
54 );
55 }
56}