crb_send/
sender.rs

1//! An implementation of an abstract sender.
2//!
3//! The crate contains a trait and an implementation of a sender.
4
5use crate::notifier::TypedNotifier;
6use anyhow::Result;
7use std::fmt;
8use std::sync::Arc;
9
10/// An abstract sender.
11pub trait Sender<M>: Send + Sync {
12    /// Sends an event (data) to a recipient.
13    fn send(&self, input: M) -> Result<()>;
14
15    fn notifier(self, message: M) -> TypedNotifier<M>
16    where
17        Self: Sized + 'static,
18    {
19        TypedNotifier::new(self, message)
20    }
21}
22
23/// An empty sender that skips sending.
24///
25/// Useful when you want to drop messages instead of sending them.
26#[derive(Debug)]
27pub struct EmptySender;
28
29impl<M> Sender<M> for EmptySender {
30    fn send(&self, _msg: M) -> Result<()> {
31        Ok(())
32    }
33}
34
35/// A wrapper to convert any function to a sender.
36pub struct FuncSender<F>(F);
37
38impl<F, IN> Sender<IN> for FuncSender<F>
39where
40    F: Fn(IN) -> Result<()>,
41    F: Send + Sync,
42{
43    fn send(&self, input: IN) -> Result<()> {
44        (self.0)(input)
45    }
46}
47
48/// A universal cloneable wrapper for `Sender`.
49pub struct Recipient<M> {
50    recipient: Arc<dyn Sender<M>>,
51}
52
53impl<M> Clone for Recipient<M> {
54    fn clone(&self) -> Self {
55        Self {
56            recipient: self.recipient.clone(),
57        }
58    }
59}
60
61impl<M> Sender<M> for Recipient<M> {
62    fn send(&self, msg: M) -> Result<()> {
63        self.recipient.send(msg)
64    }
65}
66
67impl<M> fmt::Debug for Recipient<M> {
68    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69        write!(f, "Recipient")
70    }
71}
72
73impl<M> Recipient<M> {
74    /// Wraps a sender with a reference counter.
75    pub fn new<E>(sender: E) -> Self
76    where
77        E: Sender<M> + 'static,
78    {
79        Self {
80            recipient: Arc::new(sender),
81        }
82    }
83
84    /// Changes `Recipient` to another input type.
85    pub fn reform<F, IN>(&self, func: F) -> Recipient<IN>
86    where
87        F: Fn(IN) -> M,
88        F: Send + Sync + 'static,
89        M: 'static,
90    {
91        let recipient = self.recipient.clone();
92        let func_sender = FuncSender(move |input| {
93            let output = func(input);
94            recipient.send(output)
95        });
96        Recipient::new(func_sender)
97    }
98}