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