Skip to main content

workflow_rpc/client/interface/
notification.rs

1use crate::imports::*;
2
3#[async_trait]
4pub trait NotificationTrait: Send + Sync + 'static {
5    async fn call_with_borsh(&self, data: &[u8]) -> ServerResult<()>;
6    async fn call_with_serde_json(&self, value: Value) -> ServerResult<()>;
7}
8
9pub type NotificationFn<Msg> =
10    Arc<Box<dyn Send + Sync + Fn(Msg) -> NotificationFnReturn<()> + 'static>>;
11
12pub type NotificationFnReturn<T> = Pin<Box<dyn Send + 'static + Future<Output = ServerResult<T>>>>;
13
14/// A typed notification handler that deserializes an inbound `Msg` payload
15/// (from Borsh or JSON) and invokes the wrapped async callback with it.
16pub struct Notification<Msg>
17where
18    Msg: BorshDeserialize + DeserializeOwned + Send + Sync + 'static,
19{
20    method: NotificationFn<Msg>,
21}
22
23impl<Msg> Notification<Msg>
24where
25    Msg: BorshDeserialize + DeserializeOwned + Send + Sync + 'static,
26{
27    /// Wrap the given async callback into a typed notification handler.
28    pub fn new<FN>(method_fn: FN) -> Notification<Msg>
29    where
30        FN: Send + Sync + Fn(Msg) -> NotificationFnReturn<()> + 'static,
31    {
32        Notification {
33            method: Arc::new(Box::new(method_fn)),
34        }
35    }
36}
37
38#[async_trait]
39impl<Msg> NotificationTrait for Notification<Msg>
40where
41    Msg: BorshDeserialize + DeserializeOwned + Send + Sync + 'static,
42{
43    async fn call_with_borsh(&self, data: &[u8]) -> ServerResult<()> {
44        let msg = Msg::try_from_slice(data)
45            .map_err(|err| ServerError::NotificationDeserialize(err.to_string()))?;
46        (self.method)(msg).await
47    }
48
49    async fn call_with_serde_json(&self, value: Value) -> ServerResult<()> {
50        let msg: Msg = serde_json::from_value(value)
51            .map_err(|err| ServerError::NotificationDeserialize(err.to_string()))?;
52        (self.method)(msg).await
53    }
54}