1use umsh_core::{ChannelId, ChannelKey, PublicKey};
2use umsh_mac::{
3 CapacityError, LocalIdentityId, MacHandle, MacHandleError, PeerId, Platform, SendError,
4 SendOptions, SendReceipt,
5};
6
7pub trait MacBackend: Clone {
12 type SendError;
14 type CapacityError;
16
17 fn add_peer(
19 &self,
20 key: PublicKey,
21 ) -> Result<PeerId, MacBackendError<Self::SendError, Self::CapacityError>>;
22 fn add_private_channel(
24 &self,
25 key: ChannelKey,
26 ) -> Result<(), MacBackendError<Self::SendError, Self::CapacityError>>;
27 fn add_named_channel(
29 &self,
30 name: &str,
31 ) -> Result<(), MacBackendError<Self::SendError, Self::CapacityError>>;
32 async fn send_broadcast(
34 &self,
35 from: LocalIdentityId,
36 payload: &[u8],
37 options: &SendOptions,
38 ) -> Result<SendReceipt, MacBackendError<Self::SendError, Self::CapacityError>>;
39 async fn send_multicast(
41 &self,
42 from: LocalIdentityId,
43 channel: &ChannelId,
44 payload: &[u8],
45 options: &SendOptions,
46 ) -> Result<SendReceipt, MacBackendError<Self::SendError, Self::CapacityError>>;
47 async fn send_unicast(
49 &self,
50 from: LocalIdentityId,
51 dst: &PublicKey,
52 payload: &[u8],
53 options: &SendOptions,
54 ) -> Result<Option<SendReceipt>, MacBackendError<Self::SendError, Self::CapacityError>>;
55 async fn send_blind_unicast(
57 &self,
58 from: LocalIdentityId,
59 dst: &PublicKey,
60 channel: &ChannelId,
61 payload: &[u8],
62 options: &SendOptions,
63 ) -> Result<Option<SendReceipt>, MacBackendError<Self::SendError, Self::CapacityError>>;
64 fn fill_random(
66 &self,
67 dest: &mut [u8],
68 ) -> Result<(), MacBackendError<Self::SendError, Self::CapacityError>>;
69 fn now_ms(&self) -> Result<u64, MacBackendError<Self::SendError, Self::CapacityError>>;
71
72 #[cfg(feature = "software-crypto")]
73 fn register_ephemeral(
74 &self,
75 parent: LocalIdentityId,
76 identity: umsh_crypto::software::SoftwareIdentity,
77 ) -> Result<LocalIdentityId, MacBackendError<Self::SendError, Self::CapacityError>>;
78
79 #[cfg(feature = "software-crypto")]
80 fn remove_ephemeral(
81 &self,
82 id: LocalIdentityId,
83 ) -> Result<bool, MacBackendError<Self::SendError, Self::CapacityError>>;
84}
85
86#[derive(Clone, Debug, PartialEq, Eq)]
88pub enum MacBackendError<S, C> {
89 Busy,
91 Send(S),
93 Capacity(C),
95}
96
97impl<S, C> MacBackendError<S, C> {
98 fn from_send_error(error: MacHandleError<S>) -> Self {
99 match error {
100 MacHandleError::Busy => Self::Busy,
101 MacHandleError::Inner(inner) => Self::Send(inner),
102 }
103 }
104
105 fn from_capacity_error(error: MacHandleError<C>) -> Self {
106 match error {
107 MacHandleError::Busy => Self::Busy,
108 MacHandleError::Inner(inner) => Self::Capacity(inner),
109 }
110 }
111
112 fn from_infallible_error(error: MacHandleError<core::convert::Infallible>) -> Self {
113 match error {
114 MacHandleError::Busy => Self::Busy,
115 MacHandleError::Inner(inner) => match inner {},
116 }
117 }
118}
119
120impl<
121 'a,
122 P: Platform,
123 const IDENTITIES: usize,
124 const PEERS: usize,
125 const CHANNELS: usize,
126 const ACKS: usize,
127 const TX: usize,
128 const FRAME: usize,
129 const DUP: usize,
130> MacBackend for MacHandle<'a, P, IDENTITIES, PEERS, CHANNELS, ACKS, TX, FRAME, DUP>
131{
132 type SendError = SendError;
133 type CapacityError = CapacityError;
134
135 fn add_peer(
136 &self,
137 key: PublicKey,
138 ) -> Result<PeerId, MacBackendError<Self::SendError, Self::CapacityError>> {
139 self.add_peer(key)
140 .map_err(MacBackendError::from_capacity_error)
141 }
142
143 fn add_private_channel(
144 &self,
145 key: ChannelKey,
146 ) -> Result<(), MacBackendError<Self::SendError, Self::CapacityError>> {
147 self.add_channel(key)
148 .map_err(MacBackendError::from_capacity_error)
149 }
150
151 fn add_named_channel(
152 &self,
153 name: &str,
154 ) -> Result<(), MacBackendError<Self::SendError, Self::CapacityError>> {
155 self.add_named_channel(name)
156 .map_err(MacBackendError::from_capacity_error)
157 }
158
159 async fn send_broadcast(
160 &self,
161 from: LocalIdentityId,
162 payload: &[u8],
163 options: &SendOptions,
164 ) -> Result<SendReceipt, MacBackendError<Self::SendError, Self::CapacityError>> {
165 self.send_broadcast(from, payload, options)
166 .await
167 .map_err(MacBackendError::from_send_error)
168 }
169
170 async fn send_multicast(
171 &self,
172 from: LocalIdentityId,
173 channel: &ChannelId,
174 payload: &[u8],
175 options: &SendOptions,
176 ) -> Result<SendReceipt, MacBackendError<Self::SendError, Self::CapacityError>> {
177 self.send_multicast(from, channel, payload, options)
178 .await
179 .map_err(MacBackendError::from_send_error)
180 }
181
182 async fn send_unicast(
183 &self,
184 from: LocalIdentityId,
185 dst: &PublicKey,
186 payload: &[u8],
187 options: &SendOptions,
188 ) -> Result<Option<SendReceipt>, MacBackendError<Self::SendError, Self::CapacityError>> {
189 self.send_unicast(from, dst, payload, options)
190 .await
191 .map_err(MacBackendError::from_send_error)
192 }
193
194 async fn send_blind_unicast(
195 &self,
196 from: LocalIdentityId,
197 dst: &PublicKey,
198 channel: &ChannelId,
199 payload: &[u8],
200 options: &SendOptions,
201 ) -> Result<Option<SendReceipt>, MacBackendError<Self::SendError, Self::CapacityError>> {
202 self.send_blind_unicast(from, dst, channel, payload, options)
203 .await
204 .map_err(MacBackendError::from_send_error)
205 }
206
207 fn fill_random(
208 &self,
209 dest: &mut [u8],
210 ) -> Result<(), MacBackendError<Self::SendError, Self::CapacityError>> {
211 self.fill_random(dest)
212 .map_err(MacBackendError::from_infallible_error)
213 }
214
215 fn now_ms(&self) -> Result<u64, MacBackendError<Self::SendError, Self::CapacityError>> {
216 self.now_ms()
217 .map_err(MacBackendError::from_infallible_error)
218 }
219
220 #[cfg(feature = "software-crypto")]
221 fn register_ephemeral(
222 &self,
223 parent: LocalIdentityId,
224 identity: umsh_crypto::software::SoftwareIdentity,
225 ) -> Result<LocalIdentityId, MacBackendError<Self::SendError, Self::CapacityError>> {
226 self.register_ephemeral(parent, identity)
227 .map_err(MacBackendError::from_capacity_error)
228 }
229
230 #[cfg(feature = "software-crypto")]
231 fn remove_ephemeral(
232 &self,
233 id: LocalIdentityId,
234 ) -> Result<bool, MacBackendError<Self::SendError, Self::CapacityError>> {
235 self.remove_ephemeral(id)
236 .map_err(MacBackendError::from_infallible_error)
237 }
238}