xmtp_proto/types/
group_message.rs1use super::{Cursor, GroupId};
2use crate::ConversionError;
3use chrono::Utc;
4use derive_builder::Builder;
5use openmls::prelude::ContentType;
6
7#[derive(Clone, Builder, Debug)]
9#[builder(setter(into), build_fn(error = "ConversionError"), derive(Debug))]
10pub struct GroupMessage {
11 pub cursor: Cursor,
13 pub created_ns: chrono::DateTime<Utc>,
15 pub group_id: GroupId,
17 pub message: openmls::framing::ProtocolMessage,
19 pub sender_hmac: Vec<u8>,
21 pub should_push: bool,
23 pub payload_hash: Vec<u8>,
26 #[builder(default)]
27 pub envelope_hash: Option<Vec<u8>>,
28 #[builder(default)]
29 pub expiry_ns: Option<u64>,
30}
31
32impl GroupMessage {
33 pub fn builder() -> GroupMessageBuilder {
34 GroupMessageBuilder::default()
35 }
36
37 pub fn is_commit(&self) -> bool {
38 self.message.content_type() == ContentType::Commit
39 }
40
41 pub fn timestamp(&self) -> i64 {
42 self.created_ns
43 .timestamp_nanos_opt()
44 .expect("timestamp out of range for i64, are we in 2262 A.D?")
45 }
46
47 pub fn sequence_id(&self) -> u64 {
48 self.cursor.0
49 }
50}
51
52#[cfg(any(test, feature = "test-utils"))]
53impl xmtp_common::Generate for GroupMessage {
54 fn generate() -> Self {
55 GroupMessage {
56 cursor: Default::default(),
57 created_ns: chrono::DateTime::from_timestamp_nanos(xmtp_common::rand_i64()),
58 group_id: GroupId::generate(),
59 message: openmls::prelude::PublicMessage::generate().into(),
60 sender_hmac: xmtp_common::rand_vec::<2>(),
61 should_push: true,
62 payload_hash: xmtp_common::rand_vec::<32>(),
63 envelope_hash: None,
64 expiry_ns: None,
65 }
66 }
67}
68
69impl std::fmt::Display for GroupMessage {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 let s = format!(
72 "GroupMessage {{ cursor {}, created at {:10}, group {:16} }}",
73 self.cursor,
74 self.created_ns.time().format("%H:%M:%S%.6f").to_string(),
75 self.group_id
76 );
77 write!(f, "{}", s)
78 }
79}
80
81#[cfg(test)]
82mod test {
83 use openmls::prelude::ContentType;
84 use xmtp_common::Generate;
85
86 use super::*;
87
88 #[xmtp_common::test]
89 fn test_is_commit() {
90 let group_message = GroupMessage::generate();
91 assert_eq!(
92 group_message.is_commit(),
93 group_message.message.content_type() == ContentType::Commit
94 );
95 }
96
97 #[xmtp_common::test]
98 fn test_timestamp() {
99 let test_time = chrono::Utc::now();
100 let mut group_message = GroupMessage::generate();
101 group_message.created_ns = test_time;
102 assert_eq!(
103 group_message.timestamp(),
104 test_time.timestamp_nanos_opt().unwrap()
105 );
106 }
107}