xmtp_common/
fmt.rs

1/// print bytes as a truncated hex string
2pub fn debug_hex(bytes: impl AsRef<[u8]>) -> String {
3    truncate_hex(hex::encode(bytes.as_ref()))
4}
5
6pub fn truncate_hex(hex_string: impl AsRef<str>) -> String {
7    let hex_string = hex_string.as_ref();
8    // If empty string, return it
9    if hex_string.is_empty() {
10        return String::new();
11    }
12
13    let hex_value = if let Some(hex_value) = hex_string.strip_prefix("0x") {
14        hex_value
15    } else {
16        hex_string
17    };
18
19    // If the hex value is 8 or fewer chars, return original string
20    if hex_value.len() <= 8 {
21        return hex_string.to_string();
22    }
23
24    format!(
25        "0x{}...{}",
26        &hex_value[..4],
27        &hex_value[hex_value.len() - 4..]
28    )
29}
30
31const SHORT_LEN: usize = 4;
32
33pub trait ShortHex {
34    fn short_hex(&self) -> String;
35}
36impl ShortHex for Vec<u8> {
37    fn short_hex(&self) -> String {
38        self.as_slice().short_hex()
39    }
40}
41impl ShortHex for &[u8] {
42    fn short_hex(&self) -> String {
43        hex::encode(&self[self.len().saturating_sub(SHORT_LEN)..])
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn test_long_hex() {
53        assert_eq!(
54            truncate_hex("0x5bf078bd83995fe83092d93c5655f059"),
55            "0x5bf0...f059"
56        );
57    }
58
59    #[test]
60    fn test_short_hex() {
61        let hex = "5bf078bd83995fe83092d93c5655f059";
62        let bytes = hex::decode(hex).unwrap();
63        let short_hex = bytes.short_hex();
64
65        assert_eq!(short_hex.len(), SHORT_LEN * 2);
66        assert_eq!(hex[(hex.len() - short_hex.len())..], short_hex);
67    }
68}