xmtp_api_d14n/protocol/traits/
envelopes.rs1use chrono::Utc;
3use xmtp_common::{MaybeSend, MaybeSync};
4use xmtp_proto::types::{Cursor, OrphanedEnvelope};
5
6use crate::protocol::{
7 BytesExtractor, CursorExtractor, DependsOnExtractor, MlsDataExtractor, OrphanExtractor,
8 TimestampExtractor,
9};
10
11use super::*;
12pub trait ProtocolEnvelope<'env>: std::fmt::Debug + MaybeSend + MaybeSync {
21 type Nested<'a>
22 where
23 Self: 'a;
24 fn accept<V: EnvelopeVisitor<'env>>(&self, visitor: &mut V) -> Result<(), EnvelopeError>
25 where
26 EnvelopeError: From<<V as EnvelopeVisitor<'env>>::Error>;
27 fn get_nested(&self) -> Result<Self::Nested<'_>, ConversionError>;
28}
29
30pub trait Envelope<'env>: std::fmt::Debug + MaybeSend + MaybeSync {
43 fn bytes(&self) -> Result<Vec<u8>, EnvelopeError>;
45 fn orphan(&self) -> Result<OrphanedEnvelope, EnvelopeError>;
47 fn topic(&self) -> Result<Topic, EnvelopeError>;
49 fn cursor(&self) -> Result<Cursor, EnvelopeError>;
51 fn depends_on(&self) -> Result<Option<GlobalCursor>, EnvelopeError>;
53 fn payload(&self) -> Result<Payload, EnvelopeError>;
55 fn sha256_hash(&self) -> Result<Vec<u8>, EnvelopeError>;
57 fn timestamp(&self) -> Option<chrono::DateTime<Utc>>;
59 fn client_envelope(&self) -> Result<ClientEnvelope, EnvelopeError>;
62 fn group_message(&self) -> Result<Option<GroupMessage>, EnvelopeError>;
64 fn welcome_message(&self) -> Result<Option<WelcomeMessage>, EnvelopeError>;
66}
67
68impl<'env, T> Envelope<'env> for T
71where
72 T: ProtocolEnvelope<'env>,
73{
74 fn bytes(&self) -> Result<Vec<u8>, EnvelopeError> {
75 let mut extractor = BytesExtractor::new();
76 self.accept(&mut extractor)?;
77 Ok(extractor.get())
78 }
79
80 fn orphan(&self) -> Result<OrphanedEnvelope, EnvelopeError> {
81 let mut extractor = OrphanExtractor::default();
82 self.accept(&mut extractor)?;
83 Ok(extractor.get()?)
84 }
85
86 fn topic(&self) -> Result<Topic, EnvelopeError> {
87 let mut extractor = TopicExtractor::new();
88 self.accept(&mut extractor)?;
89 Ok(extractor.get()?)
90 }
91
92 fn cursor(&self) -> Result<Cursor, EnvelopeError> {
93 let mut extractor = CursorExtractor::new();
94 self.accept(&mut extractor)?;
95 Ok(extractor.get()?)
96 }
97
98 fn depends_on(&self) -> Result<Option<GlobalCursor>, EnvelopeError> {
99 let mut extractor = DependsOnExtractor::default();
100 self.accept(&mut extractor)?;
101 Ok(extractor.get())
102 }
103
104 fn payload(&self) -> Result<Payload, EnvelopeError> {
105 let mut extractor = PayloadExtractor::new();
106 self.accept(&mut extractor)?;
107 Ok(extractor.get()?)
108 }
109
110 fn sha256_hash(&self) -> Result<Vec<u8>, EnvelopeError> {
111 let mut extractor = MlsDataExtractor::new();
112 self.accept(&mut extractor)?;
113 Ok(extractor.get_sha256()?)
114 }
115
116 fn timestamp(&self) -> Option<chrono::DateTime<Utc>> {
122 let mut extractor = TimestampExtractor::default();
123 self.accept(&mut extractor).ok()?;
124 extractor.maybe_get()
125 }
126
127 fn client_envelope(&self) -> Result<ClientEnvelope, EnvelopeError> {
128 let mut extractor = (
130 TopicExtractor::new(),
131 PayloadExtractor::new(),
132 DependsOnExtractor::default(),
133 );
134 self.accept(&mut extractor)?;
135 let topic = extractor.0.get().map_err(ExtractionError::from)?;
136 let payload = extractor.1.get().map_err(ExtractionError::from)?;
137 let depends_on = extractor.2.get();
138 Ok(ClientEnvelope {
139 aad: Some(AuthenticatedData {
140 target_topic: topic.into(),
141 depends_on: depends_on.map(Into::into),
142 }),
143 payload: Some(payload),
144 })
145 }
146
147 fn group_message(&self) -> Result<Option<GroupMessage>, EnvelopeError> {
148 let mut extractor = (
149 V3GroupMessageExtractor::default(),
150 GroupMessageExtractor::default(),
151 );
152 self.accept(&mut extractor)?;
153 if let Ok(Some(v3)) = extractor.0.get() {
154 return Ok(Some(v3));
155 }
156
157 match extractor.1.get() {
158 Ok(v) => return Ok(Some(v)),
159 Err(ExtractionError::Conversion(ConversionError::Missing { .. })) => (),
160 Err(e) => return Err(e.into()),
161 }
162
163 Ok(None)
164 }
165
166 fn welcome_message(&self) -> Result<Option<WelcomeMessage>, EnvelopeError> {
167 let mut extractor = (
168 V3WelcomeMessageExtractor::default(),
169 WelcomeMessageExtractor::default(),
170 );
171 self.accept(&mut extractor)?;
172 match extractor.0.get() {
173 Ok(v) => return Ok(Some(v)),
174 Err(ConversionError::Builder(_)) | Err(ConversionError::Missing { .. }) => (),
175 Err(e) => return Err(e.into()),
176 }
177
178 match extractor.1.get() {
179 Ok(v) => return Ok(Some(v)),
180 Err(ExtractionError::Conversion(ConversionError::Builder(_)))
181 | Err(ExtractionError::Conversion(ConversionError::Missing { .. })) => (),
182 Err(e) => return Err(e.into()),
183 }
184
185 Ok(None)
186 }
187}
188
189impl<'env, T> ProtocolEnvelope<'env> for &T
190where
191 T: ProtocolEnvelope<'env>,
192{
193 type Nested<'a>
194 = <T as ProtocolEnvelope<'env>>::Nested<'a>
195 where
196 Self: 'a;
197
198 fn accept<V: EnvelopeVisitor<'env>>(&self, visitor: &mut V) -> Result<(), EnvelopeError>
199 where
200 EnvelopeError: From<<V as EnvelopeVisitor<'env>>::Error>,
201 {
202 <T as ProtocolEnvelope<'env>>::accept(self, visitor)
203 }
204
205 fn get_nested(&self) -> Result<Self::Nested<'_>, ConversionError> {
206 <T as ProtocolEnvelope<'env>>::get_nested(self)
207 }
208}