brug/
lib.rs

1#![doc = include_str!("../README.md")]
2
3pub use async_trait::async_trait;
4
5#[cfg(feature = "macros")]
6pub use brug_macros::performer;
7
8#[async_trait]
9pub trait Performer<Command: Send> {
10    /// Perform the given command, the command has an embedded callback path
11    async fn perform(&mut self, command: Command);
12}
13
14#[async_trait]
15pub trait Sender<T: Send>: Send {
16    async fn send(self, data: T);
17}
18
19#[async_trait]
20pub trait Receiver<T: Send>: Send {
21    async fn receive(self) -> Option<T>;
22}
23
24/// Defines a type of transport for return values
25/// this might e.g. be the `tokio::sync::oneshot` channel, but any different user implementation can used too
26///
27/// The indirection (e.g. the actual channel being stored in a child type of a `Transport`) was originally meant
28/// to allow the `Command` enum's to contain a generic Sender, however it ended useful in being able to bundle both
29/// Sender and Receiver types, and offer a method to create a paired set
30pub trait Transport: 'static
31{
32    type Sender<T: Send>: Sender<T>;
33    type Receiver<T: Send>: Receiver<T>;
34
35    /// Create a new paired set of this transport method
36    fn pair<T: Send>() -> (Self::Sender<T>, Self::Receiver<T>);
37}
38
39#[cfg(feature = "tokio")]
40pub mod tokio {
41    use async_trait::async_trait;
42    use tokio::sync::oneshot;
43    use crate::{Receiver, Sender, Transport};
44
45    /// Implements [`Transport`](crate::Transport) for [`tokio::sync::oneshot`](tokio::sync::oneshot)
46    pub struct OneShot;
47
48    impl Transport for OneShot {
49        type Sender<T: Send> = oneshot::Sender<T>;
50        type Receiver<T: Send> = oneshot::Receiver<T>;
51
52        #[inline(always)]
53        fn pair<T: Send>() -> (Self::Sender<T>, Self::Receiver<T>) {
54            oneshot::channel()
55        }
56    }
57
58    #[async_trait]
59    impl<T: Send> Sender<T> for oneshot::Sender<T> {
60        #[inline(always)]
61        async fn send(self, data: T) {
62            let _ = oneshot::Sender::send(self, data);
63        }
64    }
65
66    #[async_trait]
67    impl<T: Send> Receiver<T> for oneshot::Receiver<T> {
68        #[inline(always)]
69        async fn receive(self) -> Option<T> {
70            self.await.ok()
71        }
72    }
73}
74
75#[cfg(feature = "kanal")]
76pub mod kanal {
77    use kanal::{OneshotAsyncReceiver, OneshotAsyncSender};
78    use crate::{Receiver, Sender, Transport};
79    use async_trait::async_trait;
80
81    pub struct OneShot;
82
83    impl Transport for OneShot {
84        type Sender<T: Send> = kanal::OneshotAsyncSender<T>;
85        type Receiver<T: Send> = kanal::OneshotAsyncReceiver<T>;
86
87        #[inline(always)]
88        fn pair<T: Send>() -> (Self::Sender<T>, Self::Receiver<T>) {
89            kanal::oneshot_async()
90        }
91    }
92
93    #[async_trait]
94    impl<T: Send> Receiver<T> for OneshotAsyncReceiver<T> {
95        async fn receive(self) -> Option<T> {
96            self.recv().await.ok()
97        }
98    }
99
100    #[async_trait]
101    impl<T: Send> Sender<T> for OneshotAsyncSender<T> {
102        async fn send(self, data: T) {
103            let _ = OneshotAsyncSender::send(self, data).await;
104        }
105    }
106}