1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! Miscellaneous utilities.

use async_channel::*;

/// Create a bi-directional channel with a given request and response type.
///
/// This reduces the boilerplate required to implement patterns where you need to send data across a
/// channel, but in both directions.
pub fn bi_channel<Request, Response>() -> (
    BiChannelClient<Request, Response>,
    BiChannelServer<Request, Response>,
) {
    let (request_sender, request_receiver) = async_channel::unbounded();
    let (response_sender, response_receiver) = async_channel::unbounded();

    (
        BiChannelClient {
            request_sender,
            response_receiver,
        },
        BiChannelServer {
            request_receiver,
            response_sender,
        },
    )
}

/// A [`bi_channel`] client.
///
/// See [`bi_channel`].
#[allow(missing_docs)]
pub struct BiChannelClient<Request, Response> {
    pub request_sender: Sender<Request>,
    pub response_receiver: Receiver<Response>,
}

#[allow(missing_docs)]
impl<Req, Res> BiChannelClient<Req, Res> {
    pub fn recv_blocking(&self) -> Result<Res, RecvError> {
        self.response_receiver.recv_blocking()
    }
    pub fn send_blocking(&self, req: Req) -> Result<(), SendError<Req>> {
        self.request_sender.send_blocking(req)
    }
    pub async fn send(&self, req: Req) -> Result<(), SendError<Req>> {
        self.request_sender.send(req).await
    }
    pub async fn recv(&self) -> Result<Res, RecvError> {
        self.response_receiver.recv().await
    }
    pub fn try_send(&self, req: Req) -> Result<(), TrySendError<Req>> {
        self.request_sender.try_send(req)
    }
    pub fn try_recv(&self) -> Result<Res, TryRecvError> {
        self.response_receiver.try_recv()
    }
}

/// A [`bi_channel`] server.
///
/// See [`bi_channel`].
#[allow(missing_docs)]
pub struct BiChannelServer<Request, Response> {
    pub request_receiver: Receiver<Request>,
    pub response_sender: Sender<Response>,
}

#[allow(missing_docs)]
impl<Req, Res> BiChannelServer<Req, Res> {
    pub fn recv_blocking(&self) -> Result<Req, RecvError> {
        self.request_receiver.recv_blocking()
    }
    pub fn send_blocking(&self, res: Res) -> Result<(), SendError<Res>> {
        self.response_sender.send_blocking(res)
    }
    pub async fn send(&self, res: Res) -> Result<(), SendError<Res>> {
        self.response_sender.send(res).await
    }
    pub async fn recv(&self) -> Result<Req, RecvError> {
        self.request_receiver.recv().await
    }
    pub fn try_send(&self, res: Res) -> Result<(), TrySendError<Res>> {
        self.response_sender.try_send(res)
    }
    pub fn try_recv(&self) -> Result<Req, TryRecvError> {
        self.request_receiver.try_recv()
    }
}