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}