nitinol_process/
receptor.rs

1use std::any::Any;
2use tokio::sync::mpsc::UnboundedSender;
3use tokio::sync::oneshot;
4use nitinol_core::command::Command;
5use nitinol_core::event::Event;
6
7use crate::channel::{ProcessApplier, CommandReceptor, ApplicativeReceptor, TryApplicativeReceptor, NonBlockingEntrustHandler};
8use crate::errors::ChannelDropped;
9use crate::{EventApplicator, Process, CommandHandler, TryEventApplicator};
10
11pub mod any;
12
13use self::any::DynRef;
14
15#[derive(Debug)]
16pub struct Receptor<T: Process> {
17    pub(crate) channel: UnboundedSender<Box<dyn ProcessApplier<T>>>
18}
19
20#[rustfmt::skip]
21impl<T: Process> Receptor<T> {
22    pub async fn handle<C: Command>(&self, command: C) -> Result<Result<T::Event, T::Rejection>, ChannelDropped>
23    where
24        T: CommandHandler<C>,
25    {
26        let (tx, rx) = oneshot::channel();
27        self.channel
28            .send(Box::new(CommandReceptor {
29                command,
30                oneshot: tx,
31            }))
32            .map_err(|_| ChannelDropped)?;
33
34        rx.await.map_err(|_| ChannelDropped)
35    }
36
37    pub async fn apply<E: Event>(&self, event: E) -> Result<(), ChannelDropped>
38    where
39        T: EventApplicator<E>,
40    {
41        let (tx, rx) = oneshot::channel();
42        self.channel
43            .send(Box::new(ApplicativeReceptor { event, oneshot: tx }))
44            .map_err(|_| ChannelDropped)?;
45
46        rx.await.map_err(|_| ChannelDropped)
47    }
48    
49    pub async fn try_apply<E: Event>(&self, event: E) -> Result<Result<(), T::Rejection>, ChannelDropped>
50    where
51        T: TryEventApplicator<E>,
52    {
53        let (tx, rx) = oneshot::channel();
54        self.channel
55            .send(Box::new(TryApplicativeReceptor { event, oneshot: tx }))
56            .map_err(|_| ChannelDropped)?;
57        
58        rx.await.map_err(|_| ChannelDropped)
59    }
60    
61    pub async fn entrust<C: Command>(&self, cmd: C) -> Result<(), ChannelDropped>
62    where
63        T: CommandHandler<C>,
64        T: EventApplicator<<T as CommandHandler<C>>::Event>,
65    {
66        self.channel
67            .send(Box::new(NonBlockingEntrustHandler { command: cmd }))
68            .map_err(|_| ChannelDropped)?;
69        
70        Ok(())
71    }
72}
73
74impl<T: Process> Clone for Receptor<T> {
75    fn clone(&self) -> Self {
76        Self { 
77            channel: self.channel.clone()
78        }
79    }
80}
81
82impl<T: Process> DynRef for Receptor<T> {
83    fn as_any(&self) -> &dyn Any {
84        self
85    }
86}