Skip to main content

tuwunel_service/sending/
dest.rs

1use std::fmt::Debug;
2
3use ruma::{OwnedServerName, OwnedUserId, ServerName, UserId};
4use tuwunel_core::{implement, matrix::pdu::RawPduId};
5
6#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub enum Destination {
8	Appservice(String),
9	Push(OwnedUserId, String), // user and pushkey
10	Federation(OwnedServerName),
11}
12
13/// A borrowed destination with the same hash representation as its owned form.
14///
15/// Variant order and payload hashing preserve sender shard ownership.
16#[derive(Hash)]
17pub(super) enum DestinationRef<'a> {
18	/// An appservice registration identifier.
19	Appservice(&'a str),
20
21	/// A user and pusher key.
22	Push(&'a UserId, &'a str),
23
24	/// A federation peer.
25	Federation(&'a ServerName),
26}
27
28#[implement(Destination)]
29#[inline]
30pub(super) fn borrowed(&self) -> DestinationRef<'_> {
31	match self {
32		| Self::Appservice(id) => DestinationRef::Appservice(id),
33		| Self::Push(user, key) => DestinationRef::Push(user, key),
34		| Self::Federation(server) => DestinationRef::Federation(server),
35	}
36}
37
38#[implement(Destination)]
39#[inline]
40#[must_use]
41pub(super) fn event_key(&self, pdu_id: &RawPduId) -> Vec<u8> {
42	self.suffixed_key(pdu_id.as_ref())
43}
44
45#[implement(Destination)]
46#[inline]
47#[must_use]
48pub(super) fn count_key(&self, count: u64) -> Vec<u8> { self.suffixed_key(&count.to_be_bytes()) }
49
50#[implement(Destination)]
51#[must_use]
52fn suffixed_key(&self, suffix: &[u8]) -> Vec<u8> {
53	let mut key = self.get_prefix_with_capacity(suffix.len());
54
55	key.extend_from_slice(suffix);
56	key
57}
58
59#[implement(Destination)]
60#[inline]
61#[must_use]
62pub(super) fn get_prefix(&self) -> Vec<u8> { self.get_prefix_with_capacity(0) }
63
64#[implement(Destination)]
65#[must_use]
66pub(super) fn get_prefix_with_capacity(&self, additional: usize) -> Vec<u8> {
67	match self {
68		| Self::Federation(server) => {
69			let len = server
70				.as_bytes()
71				.len()
72				.saturating_add(1)
73				.saturating_add(additional);
74
75			let mut p = Vec::with_capacity(len);
76			p.extend_from_slice(server.as_bytes());
77			p.push(0xFF);
78			p
79		},
80		| Self::Appservice(server) => {
81			let sigil = b"+";
82			let len = sigil
83				.len()
84				.saturating_add(server.len())
85				.saturating_add(1)
86				.saturating_add(additional);
87
88			let mut p = Vec::with_capacity(len);
89			p.extend_from_slice(sigil);
90			p.extend_from_slice(server.as_bytes());
91			p.push(0xFF);
92			p
93		},
94		| Self::Push(user, pushkey) => {
95			let sigil = b"$";
96			let len = sigil
97				.len()
98				.saturating_add(user.as_bytes().len())
99				.saturating_add(1)
100				.saturating_add(pushkey.len())
101				.saturating_add(1)
102				.saturating_add(additional);
103
104			let mut p = Vec::with_capacity(len);
105			p.extend_from_slice(sigil);
106			p.extend_from_slice(user.as_bytes());
107			p.push(0xFF);
108			p.extend_from_slice(pushkey.as_bytes());
109			p.push(0xFF);
110			p
111		},
112	}
113}