memberlist_core/transport/
stream.rs1use async_channel::{Receiver, Sender};
2pub use async_channel::{RecvError, SendError, TryRecvError, TrySendError};
3use futures::Stream;
4
5use super::*;
6
7#[viewit::viewit(
9 vis_all = "",
10 getters(vis_all = "pub", style = "ref"),
11 setters(vis_all = "pub", prefix = "with")
12)]
13#[derive(Debug, Clone, PartialEq, Eq, Hash)]
14pub struct Packet<A, T> {
15 #[viewit(
17 getter(
18 const,
19 style = "ref",
20 attrs(doc = "Returns the messages of the packet")
21 ),
22 setter(attrs(doc = "Sets the messages of the packet (Builder pattern)"))
23 )]
24 payload: Bytes,
25
26 #[viewit(
29 getter(
30 const,
31 style = "ref",
32 attrs(doc = "Returns the address sent the packet")
33 ),
34 setter(attrs(doc = "Sets the address who sent the packet (Builder pattern)"))
35 )]
36 from: A,
37
38 #[viewit(
42 getter(
43 const,
44 style = "ref",
45 attrs(doc = "Returns the instant when the packet was received")
46 ),
47 setter(attrs(doc = "Sets the instant when the packet was received (Builder pattern)"))
48 )]
49 timestamp: T,
50}
51
52impl<A, T> Packet<A, T> {
53 #[inline]
55 pub const fn new(from: A, timestamp: T, payload: Bytes) -> Self {
56 Self {
57 payload,
58 from,
59 timestamp,
60 }
61 }
62
63 #[inline]
65 pub fn into_components(self) -> (A, T, Bytes) {
66 (self.from, self.timestamp, self.payload)
67 }
68
69 #[inline]
71 pub fn set_from(&mut self, from: A) -> &mut Self {
72 self.from = from;
73 self
74 }
75
76 #[inline]
78 pub fn set_timestamp(&mut self, timestamp: T) -> &mut Self {
79 self.timestamp = timestamp;
80 self
81 }
82
83 #[inline]
85 pub fn set_payload(&mut self, payload: Bytes) -> &mut Self {
86 self.payload = payload;
87 self
88 }
89}
90
91#[derive(Debug, Clone)]
93#[repr(transparent)]
94pub struct PacketProducer<A, T> {
95 sender: Sender<Packet<A, T>>,
96}
97
98#[pin_project::pin_project]
100#[derive(Debug, Clone)]
101#[repr(transparent)]
102pub struct PacketSubscriber<A, T> {
103 #[pin]
104 receiver: Receiver<Packet<A, T>>,
105}
106
107pub fn packet_stream<T: Transport>(capacity: usize) -> (
109 PacketProducer<T::ResolvedAddress, <T::Runtime as RuntimeLite>::Instant>,
110 PacketSubscriber<T::ResolvedAddress, <T::Runtime as RuntimeLite>::Instant>,
111) {
112 let (sender, receiver) = async_channel::bounded(capacity);
113 (PacketProducer { sender }, PacketSubscriber { receiver })
114}
115
116impl<A, T> PacketProducer<A, T> {
117 pub async fn send(&self, packet: Packet<A, T>) -> Result<(), SendError<Packet<A, T>>> {
123 self.sender.send(packet).await
124 }
125
126 pub fn try_send(&self, packet: Packet<A, T>) -> Result<(), TrySendError<Packet<A, T>>> {
130 self.sender.try_send(packet)
131 }
132
133 pub fn is_empty(&self) -> bool {
135 self.sender.is_empty()
136 }
137
138 pub fn len(&self) -> usize {
140 self.sender.len()
141 }
142
143 pub fn is_full(&self) -> bool {
145 self.sender.is_full()
146 }
147
148 pub fn is_closed(&self) -> bool {
150 self.sender.is_closed()
151 }
152
153 pub fn close(&self) -> bool {
155 self.sender.close()
156 }
157}
158
159impl<A, T> PacketSubscriber<A, T> {
160 pub async fn recv(&self) -> Result<Packet<A, T>, RecvError> {
167 self.receiver.recv().await
168 }
169
170 pub fn try_recv(&self) -> Result<Packet<A, T>, TryRecvError> {
174 self.receiver.try_recv()
175 }
176
177 pub fn is_empty(&self) -> bool {
179 self.receiver.is_empty()
180 }
181
182 pub fn len(&self) -> usize {
184 self.receiver.len()
185 }
186
187 pub fn is_full(&self) -> bool {
189 self.receiver.is_full()
190 }
191
192 pub fn is_closed(&self) -> bool {
194 self.receiver.is_closed()
195 }
196
197 pub fn close(&self) -> bool {
199 self.receiver.close()
200 }
201}
202
203impl<A, T> Stream for PacketSubscriber<A, T> {
204 type Item = <Receiver<Packet<A, T>> as Stream>::Item;
205
206 fn poll_next(
207 self: std::pin::Pin<&mut Self>,
208 cx: &mut std::task::Context<'_>,
209 ) -> std::task::Poll<Option<Self::Item>> {
210 <Receiver<_> as Stream>::poll_next(self.project().receiver, cx)
211 }
212}
213
214pub fn promised_stream<T: Transport>() -> (
216 StreamProducer<T::ResolvedAddress, T::Connection>,
217 StreamSubscriber<T::ResolvedAddress, T::Connection>,
218) {
219 let (sender, receiver) = async_channel::bounded(1);
220 (StreamProducer { sender }, StreamSubscriber { receiver })
221}
222
223#[derive(Debug)]
225#[repr(transparent)]
226pub struct StreamProducer<A, S> {
227 sender: Sender<(A, S)>,
228}
229
230impl<A, S> Clone for StreamProducer<A, S> {
231 fn clone(&self) -> Self {
232 Self {
233 sender: self.sender.clone(),
234 }
235 }
236}
237
238#[pin_project::pin_project]
240#[derive(Debug)]
241#[repr(transparent)]
242pub struct StreamSubscriber<A, S> {
243 #[pin]
244 receiver: Receiver<(A, S)>,
245}
246
247impl<A, S> Clone for StreamSubscriber<A, S> {
248 fn clone(&self) -> Self {
249 Self {
250 receiver: self.receiver.clone(),
251 }
252 }
253}
254
255impl<A, S> StreamProducer<A, S> {
256 pub async fn send(&self, addr: A, conn: S) -> Result<(), SendError<(A, S)>> {
262 self.sender.send((addr, conn)).await
263 }
264
265 pub fn try_send(&self, addr: A, conn: S) -> Result<(), TrySendError<(A, S)>> {
269 self.sender.try_send((addr, conn))
270 }
271
272 pub fn is_empty(&self) -> bool {
274 self.sender.is_empty()
275 }
276
277 pub fn len(&self) -> usize {
279 self.sender.len()
280 }
281
282 pub fn is_full(&self) -> bool {
284 self.sender.is_full()
285 }
286
287 pub fn is_closed(&self) -> bool {
289 self.sender.is_closed()
290 }
291
292 pub fn close(&self) -> bool {
294 self.sender.close()
295 }
296}
297
298impl<A, S> StreamSubscriber<A, S> {
299 pub async fn recv(&self) -> Result<(A, S), RecvError> {
306 self.receiver.recv().await
307 }
308
309 pub fn try_recv(&self) -> Result<(A, S), TryRecvError> {
313 self.receiver.try_recv()
314 }
315
316 pub fn is_empty(&self) -> bool {
318 self.receiver.is_empty()
319 }
320
321 pub fn len(&self) -> usize {
323 self.receiver.len()
324 }
325
326 pub fn is_full(&self) -> bool {
328 self.receiver.is_full()
329 }
330
331 pub fn is_closed(&self) -> bool {
333 self.receiver.is_closed()
334 }
335
336 pub fn close(&self) -> bool {
338 self.receiver.close()
339 }
340}
341
342impl<A, S> Stream for StreamSubscriber<A, S> {
343 type Item = <Receiver<(A, S)> as Stream>::Item;
344
345 fn poll_next(
346 self: std::pin::Pin<&mut Self>,
347 cx: &mut std::task::Context<'_>,
348 ) -> std::task::Poll<Option<Self::Item>> {
349 <Receiver<_> as Stream>::poll_next(self.project().receiver, cx)
350 }
351}
352
353#[cfg(test)]
354mod tests {
355 use std::net::SocketAddr;
356
357 use bytes::Bytes;
358 use smol_str::SmolStr;
359
360 use super::*;
361
362 async fn access<R: RuntimeLite>() {
363 let messages = Message::<SmolStr, SocketAddr>::user_data(Bytes::new());
364 let timestamp = R::now();
365 let mut packet = Packet::<SocketAddr, _>::new(
366 "127.0.0.1:8080".parse().unwrap(),
367 timestamp,
368 messages.encode_to_bytes().unwrap(),
369 );
370 packet.set_from("127.0.0.1:8081".parse().unwrap());
371
372 let start = R::now();
373 packet.set_timestamp(start);
374 let messages = Message::<SmolStr, SocketAddr>::user_data(Bytes::from_static(b"a"))
375 .encode_to_bytes()
376 .unwrap();
377 packet.set_payload(messages);
378 assert_eq!(
379 packet.payload(),
380 &Message::<SmolStr, SocketAddr>::user_data(Bytes::from_static(b"a"))
381 .encode_to_bytes()
382 .unwrap(),
383 );
384 assert_eq!(
385 *packet.from(),
386 "127.0.0.1:8081".parse::<SocketAddr>().unwrap()
387 );
388 assert_eq!(*packet.timestamp(), start);
389 }
390
391 #[test]
392 fn tokio_access() {
393 tokio::runtime::Builder::new_current_thread()
394 .worker_threads(1)
395 .enable_all()
396 .build()
397 .unwrap()
398 .block_on(access::<agnostic_lite::tokio::TokioRuntime>());
399 }
400}