nitinol_process/channel/
command.rs1use std::fmt::Debug;
2use super::ProcessApplier;
3use crate::errors::ChannelDropped;
4use crate::{Process, Context};
5use async_trait::async_trait;
6use nitinol_core::command::Command;
7use nitinol_core::event::Event;
8use tokio::sync::oneshot;
9
10#[async_trait]
11pub trait CommandHandler<C: Command>: 'static + Sync + Send {
12 type Event: Event;
13 type Rejection: Debug + 'static + Sync + Send;
14 async fn handle(&self, command: C, ctx: &mut Context) -> Result<Self::Event, Self::Rejection>;
15}
16
17pub(crate) struct CommandReceptor<C: Command, T: Process>
18where
19 T: CommandHandler<C>,
20{
21 pub(crate) command: C,
22 pub(crate) oneshot: oneshot::Sender<Result<T::Event, T::Rejection>>,
23}
24
25#[async_trait::async_trait]
26impl<C: Command, T: Process> ProcessApplier<T> for CommandReceptor<C, T>
27where
28 T: CommandHandler<C>,
29{
30 async fn apply(
31 self: Box<Self>,
32 entity: &mut T,
33 ctx: &mut Context,
34 ) -> Result<(), ChannelDropped> {
35 self.oneshot
36 .send(entity.handle(self.command, ctx).await)
37 .map_err(|_| ChannelDropped)
38 }
39}