bones_framework/
utils.rs

1//! Miscellaneous utilities.
2
3use async_channel::*;
4
5/// Create a bi-directional channel with a given request and response type.
6///
7/// This reduces the boilerplate required to implement patterns where you need to send data across a
8/// channel, but in both directions.
9pub fn bi_channel<Request, Response>() -> (
10    BiChannelClient<Request, Response>,
11    BiChannelServer<Request, Response>,
12) {
13    let (request_sender, request_receiver) = async_channel::unbounded();
14    let (response_sender, response_receiver) = async_channel::unbounded();
15
16    (
17        BiChannelClient {
18            request_sender,
19            response_receiver,
20        },
21        BiChannelServer {
22            request_receiver,
23            response_sender,
24        },
25    )
26}
27
28/// A [`bi_channel`] client.
29///
30/// See [`bi_channel`].
31#[allow(missing_docs)]
32pub struct BiChannelClient<Request, Response> {
33    pub request_sender: Sender<Request>,
34    pub response_receiver: Receiver<Response>,
35}
36
37#[allow(missing_docs)]
38impl<Req, Res> BiChannelClient<Req, Res> {
39    pub fn recv_blocking(&self) -> Result<Res, RecvError> {
40        self.response_receiver.recv_blocking()
41    }
42    pub fn send_blocking(&self, req: Req) -> Result<(), SendError<Req>> {
43        self.request_sender.send_blocking(req)
44    }
45    pub async fn send(&self, req: Req) -> Result<(), SendError<Req>> {
46        self.request_sender.send(req).await
47    }
48    pub async fn recv(&self) -> Result<Res, RecvError> {
49        self.response_receiver.recv().await
50    }
51    pub fn try_send(&self, req: Req) -> Result<(), TrySendError<Req>> {
52        self.request_sender.try_send(req)
53    }
54    pub fn try_recv(&self) -> Result<Res, TryRecvError> {
55        self.response_receiver.try_recv()
56    }
57}
58
59/// A [`bi_channel`] server.
60///
61/// See [`bi_channel`].
62#[allow(missing_docs)]
63pub struct BiChannelServer<Request, Response> {
64    pub request_receiver: Receiver<Request>,
65    pub response_sender: Sender<Response>,
66}
67
68#[allow(missing_docs)]
69impl<Req, Res> BiChannelServer<Req, Res> {
70    pub fn recv_blocking(&self) -> Result<Req, RecvError> {
71        self.request_receiver.recv_blocking()
72    }
73    pub fn send_blocking(&self, res: Res) -> Result<(), SendError<Res>> {
74        self.response_sender.send_blocking(res)
75    }
76    pub async fn send(&self, res: Res) -> Result<(), SendError<Res>> {
77        self.response_sender.send(res).await
78    }
79    pub async fn recv(&self) -> Result<Req, RecvError> {
80        self.request_receiver.recv().await
81    }
82    pub fn try_send(&self, res: Res) -> Result<(), TrySendError<Res>> {
83        self.response_sender.try_send(res)
84    }
85    pub fn try_recv(&self) -> Result<Req, TryRecvError> {
86        self.request_receiver.try_recv()
87    }
88}