xmtp_proto/types/ids/
group_id.rs1use std::{fmt, ops::Deref, str::FromStr};
2
3use bytes::Bytes;
4use hex::FromHexError;
5
6#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
7pub struct GroupId(bytes::Bytes);
8
9impl GroupId {
10 pub fn as_slice(&self) -> &[u8] {
11 self.0.as_ref()
12 }
13}
14
15impl fmt::Debug for GroupId {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 f.debug_tuple("GroupId")
18 .field(&xmtp_common::fmt::debug_hex(&self.0))
19 .finish()
20 }
21}
22
23impl FromStr for GroupId {
24 type Err = FromHexError;
25
26 fn from_str(s: &str) -> Result<Self, Self::Err> {
27 Ok(GroupId(Bytes::from(hex::decode(s)?)))
28 }
29}
30
31impl AsRef<[u8]> for GroupId {
32 fn as_ref(&self) -> &[u8] {
33 &self.0
34 }
35}
36
37impl fmt::Display for GroupId {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 write!(f, "{:x}", self.0)
40 }
41}
42
43impl Deref for GroupId {
44 type Target = bytes::Bytes;
45 fn deref(&self) -> &Self::Target {
46 &self.0
47 }
48}
49
50impl std::borrow::Borrow<[u8]> for GroupId {
51 fn borrow(&self) -> &[u8] {
52 self.0.as_ref()
53 }
54}
55
56impl From<Vec<u8>> for GroupId {
57 fn from(v: Vec<u8>) -> GroupId {
58 GroupId(v.into())
59 }
60}
61
62impl From<&[u8]> for GroupId {
63 fn from(v: &[u8]) -> GroupId {
64 GroupId(v.to_vec().into())
65 }
66}
67
68xmtp_common::if_test! {
69 impl xmtp_common::Generate for GroupId {
70 fn generate() -> Self {
71 GroupId(xmtp_common::rand_vec::<16>().into())
72 }
73 }
74}
75
76#[cfg(test)]
77mod test {
78 use rstest::rstest;
79
80 use super::*;
81
82 #[xmtp_common::test]
83 fn test_fromstr() {
84 let hex = hex::encode(xmtp_common::rand_vec::<16>());
85 let id: GroupId = hex.parse().unwrap();
86 assert_eq!(hex::encode(&id.0), hex);
87 }
88
89 #[rstest]
90 #[case(b"test_group".to_vec())]
91 #[case(vec![1, 2, 3, 4, 5])]
92 #[case(Vec::new())]
93 #[xmtp_common::test]
94 async fn test_group_id_from_vec(#[case] input: Vec<u8>) {
95 assert_eq!(GroupId::from(input.clone()).as_slice(), input.as_slice());
96 assert_eq!(GroupId::from(input.clone()).as_ref(), input.as_slice());
97 }
98
99 #[rstest]
100 #[case(b"test")]
101 #[case(b"")]
102 #[case(b"longer_test_data")]
103 #[xmtp_common::test]
104 async fn test_group_id_from_slice(#[case] input: &[u8]) {
105 assert_eq!(GroupId::from(input).as_slice(), input);
106 }
107
108 #[xmtp_common::test]
109 fn test_group_id_display_debug() {
110 let data = vec![0x12, 0x34, 0xab, 0xcd];
111 assert!(format!("{}", GroupId::from(data.clone())).contains("1234abcd"));
112 assert!(format!("{:?}", GroupId::from(data)).contains("GroupId"));
113 }
114}