lum/event/
subscriber.rs

1use std::sync::Arc;
2
3use thiserror::Error;
4use tokio::sync::mpsc::{error::SendError, Sender};
5use uuid::Uuid;
6
7use crate::service::{BoxedError, PinnedBoxedFutureResult};
8
9pub enum Callback<T>
10where
11    T: Send + Sync + 'static,
12{
13    Channel(Sender<Arc<T>>),
14    Closure(Box<dyn Fn(Arc<T>) -> Result<(), BoxedError> + Send + Sync>),
15    AsyncClosure(Box<dyn Fn(Arc<T>) -> PinnedBoxedFutureResult<()> + Send + Sync>),
16}
17
18#[derive(Debug, Error)]
19pub enum DispatchError<T>
20where
21    T: Send + Sync + 'static,
22{
23    #[error("Failed to send data to channel: {0}")]
24    ChannelSend(#[from] SendError<Arc<T>>),
25
26    #[error("Failed to dispatch data to closure: {0}")]
27    Closure(BoxedError),
28
29    #[error("Failed to dispatch data to async closure: {0}")]
30    AsyncClosure(BoxedError),
31}
32
33pub struct Subscriber<T>
34where
35    T: Send + Sync + 'static,
36{
37    pub name: String,
38    pub log_on_error: bool,
39    pub remove_on_error: bool,
40    pub callback: Callback<T>,
41
42    pub uuid: Uuid,
43}
44
45impl<T> Subscriber<T>
46where
47    T: Send + Sync + 'static,
48{
49    pub fn new<S>(name: S, log_on_error: bool, remove_on_error: bool, callback: Callback<T>) -> Self
50    where
51        S: Into<String>,
52    {
53        Self {
54            name: name.into(),
55            log_on_error,
56            remove_on_error,
57            callback,
58            uuid: Uuid::new_v4(),
59        }
60    }
61
62    pub async fn dispatch(&self, data: Arc<T>) -> Result<(), DispatchError<T>> {
63        match &self.callback {
64            Callback::Channel(sender) => {
65                sender.send(data).await.map_err(DispatchError::ChannelSend)
66            }
67            Callback::Closure(closure) => closure(data).map_err(DispatchError::Closure),
68            Callback::AsyncClosure(closure) => {
69                closure(data).await.map_err(DispatchError::AsyncClosure)
70            }
71        }
72    }
73}
74
75impl<T> PartialEq for Subscriber<T>
76where
77    T: Send + Sync + 'static,
78{
79    fn eq(&self, other: &Self) -> bool {
80        self.uuid == other.uuid
81    }
82}
83
84impl<T> Eq for Subscriber<T> where T: Send + Sync {}