crb_morph/
lib.rs

1use async_trait::async_trait;
2use crb_runtime::{Context, InteractiveRuntime, Interruptor, Runtime};
3
4pub trait MorphContext: Context + 'static {
5    fn morph(&mut self, next: impl Morph<Context = Self>);
6    fn next_state(&mut self) -> Option<Box<dyn Morph<Context = Self>>>;
7}
8
9pub struct MorphSession {
10    next_state: Option<Box<dyn Morph<Context = Self>>>,
11}
12
13impl MorphContext for MorphSession {
14    fn morph(&mut self, next: impl Morph<Context = Self>) {
15        self.next_state = Some(Box::new(next));
16    }
17
18    fn next_state(&mut self) -> Option<Box<dyn Morph<Context = Self>>> {
19        self.next_state.take()
20    }
21}
22
23impl Context for MorphSession {
24    type Address = ();
25
26    fn address(&self) -> &Self::Address {
27        &()
28    }
29}
30
31pub trait Morph: Send + 'static {
32    // TODO:
33    // type Message; ? and the `send` method that expects `impl Into<Morph::Message>`
34    // Routing? call the method only if that is implemented for a particular state?
35    type Context;
36}
37
38pub struct MorphRuntime<C> {
39    context: C,
40    morphed: Box<dyn Morph<Context = C>>,
41}
42
43#[async_trait]
44impl<C: MorphContext> InteractiveRuntime for MorphRuntime<C> {
45    type Context = C;
46
47    fn address(&self) -> <Self::Context as Context>::Address {
48        self.context.address().clone()
49    }
50}
51
52#[async_trait]
53impl<C: MorphContext> Runtime for MorphRuntime<C> {
54    fn get_interruptor(&mut self) -> Interruptor {
55        todo!()
56    }
57
58    async fn routine(&mut self) {
59        loop {
60            if let Some(morphed) = self.context.next_state() {
61                self.morphed = morphed;
62            }
63        }
64    }
65}