1use core::future::Future;
4use core::marker::PhantomData;
5
6use communication::{Consumer, Received};
7
8use crate::Exit;
9use crate::deadlined::{TimeEvent, TimeReached};
10use crate::supervising::{ChildEvent, ChildStopped};
11use crate::verdict::{Never, Step};
12use crate::watching::{PeerEvent, PeerStopped};
13
14pub trait Address: Copy + Eq {
16 type Nonce: Copy + Eq;
17
18 #[must_use]
19 fn birth(self, nonce: Self::Nonce) -> Self;
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
23pub struct MailAddr(pub u64);
24
25impl Address for MailAddr {
26 type Nonce = u64;
27
28 fn birth(self, nonce: u64) -> Self {
29 Self(self.0 ^ nonce.wrapping_mul(0x9E37_79B9_7F4A_7C15))
30 }
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36pub enum Route<A: Address> {
37 Global(A),
38 Child(A::Nonce),
39 Service,
40}
41
42pub struct Recipient<A: Address, M> {
44 route: Route<A>,
45 message: PhantomData<fn(M)>,
46}
47
48impl<A: Address, M> Copy for Recipient<A, M> {}
49
50impl<A: Address, M> Clone for Recipient<A, M> {
51 fn clone(&self) -> Self {
52 *self
53 }
54}
55
56impl<A: Address, M> Recipient<A, M> {
57 #[must_use]
58 pub fn global(address: A) -> Self {
59 Self::from_route(Route::Global(address))
60 }
61
62 #[must_use]
63 pub fn child(nonce: A::Nonce) -> Self {
64 Self::from_route(Route::Child(nonce))
65 }
66
67 #[must_use]
68 pub(crate) fn service() -> Self {
69 Self::from_route(Route::Service)
70 }
71
72 #[must_use]
73 pub fn route(self) -> Route<A> {
74 self.route
75 }
76
77 const fn from_route(route: Route<A>) -> Self {
78 Self {
79 route,
80 message: PhantomData,
81 }
82 }
83}
84
85#[derive(Clone, PartialEq, Eq)]
87pub struct Delivery<A: Address, M> {
88 pub to: Recipient<A, M>,
89 pub message: M,
90}
91
92impl<A: Address, M> Delivery<A, M> {
93 #[must_use]
94 pub fn new(to: Recipient<A, M>, message: M) -> Self {
95 Self { to, message }
96 }
97}
98
99impl<A: Address, M> PartialEq for Recipient<A, M> {
100 fn eq(&self, other: &Self) -> bool {
101 self.route == other.route
102 }
103}
104
105impl<A: Address, M> Eq for Recipient<A, M> {}
106
107impl<A: Address + core::fmt::Debug, M> core::fmt::Debug for Recipient<A, M>
108where
109 A::Nonce: core::fmt::Debug,
110{
111 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
112 self.route.fmt(f)
113 }
114}
115
116#[derive(Debug, Clone, PartialEq, Eq)]
118pub struct SendProduct<L, R> {
119 pub inner: L,
120 pub own: R,
121}
122
123pub trait SendAlgebra: Sized {
125 fn empty() -> Self;
126 fn append(&mut self, other: Self);
127}
128
129impl<T> SendAlgebra for Vec<T> {
130 fn empty() -> Self {
131 Vec::new()
132 }
133
134 fn append(&mut self, mut other: Self) {
135 Vec::append(self, &mut other);
136 }
137}
138
139impl<L: SendAlgebra, R: SendAlgebra> SendAlgebra for SendProduct<L, R> {
140 fn empty() -> Self {
141 Self {
142 inner: L::empty(),
143 own: R::empty(),
144 }
145 }
146
147 fn append(&mut self, other: Self) {
148 self.inner.append(other.inner);
149 self.own.append(other.own);
150 }
151}
152
153#[derive(Debug, Clone, PartialEq, Eq)]
156pub struct Create<A: Address, New> {
157 pub nonce: A::Nonce,
158 pub child: New,
159}
160
161pub trait BirthMode {
163 type Child;
164}
165
166#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
168pub struct NoBirths;
169
170impl BirthMode for NoBirths {
171 type Child = Never;
172}
173
174#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
176pub struct Births<C>(PhantomData<fn() -> C>);
177
178impl<C> BirthMode for Births<C> {
179 type Child = C;
180}
181
182pub type Become<A, Ph = Never> = Step<Ph, Exit<A>>;
183
184pub struct Actions<A: Address, Ph, Sends, Birth: BirthMode> {
196 pub sends: Sends,
197 pub creates: Vec<Create<A, Birth::Child>>,
198 pub become_: Become<A, Ph>,
199}
200
201impl<A: Address, Ph, Sends: SendAlgebra, Birth: BirthMode> Actions<A, Ph, Sends, Birth> {
202 #[must_use]
203 pub fn just(become_: Become<A, Ph>) -> Self {
204 Self {
205 sends: Sends::empty(),
206 creates: Vec::new(),
207 become_,
208 }
209 }
210
211 #[must_use]
212 pub fn cont() -> Self {
213 Self::just(Step::Continue)
214 }
215
216 #[must_use]
217 pub fn stop(exit: Exit<A>) -> Self {
218 Self::just(Step::Stop(exit))
219 }
220
221 #[must_use]
222 pub fn goto(phase: Ph) -> Self {
223 Self::just(Step::Goto(phase))
224 }
225}
226
227pub type Acted<A, Ph, Sends, Birth, E> = Result<Actions<A, Ph, Sends, Birth>, E>;
228
229#[derive(Debug, Clone, PartialEq, Eq)]
231pub struct User<A, M> {
232 pub from: A,
233 pub message: M,
234}
235
236pub trait UserEvent: Sized {
238 type Addr: Address;
239 type Message;
240
241 fn user(from: Self::Addr, message: Self::Message) -> Self;
242 fn into_user(self) -> Result<User<Self::Addr, Self::Message>, Self>;
247}
248
249pub type StateActed<A, Out, Birth, Err> = Acted<A, Never, Vec<Delivery<A, Out>>, Birth, Err>;
250
251pub trait State<Out = Never, Birth = NoBirths, Err = Never>
252where
253 Birth: BirthMode,
254{
255 type Addr: Address;
256 type Msg;
257
258 #[allow(
263 clippy::type_complexity,
264 reason = "the alias exposes all state protocol seats"
265 )]
266 fn handle(
267 &mut self,
268 from: Self::Addr,
269 message: Self::Msg,
270 ) -> StateActed<Self::Addr, Out, Birth, Err>;
271}
272
273pub trait Behavior {
276 type Addr: Address;
277 type Msg;
278 type Event: UserEvent<Addr = Self::Addr, Message = Self::Msg>;
279 type Sends: SendAlgebra;
280 type Ph;
281 type Error;
282 type Birth: BirthMode;
283 type Effect;
284 type Done;
285
286 fn init(&mut self) -> impl Future<Output = Result<Self::Effect, Self::Error>> + Send;
287
288 fn step(
289 &mut self,
290 event: Self::Event,
291 ) -> impl Future<Output = Result<Self::Effect, Self::Error>> + Send;
292}
293
294pub struct Base<S: State<O, Br, E>, O = Never, Br: BirthMode = NoBirths, E = Never> {
295 state: S,
296 marker: PhantomData<fn(O, Br, E)>,
297}
298
299impl<S: State<O, Br, E>, O, Br: BirthMode, E> Base<S, O, Br, E> {
300 #[must_use]
301 pub fn new(state: S) -> Self {
302 Self {
303 state,
304 marker: PhantomData,
305 }
306 }
307
308 #[must_use]
309 pub fn state(&self) -> &S {
310 &self.state
311 }
312}
313
314pub type Transition<S, A, M, O, Br, E> =
315 fn(&mut S, A, M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E>;
316
317pub struct FnState<S, A: Address, M, O = Never, Br: BirthMode = NoBirths, E = Never> {
318 pub state: S,
319 pub handle: Transition<S, A, M, O, Br, E>,
320}
321
322impl<S, A: Address, M, O, Br: BirthMode, E> State<O, Br, E> for FnState<S, A, M, O, Br, E> {
323 type Addr = A;
324 type Msg = M;
325
326 fn handle(&mut self, from: A, message: M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E> {
327 (self.handle)(&mut self.state, from, message)
328 }
329}
330
331impl<S, A: Address, M, O, Br: BirthMode, E> Base<FnState<S, A, M, O, Br, E>, O, Br, E> {
332 #[must_use]
333 pub fn from_fn(state: S, handle: Transition<S, A, M, O, Br, E>) -> Self {
334 Self::new(FnState { state, handle })
335 }
336}
337
338impl<A: Address, M> UserEvent for User<A, M> {
339 type Addr = A;
340 type Message = M;
341
342 fn user(from: A, message: M) -> Self {
343 Self { from, message }
344 }
345
346 fn into_user(self) -> Result<Self, Self> {
347 Ok(self)
348 }
349}
350
351impl<A: Address, M> TimeEvent for User<A, M> {
352 fn time_reached(_: TimeReached) -> Option<Self> {
353 None
354 }
355}
356
357impl<A: Address, M> PeerEvent<A> for User<A, M> {
358 fn peer_stopped(_: PeerStopped<A>) -> Option<Self> {
359 None
360 }
361}
362
363impl<A: Address, M> ChildEvent<A> for User<A, M> {
364 fn child_stopped(_: ChildStopped<A>) -> Option<Self> {
365 None
366 }
367}
368
369impl<S, O, Br, E> Behavior for Base<S, O, Br, E>
370where
371 S: State<O, Br, E> + Send,
372 S::Addr: Send,
373 S::Msg: Send,
374 Br: BirthMode,
375 Br::Child: Send,
376 E: Send,
377{
378 type Addr = S::Addr;
379 type Msg = S::Msg;
380 type Event = User<S::Addr, S::Msg>;
381 type Sends = Vec<Delivery<S::Addr, O>>;
382 type Ph = Never;
383 type Error = E;
384 type Birth = Br;
385 type Effect = Actions<S::Addr, Never, Self::Sends, Br>;
386 type Done = Exit<S::Addr>;
387
388 async fn init(&mut self) -> Result<Self::Effect, E> {
389 Ok(Actions::cont())
390 }
391
392 async fn step(&mut self, event: Self::Event) -> Result<Self::Effect, E> {
393 self.state.handle(event.from, event.message)
394 }
395}
396
397pub struct Transcript<A: Address, Sends, New> {
398 pub sends: Sends,
399 pub creates: Vec<Create<A, New>>,
400 pub exit: Exit<A>,
401}
402
403pub async fn run<B, C, A, Sends, Br>(
408 mut behavior: B,
409 mut mailbox: Consumer<C, B::Msg>,
410 from: A,
411) -> Result<Transcript<A, Sends, Br::Child>, B::Error>
412where
413 A: Address,
414 Sends: SendAlgebra,
415 Br: BirthMode,
416 B: Behavior<
417 Addr = A,
418 Ph = Never,
419 Sends = Sends,
420 Birth = Br,
421 Effect = Actions<A, Never, Sends, Br>,
422 Done = Exit<A>,
423 >,
424{
425 let mut sends = Sends::empty();
426 let mut creates = Vec::new();
427 let initial = behavior.init().await?;
428 sends.append(initial.sends);
429 creates.extend(initial.creates);
430 match initial.become_ {
431 Step::Continue => {}
432 Step::Goto(never) => match never {},
433 Step::Stop(exit) => {
434 return Ok(Transcript {
435 sends,
436 creates,
437 exit,
438 });
439 }
440 }
441 while let Some(received) = mailbox.recv().await {
442 let Received::User(message) = received else {
443 continue;
444 };
445 let actions = behavior.step(B::Event::user(from, message)).await?;
446 sends.append(actions.sends);
447 creates.extend(actions.creates);
448 match actions.become_ {
449 Step::Continue => {}
450 Step::Goto(never) => match never {},
451 Step::Stop(exit) => {
452 return Ok(Transcript {
453 sends,
454 creates,
455 exit,
456 });
457 }
458 }
459 }
460 Ok(Transcript {
461 sends,
462 creates,
463 exit: Exit::Collected,
464 })
465}