trait_enumizer/
returnval.rs

1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2/// Error returned when failed to send method's return value to the channel in enum.
3/// Typically channel return the value back to caller when attempting to send to a closed channel.
4/// In Enumizer, we cannot have return type dependent on T, so are just ignoring the value.
5/// 
6/// If needed, you can make your own channel class that would box up undelivered return value to some `Box<dyn Any>`. 
7pub struct FailedToSendReturnValue;
8impl core::fmt::Display for FailedToSendReturnValue {
9    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10        write!(
11            f,
12            "trait-enumizer: Failed to send return value back to caller"
13        )
14    }
15}
16#[cfg(feature="std")]
17impl std::error::Error for FailedToSendReturnValue {}
18
19/// Channel class for using `flume::bounded(1)` to deliver return values. Supports both sync and async.
20#[cfg(feature = "flume")]
21#[cfg_attr(docsrs, doc(cfg(feature = "flume")))]
22#[macro_export]
23macro_rules! flume_class {
24    (Sender<$T:ty>) => { ::flume::Sender<$T> };
25    (SendError) => { $crate::FailedToSendReturnValue };
26    (RecvError) => { ::flume::RecvError };
27    (create::<$T:ty>()) => { ::flume::bounded(1) };
28    (send::<$T:ty>($channel:expr, $msg:expr)) => { ($channel).send($msg).map_err(|_| $crate::FailedToSendReturnValue) };
29    (recv::<$T:ty>($channel:expr)) => { ($channel).recv() };
30    (send_async::<$T:ty>($channel:expr, $msg:expr)) => { ($channel).send_async($msg).await.map_err(|_| $crate::FailedToSendReturnValue) };
31    (recv_async::<$T:ty>($channel:expr)) => { ($channel).recv_async().await };
32}
33#[cfg(feature = "crossbeam-channel")]
34#[cfg_attr(docsrs, doc(cfg(feature = "crossbeam-channel")))]
35#[macro_export]
36/// Channel class for using `::crossbeam_channel::bounded(1)` to deliver return values. Sync-only.
37macro_rules! crossbeam_class {
38    (Sender<$T:ty>) => { ::crossbeam_channel::Sender<$T> };
39    (SendError) => { $crate::FailedToSendReturnValue };
40    (RecvError) => { ::crossbeam_channel::RecvError };
41    (create::<$T:ty>()) => { ::crossbeam_channel::bounded(1) };
42    (send::<$T:ty>($channel:expr, $msg:expr)) => { ($channel).send($msg).map_err(|_| $crate::FailedToSendReturnValue) };
43    (recv::<$T:ty>($channel:expr)) => { ($channel).recv() };
44}
45
46/// Channel class for using `tokio::sync::oneshot::channel()` to deliver return values. Supports both sync and async.
47#[cfg(feature = "tokio")]
48#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
49#[macro_export]
50macro_rules! tokio_oneshot_class {
51    (Sender<$T:ty>) => { ::tokio::sync::oneshot::Sender<$T> };
52    (SendError) => { $crate::FailedToSendReturnValue };
53    (RecvError) => { ::tokio::sync::oneshot::error::RecvError };
54    (create::<$T:ty>()) => { ::tokio::sync::oneshot::channel() };
55    (send::<$T:ty>($channel:expr, $msg:expr)) => { ($channel).send($msg).map_err(|_| $crate::FailedToSendReturnValue) };
56    (recv::<$T:ty>($channel:expr)) => { ($channel).blocking_recv() };
57    (send_async::<$T:ty>($channel:expr, $msg:expr)) => { ($channel).send($msg).map_err(|_| $crate::FailedToSendReturnValue) };
58    (recv_async::<$T:ty>($channel:expr)) => { ($channel).await };
59}
60
61
62#[cfg(feature = "catty")]
63#[cfg_attr(docsrs, doc(cfg(feature = "catty")))]
64#[macro_export]
65/// Channel class for using `catty::oneshot()` to deliver return values. Async-only.
66macro_rules! catty_class {
67    (Sender<$T:ty>) => { ::catty::Sender<$T> };
68    (SendError) => { $crate::FailedToSendReturnValue };
69    (RecvError) => { ::catty::Disconnected };
70    (create::<$T:ty>()) => { ::catty::oneshot() };
71    (send::<$T:ty>($channel:expr, $msg:expr)) => { ($channel).send($msg).map_err(|_| $crate::FailedToSendReturnValue) };
72    (send_async::<$T:ty>($channel:expr, $msg:expr)) => { ($channel).send($msg).map_err(|_| $crate::FailedToSendReturnValue) };
73    (recv_async::<$T:ty>($channel:expr)) => { ($channel).await };
74}
75
76#[cfg(feature = "futures")]
77#[cfg_attr(docsrs, doc(cfg(feature = "futures")))]
78#[macro_export]
79/// Channel class for using `futures::channel::oneshot::channel()` to deliver return values. Async-only.
80macro_rules! futures_oneshot_class {
81    (Sender<$T:ty>) => { ::futures::channel::oneshot::Sender<$T> };
82    (SendError) => { $crate::FailedToSendReturnValue };
83    (RecvError) => { ::futures::channel::oneshot::Canceled };
84    (create::<$T:ty>()) => { ::futures::channel::oneshot::channel() };
85    (send::<$T:ty>($channel:expr, $msg:expr)) => { ($channel).send($msg).map_err(|_| $crate::FailedToSendReturnValue) };
86    (send_async::<$T:ty>($channel:expr, $msg:expr)) => { ($channel).send($msg).map_err(|_| $crate::FailedToSendReturnValue) };
87    (recv_async::<$T:ty>($channel:expr)) => { ($channel).await };
88}
89
90
91
92#[cfg(feature = "std")]
93#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
94#[macro_export]
95/// Channel class for using `std::sync::mpsc::sync_channel(1)` to deliver return values. Sync-only.
96macro_rules! stdmpsc_class {
97    (Sender<$T:ty>) => { ::std::sync::mpsc::SyncSender<$T> };
98    (SendError) => { $crate::FailedToSendReturnValue };
99    (RecvError) => { ::std::sync::mpsc::RecvError };
100    (create::<$T:ty>()) => { ::std::sync::mpsc::sync_channel(1) };
101    (send::<$T:ty>($channel:expr, $msg:expr)) => { ($channel).send($msg).map_err(|_| $crate::FailedToSendReturnValue) };
102    (recv::<$T:ty>($channel:expr)) => { ($channel).recv() };
103}