1use communication::{Consumer, Received};
4use core::ops::ControlFlow;
5
6use crate::Exit;
7use crate::actor::{Address, BirthMode, Create};
8use crate::calculus::ActionReducer;
9use crate::calculus::Behavior;
10use crate::calculus::UserEvent;
11use crate::effects::SendAlgebra;
12use crate::next::Never;
13
14pub struct Transcript<A: Address, Sends, New> {
15 pub sends: Sends,
16 pub creates: Vec<Create<A, New>>,
17 pub exit: Exit<A>,
18}
19
20impl<A: Address, Sends, New> Transcript<A, Sends, New> {
21 #[must_use]
22 pub const fn new(sends: Sends, creates: Vec<Create<A, New>>, exit: Exit<A>) -> Self {
23 Self {
24 sends,
25 creates,
26 exit,
27 }
28 }
29}
30
31pub async fn run<B, C, A, Sends, Br>(
36 mut behavior: B,
37 mut mailbox: Consumer<C, B::Msg>,
38 from: A,
39) -> Result<Transcript<A, Sends, Br::Child>, B::Error>
40where
41 A: Address,
42 Sends: SendAlgebra,
43 Br: BirthMode,
44 B: Behavior<Addr = A, Ph = Never, Sends = Sends, Birth = Br>,
45{
46 let mut fold = ActionReducer::new();
47 if let ControlFlow::Break(exit) = fold.push(behavior.init()?) {
48 let effects = fold.finish(Some(exit)).effects;
49 return Ok(Transcript::new(effects.sends, effects.creates, exit));
50 }
51 while let Some(received) = mailbox.recv().await {
52 let Received::User(message) = received else {
53 continue;
54 };
55 if let ControlFlow::Break(exit) =
56 fold.push(behavior.transition(B::Event::user(from, message))?)
57 {
58 let effects = fold.finish(Some(exit)).effects;
59 return Ok(Transcript::new(effects.sends, effects.creates, exit));
60 }
61 }
62 let effects = fold.finish(None).effects;
63 Ok(Transcript::new(
64 effects.sends,
65 effects.creates,
66 Exit::Collected,
67 ))
68}