xmtp_common/
snippet.rs

1/// Length for snippet truncation
2pub const SNIPPET_LENGTH: usize = 6;
3
4/// Trait for creating short, truncated representations of values for display/debugging
5pub trait Snippet {
6    /// Returns a short, truncated representation of the value
7    fn snippet(&self) -> String;
8}
9
10impl Snippet for str {
11    fn snippet(&self) -> String {
12        if self.len() <= SNIPPET_LENGTH {
13            self.to_string()
14        } else {
15            format!("{}..", &self[..SNIPPET_LENGTH])
16        }
17    }
18}
19
20impl Snippet for [u8] {
21    fn snippet(&self) -> String {
22        let encoded = hex::encode(self);
23        if encoded.len() <= SNIPPET_LENGTH {
24            encoded
25        } else {
26            format!("{}..", &encoded[..SNIPPET_LENGTH])
27        }
28    }
29}
30
31impl Snippet for Vec<u8> {
32    fn snippet(&self) -> String {
33        self.as_slice().snippet()
34    }
35}
36
37impl Snippet for String {
38    fn snippet(&self) -> String {
39        self.as_str().snippet()
40    }
41}
42
43impl<T: Snippet> Snippet for Option<T> {
44    fn snippet(&self) -> String {
45        match self {
46            Some(value) => value.snippet(),
47            None => "".to_string(),
48        }
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn test_str_snippet() {
58        assert_eq!("hello".snippet(), "hello");
59        assert_eq!("hello world".snippet(), "hello ..");
60        assert_eq!("".snippet(), "");
61        assert_eq!("a".snippet(), "a");
62    }
63
64    #[test]
65    fn test_bytes_snippet() {
66        let short_bytes = vec![1, 2, 3];
67        let long_bytes = vec![1, 2, 3, 4, 5, 6, 7, 8];
68
69        assert_eq!(short_bytes.snippet(), "010203");
70        assert_eq!(long_bytes.snippet(), "010203..");
71        assert_eq!([].snippet(), "");
72    }
73
74    #[test]
75    fn test_string_snippet() {
76        let short_string = String::from("hello");
77        let long_string = String::from("hello world");
78
79        assert_eq!(short_string.snippet(), "hello");
80        assert_eq!(long_string.snippet(), "hello ..");
81    }
82
83    #[test]
84    fn test_option_snippet() {
85        let some_string: Option<String> = Some("hello world".to_string());
86        let none_string: Option<String> = None;
87        let some_bytes: Option<Vec<u8>> = Some(vec![1, 2, 3, 4, 5, 6, 7, 8]);
88        let none_bytes: Option<Vec<u8>> = None;
89
90        assert_eq!(some_string.snippet(), "hello ..");
91        assert_eq!(none_string.snippet(), "");
92        assert_eq!(some_bytes.snippet(), "010203..");
93        assert_eq!(none_bytes.snippet(), "");
94    }
95}