Skip to main content

behavior/fold/
driver.rs

1//! A minimal mailbox driver for complete user-lane behaviors.
2
3use communication::{Consumer, Received};
4
5use super::behavior::Behavior;
6use super::user_event::UserEvent;
7use crate::Exit;
8use crate::actor::{Address, BirthMode, Create};
9use crate::transition::SendAlgebra;
10use crate::verdict::{Never, Step};
11
12pub struct Transcript<A: Address, Sends, New> {
13    pub sends: Sends,
14    pub creates: Vec<Create<A, New>>,
15    pub exit: Exit<A>,
16}
17
18/// Drive user-lane messages through a complete behavior protocol.
19///
20/// # Errors
21/// Returns the first controlled behavior failure.
22pub async fn run<B, C, A, Sends, Br>(
23    mut behavior: B,
24    mut mailbox: Consumer<C, B::Msg>,
25    from: A,
26) -> Result<Transcript<A, Sends, Br::Child>, B::Error>
27where
28    A: Address,
29    Sends: SendAlgebra,
30    Br: BirthMode,
31    B: Behavior<Addr = A, Ph = Never, Sends = Sends, Birth = Br>,
32{
33    let mut sends = Sends::empty();
34    let mut creates = Vec::new();
35    let initial = behavior.init().await?;
36    sends.append(initial.sends);
37    creates.extend(initial.creates);
38    match initial.become_ {
39        Step::Continue => {}
40        Step::Goto(never) => match never {},
41        Step::Stop(exit) => {
42            return Ok(Transcript {
43                sends,
44                creates,
45                exit,
46            });
47        }
48    }
49    while let Some(received) = mailbox.recv().await {
50        let Received::User(message) = received else {
51            continue;
52        };
53        let actions = behavior.step(B::Event::user(from, message)).await?;
54        sends.append(actions.sends);
55        creates.extend(actions.creates);
56        match actions.become_ {
57            Step::Continue => {}
58            Step::Goto(never) => match never {},
59            Step::Stop(exit) => {
60                return Ok(Transcript {
61                    sends,
62                    creates,
63                    exit,
64                });
65            }
66        }
67    }
68    Ok(Transcript {
69        sends,
70        creates,
71        exit: Exit::Collected,
72    })
73}