xmtp_api_d14n/protocol/traits/
envelope_collection.rs1use xmtp_common::{MaybeSend, MaybeSync};
3use xmtp_proto::types::{Cursor, OrphanedEnvelope};
4
5use super::*;
6
7pub trait EnvelopeCollection<'env>: MaybeSend + MaybeSync {
11 fn topics(&self) -> Result<Vec<Topic>, EnvelopeError>;
13 fn cursors(&self) -> Result<Vec<Cursor>, EnvelopeError>;
15 fn payloads(&self) -> Result<Vec<Payload>, EnvelopeError>;
17 fn orphans(&self) -> Result<Vec<OrphanedEnvelope>, EnvelopeError>;
19 fn sha256_hashes(&self) -> Result<Vec<Vec<u8>>, EnvelopeError>;
21 fn client_envelopes(&self) -> Result<Vec<ClientEnvelope>, EnvelopeError>;
23 fn group_messages(&self) -> Result<Vec<Option<GroupMessage>>, EnvelopeError>;
25 fn welcome_messages(&self) -> Result<Vec<Option<WelcomeMessage>>, EnvelopeError>;
27 fn len(&self) -> usize;
29 fn is_empty(&self) -> bool;
31 fn consume<E>(self) -> Result<Vec<<E as Extractor>::Output>, EnvelopeError>
33 where
34 for<'a> E: Default + Extractor + EnvelopeVisitor<'a>,
35 for<'a> EnvelopeError: From<<E as EnvelopeVisitor<'a>>::Error>,
36 Self: Sized;
37}
38
39impl<'env, T> EnvelopeCollection<'env> for Vec<T>
40where
41 T: ProtocolEnvelope<'env> + std::fmt::Debug + MaybeSend + MaybeSync,
42{
43 fn topics(&self) -> Result<Vec<Topic>, EnvelopeError> {
44 self.iter()
45 .map(|t| t.topic())
46 .collect::<Result<Vec<Topic>, _>>()
47 }
48
49 fn cursors(&self) -> Result<Vec<Cursor>, EnvelopeError> {
50 self.iter()
51 .map(|t| t.cursor())
52 .collect::<Result<Vec<Cursor>, _>>()
53 }
54
55 fn orphans(&self) -> Result<Vec<OrphanedEnvelope>, EnvelopeError> {
56 self.iter().map(|t| t.orphan()).collect::<Result<_, _>>()
57 }
58
59 fn payloads(&self) -> Result<Vec<Payload>, EnvelopeError> {
60 self.iter()
61 .map(|t| t.payload())
62 .collect::<Result<Vec<Payload>, _>>()
63 }
64
65 fn sha256_hashes(&self) -> Result<Vec<Vec<u8>>, EnvelopeError> {
66 self.iter()
67 .map(|t| t.sha256_hash())
68 .collect::<Result<Vec<Vec<u8>>, _>>()
69 }
70
71 fn client_envelopes(&self) -> Result<Vec<ClientEnvelope>, EnvelopeError> {
72 self.iter()
73 .map(|t| t.client_envelope())
74 .collect::<Result<Vec<ClientEnvelope>, EnvelopeError>>()
75 }
76
77 fn group_messages(&self) -> Result<Vec<Option<GroupMessage>>, EnvelopeError> {
78 self.iter()
79 .map(|t| t.group_message())
80 .collect::<Result<Vec<Option<GroupMessage>>, EnvelopeError>>()
81 }
82
83 fn welcome_messages(&self) -> Result<Vec<Option<WelcomeMessage>>, EnvelopeError> {
84 self.iter()
85 .map(|t| t.welcome_message())
86 .collect::<Result<Vec<Option<WelcomeMessage>>, EnvelopeError>>()
87 }
88
89 fn len(&self) -> usize {
90 Vec::len(self)
91 }
92
93 fn is_empty(&self) -> bool {
94 Vec::is_empty(self)
95 }
96
97 fn consume<E>(self) -> Result<Vec<<E as Extractor>::Output>, EnvelopeError>
98 where
99 for<'a> E: Default + Extractor + EnvelopeVisitor<'a>,
100 for<'a> EnvelopeError: From<<E as EnvelopeVisitor<'a>>::Error>,
101 Self: Sized,
102 {
103 SequencedExtractor::builder()
104 .envelopes(self)
105 .build::<E>()
106 .get()
107 }
108}
109
110pub trait TryEnvelopeCollectionExt<'env>: EnvelopeCollection<'env> {
112 #[allow(clippy::type_complexity)]
115 fn try_consume<E>(
116 self,
117 ) -> Result<
118 (
119 Vec<<E as TryExtractor>::Ok>,
120 Vec<<E as TryExtractor>::Error>,
121 ),
122 EnvelopeError,
123 >
124 where
125 for<'a> E: TryExtractor,
126 for<'a> E: Default + EnvelopeVisitor<'a>,
127 for<'a> EnvelopeError: From<<E as EnvelopeVisitor<'a>>::Error>,
128 EnvelopeError: From<<E as TryExtractor>::Error>,
129 Self: Sized,
130 {
131 let (success, failure): (Vec<_>, Vec<_>) =
132 self.consume::<E>()?.into_iter().partition_result();
133 Ok((success, failure))
134 }
135}
136
137impl<'env, T> TryEnvelopeCollectionExt<'env> for T where T: EnvelopeCollection<'env> {}