Skip to main content

clawless_core/event/
sender.rs

1use tokio::sync::mpsc;
2
3use super::Event;
4
5/// Sender handle for the event channel
6///
7/// `EventSender` is a clonable handle that commands use to emit events into the channel. The
8/// paired [`EventReceiver`] consumes these events for rendering.
9///
10/// Internally, `EventSender` wraps a [`tokio::sync::mpsc::Sender<Event>`]. Cloning an
11/// `EventSender` produces another handle to the same channel, not an independent channel.
12///
13/// [`EventReceiver`]: super::EventReceiver
14// r[impl event.safety.producer-clone]
15// r[impl event.safety.producer-concurrent]
16#[derive(Clone, Debug)]
17pub struct EventSender {
18    /// The half of the Tokio channel that sends events
19    inner: mpsc::Sender<Event>,
20}
21
22impl EventSender {
23    /// Wraps a Tokio sender in an [`EventSender`]
24    ///
25    /// Only [`event_channel`] makes a sender. Clawless creates the matched receiver at the
26    /// same time.
27    ///
28    /// [`event_channel`]: super::event_channel
29    pub(super) fn new(inner: mpsc::Sender<Event>) -> Self {
30        Self { inner }
31    }
32
33    /// Sends an event into the channel
34    ///
35    /// # Errors
36    ///
37    /// Returns [`SendError`] if the [`EventReceiver`] has been dropped.
38    ///
39    /// [`EventReceiver`]: super::EventReceiver
40    /// [`SendError`]: super::SendError
41    pub async fn send(&self, event: Event) -> Result<(), super::SendError> {
42        self.inner
43            .send(event)
44            .await
45            .map_err(|e| super::SendError(e.0))
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    // An assertion in a test panics by design. A `# Panics` section on every test
52    // would repeat that and give the reader no information.
53    #![allow(clippy::missing_panics_doc)]
54
55    use super::*;
56
57    #[test]
58    fn trait_send() {
59        fn assert_send<T: Send>() {}
60        assert_send::<EventSender>();
61    }
62
63    // r[verify event.safety.producer-concurrent]
64    #[test]
65    fn trait_sync() {
66        fn assert_sync<T: Sync>() {}
67        assert_sync::<EventSender>();
68    }
69
70    #[test]
71    fn trait_unpin() {
72        fn assert_unpin<T: Unpin>() {}
73        assert_unpin::<EventSender>();
74    }
75}