xmtp_api_d14n/protocol/traits/
sort.rs

1use xmtp_proto::types::{GlobalCursor, TopicCursor};
2
3use crate::protocol::{Envelope, EnvelopeError};
4
5// TODO: sort returns an error because going through the envelopes is
6// fallible b/c deserialization.
7// https://github.com/xmtp/libxmtp/issues/2691 solves this.
8
9/// Envelopes in a d14n-context must be sorted according to its
10/// dependencies, and by-originator.
11/// [XIP, cross-originator sorting](https://github.com/xmtp/XIPs/blob/main/XIPs/xip-49-decentralized-backend.md#335-cross-originator-message-ordering)
12pub trait Sort<Missing> {
13    /// Sort envelopes in-place
14    /// elements remaining in `Self` are guaranteed to be sorted.
15    /// The sort optionally returns `Missing` elements.
16    /// it is up to the caller to resolve any missing envelopes.
17    fn sort(self) -> Result<Option<Missing>, EnvelopeError>;
18}
19
20/// Extension trait to modify a [`TopicCursor`]
21/// with the contents of an envelope.
22pub trait ApplyCursor<E> {
23    /// applies an envelope to a cursor
24    fn apply(&mut self, envelope: &E) -> Result<(), EnvelopeError>;
25}
26
27impl<'a, E: Envelope<'a>> ApplyCursor<E> for TopicCursor {
28    fn apply(&mut self, envelope: &E) -> Result<(), EnvelopeError> {
29        let topic = envelope.topic()?;
30        let cursor = envelope.cursor()?;
31        self.entry(topic)
32            .and_modify(|global| {
33                global.apply(&cursor);
34            })
35            .or_insert_with(|| {
36                let mut map = GlobalCursor::default();
37                map.apply(&cursor);
38                map
39            });
40        Ok(())
41    }
42}