1use crate::routine::TaskError;
2use anyhow::{Error, Result};
3use async_trait::async_trait;
4use crb_actor::kit::{Actor, Address, MessageFor};
5
6pub type BoxFinalizer<O> = Box<dyn Finalizer<O>>;
7
8#[async_trait]
9pub trait Finalizer<O>
10where
11 Self: Send + 'static,
12 O: Send + 'static,
13{
14 async fn finalize(&mut self, output: Result<O, TaskError>) -> Result<()> {
15 output?;
16 Ok(())
17 }
18}
19
20#[async_trait]
21pub trait OnOutput<O>: Actor {
22 async fn on_output(&mut self, output: Result<O, TaskError>) -> Result<()>;
23}
24
25#[async_trait]
26impl<A, O> Finalizer<O> for Address<A>
27where
28 A: OnOutput<O>,
29 O: Send + 'static,
30{
31 async fn finalize(&mut self, output: Result<O, TaskError>) -> Result<()> {
32 let msg = RoutineOutput { output };
33 self.send(msg)?;
34 Ok(())
35 }
36}
37
38struct RoutineOutput<O> {
39 output: Result<O, TaskError>,
40}
41
42#[async_trait]
43impl<A, O> MessageFor<A> for RoutineOutput<O>
44where
45 A: OnOutput<O>,
46 O: Send + 'static,
47{
48 async fn handle(self: Box<Self>, actor: &mut A, _ctx: &mut A::Context) -> Result<(), Error> {
49 actor.on_output(self.output).await
50 }
51}