nitinol_process/
receptor.rs1use 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}