crb_routine/
finalizer.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use crate::routine::TaskError;
use anyhow::{Error, Result};
use async_trait::async_trait;
use crb_actor::kit::{Actor, Address, MessageFor};

pub type BoxFinalizer<O> = Box<dyn Finalizer<O>>;

#[async_trait]
pub trait Finalizer<O>
where
    Self: Send + 'static,
    O: Send + 'static,
{
    async fn finalize(&mut self, output: Result<O, TaskError>) -> Result<()> {
        output?;
        Ok(())
    }
}

#[async_trait]
pub trait OnOutput<O>: Actor {
    async fn on_output(&mut self, output: Result<O, TaskError>) -> Result<()>;
}

#[async_trait]
impl<A, O> Finalizer<O> for Address<A>
where
    A: OnOutput<O>,
    O: Send + 'static,
{
    async fn finalize(&mut self, output: Result<O, TaskError>) -> Result<()> {
        let msg = RoutineOutput { output };
        self.send(msg)?;
        Ok(())
    }
}

struct RoutineOutput<O> {
    output: Result<O, TaskError>,
}

#[async_trait]
impl<A, O> MessageFor<A> for RoutineOutput<O>
where
    A: OnOutput<O>,
    O: Send + 'static,
{
    async fn handle(self: Box<Self>, actor: &mut A, _ctx: &mut A::Context) -> Result<(), Error> {
        actor.on_output(self.output).await
    }
}