1use core::future::Future;
4use core::marker::PhantomData;
5
6use communication::{Consumer, Received};
7
8use crate::Exit;
9use crate::protocol::{
10 ChildEvent, ChildStopped, PeerEvent, PeerStopped, ShutdownEvent, ShutdownRequested, TimeEvent,
11 TimerElapsed, WorkerEvent, WorkerStopped,
12};
13use crate::verdict::{Never, Step};
14
15pub trait Address: Copy + Eq {
17 type Nonce: Copy + Eq;
18
19 #[must_use]
20 fn birth(self, nonce: Self::Nonce) -> Self;
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
24pub struct MailAddr(pub u64);
25
26impl Address for MailAddr {
27 type Nonce = u64;
28
29 fn birth(self, nonce: u64) -> Self {
30 Self(self.0 ^ nonce.wrapping_mul(0x9E37_79B9_7F4A_7C15))
31 }
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36pub enum Route<A: Address> {
37 Global(A),
38 Child(A::Nonce),
39}
40
41pub struct Recipient<A: Address, M> {
43 route: Route<A>,
44 message: PhantomData<fn(M)>,
45}
46
47impl<A: Address, M> Copy for Recipient<A, M> {}
48
49impl<A: Address, M> Clone for Recipient<A, M> {
50 fn clone(&self) -> Self {
51 *self
52 }
53}
54
55impl<A: Address, M> Recipient<A, M> {
56 #[must_use]
57 pub fn global(address: A) -> Self {
58 Self::from_route(Route::Global(address))
59 }
60
61 #[must_use]
62 pub fn child(nonce: A::Nonce) -> Self {
63 Self::from_route(Route::Child(nonce))
64 }
65
66 #[must_use]
67 pub fn route(self) -> Route<A> {
68 self.route
69 }
70
71 const fn from_route(route: Route<A>) -> Self {
72 Self {
73 route,
74 message: PhantomData,
75 }
76 }
77}
78
79#[derive(Clone, PartialEq, Eq)]
81pub struct Delivery<A: Address, M> {
82 pub to: Recipient<A, M>,
83 pub message: M,
84}
85
86impl<A: Address, M> Delivery<A, M> {
87 #[must_use]
88 pub fn new(to: Recipient<A, M>, message: M) -> Self {
89 Self { to, message }
90 }
91}
92
93impl<A: Address, M> PartialEq for Recipient<A, M> {
94 fn eq(&self, other: &Self) -> bool {
95 self.route == other.route
96 }
97}
98
99impl<A: Address, M> Eq for Recipient<A, M> {}
100
101impl<A: Address + core::fmt::Debug, M> core::fmt::Debug for Recipient<A, M>
102where
103 A::Nonce: core::fmt::Debug,
104{
105 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
106 self.route.fmt(f)
107 }
108}
109
110#[derive(Debug, Clone, PartialEq, Eq)]
112pub struct SendProduct<L, R> {
113 pub inner: L,
114 pub own: R,
115}
116
117pub trait SendAlgebra: Sized {
119 fn empty() -> Self;
120 fn append(&mut self, other: Self);
121}
122
123impl<T> SendAlgebra for Vec<T> {
124 fn empty() -> Self {
125 Vec::new()
126 }
127
128 fn append(&mut self, mut other: Self) {
129 Vec::append(self, &mut other);
130 }
131}
132
133impl<L: SendAlgebra, R: SendAlgebra> SendAlgebra for SendProduct<L, R> {
134 fn empty() -> Self {
135 Self {
136 inner: L::empty(),
137 own: R::empty(),
138 }
139 }
140
141 fn append(&mut self, other: Self) {
142 self.inner.append(other.inner);
143 self.own.append(other.own);
144 }
145}
146
147#[derive(Debug, Clone, PartialEq, Eq)]
154pub struct ServiceSends<M> {
155 requests: Vec<M>,
156}
157
158impl<M> ServiceSends<M> {
159 #[must_use]
160 pub fn new(requests: Vec<M>) -> Self {
161 Self { requests }
162 }
163
164 #[must_use]
165 pub fn one(request: M) -> Self {
166 Self::new(vec![request])
167 }
168
169 #[must_use]
170 pub fn as_slice(&self) -> &[M] {
171 &self.requests
172 }
173
174 pub fn iter(&self) -> core::slice::Iter<'_, M> {
175 self.requests.iter()
176 }
177
178 #[must_use]
179 pub fn len(&self) -> usize {
180 self.requests.len()
181 }
182
183 #[must_use]
184 pub fn is_empty(&self) -> bool {
185 self.requests.is_empty()
186 }
187
188 pub fn extend(&mut self, requests: impl IntoIterator<Item = M>) {
189 self.requests.extend(requests);
190 }
191
192 #[must_use]
193 pub fn into_requests(self) -> Vec<M> {
194 self.requests
195 }
196}
197
198impl<M> core::ops::Index<usize> for ServiceSends<M> {
199 type Output = M;
200
201 fn index(&self, index: usize) -> &Self::Output {
202 &self.requests[index]
203 }
204}
205
206impl<M> IntoIterator for ServiceSends<M> {
207 type Item = M;
208 type IntoIter = std::vec::IntoIter<M>;
209
210 fn into_iter(self) -> Self::IntoIter {
211 self.requests.into_iter()
212 }
213}
214
215impl<'a, M> IntoIterator for &'a ServiceSends<M> {
216 type Item = &'a M;
217 type IntoIter = core::slice::Iter<'a, M>;
218
219 fn into_iter(self) -> Self::IntoIter {
220 self.requests.iter()
221 }
222}
223
224impl<M> SendAlgebra for ServiceSends<M> {
225 fn empty() -> Self {
226 Self::new(Vec::new())
227 }
228
229 fn append(&mut self, mut other: Self) {
230 self.requests.append(&mut other.requests);
231 }
232}
233
234#[derive(Debug, Clone, Copy, PartialEq, Eq)]
241pub enum CreationKind {
242 Birth,
244 ReplacementIncarnation,
246}
247
248#[derive(Debug, Clone, PartialEq, Eq)]
256pub struct Create<A: Address, New> {
257 pub nonce: A::Nonce,
258 pub child: New,
259 pub kind: CreationKind,
260}
261
262impl<A: Address, New> Create<A, New> {
263 #[must_use]
265 pub const fn birth(nonce: A::Nonce, child: New) -> Self {
266 Self {
267 nonce,
268 child,
269 kind: CreationKind::Birth,
270 }
271 }
272
273 #[must_use]
275 pub const fn replacement_incarnation(nonce: A::Nonce, child: New) -> Self {
276 Self {
277 nonce,
278 child,
279 kind: CreationKind::ReplacementIncarnation,
280 }
281 }
282}
283
284pub trait BirthMode {
286 type Child;
287}
288
289#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
291pub struct NoBirths;
292
293impl BirthMode for NoBirths {
294 type Child = Never;
295}
296
297#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
299pub struct Births<C>(PhantomData<fn() -> C>);
300
301impl<C> BirthMode for Births<C> {
302 type Child = C;
303}
304
305pub type Become<A, Ph = Never> = Step<Ph, Exit<A>>;
306
307pub struct Actions<A: Address, Ph, Sends, Birth: BirthMode> {
321 pub sends: Sends,
322 pub creates: Vec<Create<A, Birth::Child>>,
323 pub become_: Become<A, Ph>,
324}
325
326impl<A: Address, Ph, Sends: SendAlgebra, Birth: BirthMode> Actions<A, Ph, Sends, Birth> {
327 #[must_use]
328 pub fn just(become_: Become<A, Ph>) -> Self {
329 Self {
330 sends: Sends::empty(),
331 creates: Vec::new(),
332 become_,
333 }
334 }
335
336 #[must_use]
337 pub fn cont() -> Self {
338 Self::just(Step::Continue)
339 }
340
341 #[must_use]
342 pub fn stop(exit: Exit<A>) -> Self {
343 Self::just(Step::Stop(exit))
344 }
345
346 #[must_use]
347 pub fn goto(phase: Ph) -> Self {
348 Self::just(Step::Goto(phase))
349 }
350}
351
352pub type Acted<A, Ph, Sends, Birth, E> = Result<Actions<A, Ph, Sends, Birth>, E>;
353
354#[derive(Debug, Clone, PartialEq, Eq)]
356pub struct User<A, M> {
357 pub from: A,
358 pub message: M,
359}
360
361pub trait UserEvent: Sized {
363 type Addr: Address;
364 type Message;
365
366 fn user(from: Self::Addr, message: Self::Message) -> Self;
367 fn into_user(self) -> Result<User<Self::Addr, Self::Message>, Self>;
372}
373
374pub type StateActed<A, Out, Birth, Err> = Acted<A, Never, Vec<Delivery<A, Out>>, Birth, Err>;
375
376pub type BehaviorActed<B> = Acted<
378 <B as Behavior>::Addr,
379 <B as Behavior>::Ph,
380 <B as Behavior>::Sends,
381 <B as Behavior>::Birth,
382 <B as Behavior>::Error,
383>;
384
385pub trait State<Out = Never, Birth = NoBirths, Err = Never>
386where
387 Birth: BirthMode,
388{
389 type Addr: Address;
390 type Msg;
391
392 #[allow(
397 clippy::type_complexity,
398 reason = "the alias exposes all state protocol seats"
399 )]
400 fn handle(
401 &mut self,
402 from: Self::Addr,
403 message: Self::Msg,
404 ) -> StateActed<Self::Addr, Out, Birth, Err>;
405}
406
407pub trait Behavior {
420 type Addr: Address;
421 type Msg;
422 type Event: UserEvent<Addr = Self::Addr, Message = Self::Msg>;
423 type Sends: SendAlgebra;
424 type Ph;
425 type Error;
426 type Birth: BirthMode;
427
428 fn init(&mut self) -> impl Future<Output = BehaviorActed<Self>> + Send;
429
430 fn step(&mut self, event: Self::Event) -> impl Future<Output = BehaviorActed<Self>> + Send;
431}
432
433pub struct Base<S: State<O, Br, E>, O = Never, Br: BirthMode = NoBirths, E = Never> {
434 state: S,
435 marker: PhantomData<fn(O, Br, E)>,
436}
437
438impl<S: State<O, Br, E>, O, Br: BirthMode, E> Base<S, O, Br, E> {
439 #[must_use]
440 pub fn new(state: S) -> Self {
441 Self {
442 state,
443 marker: PhantomData,
444 }
445 }
446
447 #[must_use]
448 pub fn state(&self) -> &S {
449 &self.state
450 }
451}
452
453pub type Transition<S, A, M, O, Br, E> =
454 fn(&mut S, A, M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E>;
455
456pub struct FnState<S, A: Address, M, O = Never, Br: BirthMode = NoBirths, E = Never> {
457 pub state: S,
458 pub handle: Transition<S, A, M, O, Br, E>,
459}
460
461impl<S, A: Address, M, O, Br: BirthMode, E> State<O, Br, E> for FnState<S, A, M, O, Br, E> {
462 type Addr = A;
463 type Msg = M;
464
465 fn handle(&mut self, from: A, message: M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E> {
466 (self.handle)(&mut self.state, from, message)
467 }
468}
469
470impl<S, A: Address, M, O, Br: BirthMode, E> Base<FnState<S, A, M, O, Br, E>, O, Br, E> {
471 #[must_use]
472 pub fn from_fn(state: S, handle: Transition<S, A, M, O, Br, E>) -> Self {
473 Self::new(FnState { state, handle })
474 }
475}
476
477impl<A: Address, M> UserEvent for User<A, M> {
478 type Addr = A;
479 type Message = M;
480
481 fn user(from: A, message: M) -> Self {
482 Self { from, message }
483 }
484
485 fn into_user(self) -> Result<Self, Self> {
486 Ok(self)
487 }
488}
489
490impl<A: Address, M> TimeEvent for User<A, M> {
491 fn time_reached(_: TimerElapsed) -> Option<Self> {
492 None
493 }
494}
495
496impl<A: Address, M> PeerEvent<A> for User<A, M> {
497 fn peer_stopped(_: PeerStopped<A>) -> Option<Self> {
498 None
499 }
500}
501
502impl<A: Address, M> ChildEvent<A> for User<A, M> {
503 fn child_stopped(_: ChildStopped<A>) -> Option<Self> {
504 None
505 }
506}
507
508impl<A: Address, M> WorkerEvent<A> for User<A, M> {
509 fn worker_stopped(_: WorkerStopped<A>) -> Option<Self> {
510 None
511 }
512}
513
514impl<A: Address, M> ShutdownEvent for User<A, M> {
515 fn shutdown_requested(_: ShutdownRequested) -> Option<Self> {
516 None
517 }
518}
519
520impl<S, O, Br, E> Behavior for Base<S, O, Br, E>
521where
522 S: State<O, Br, E> + Send,
523 S::Addr: Send,
524 S::Msg: Send,
525 Br: BirthMode,
526 Br::Child: Send,
527 E: Send,
528{
529 type Addr = S::Addr;
530 type Msg = S::Msg;
531 type Event = User<S::Addr, S::Msg>;
532 type Sends = Vec<Delivery<S::Addr, O>>;
533 type Ph = Never;
534 type Error = E;
535 type Birth = Br;
536
537 async fn init(&mut self) -> StateActed<S::Addr, O, Br, E> {
538 Ok(Actions::cont())
539 }
540
541 async fn step(&mut self, event: Self::Event) -> StateActed<S::Addr, O, Br, E> {
542 self.state.handle(event.from, event.message)
543 }
544}
545
546pub struct Transcript<A: Address, Sends, New> {
547 pub sends: Sends,
548 pub creates: Vec<Create<A, New>>,
549 pub exit: Exit<A>,
550}
551
552pub async fn run<B, C, A, Sends, Br>(
557 mut behavior: B,
558 mut mailbox: Consumer<C, B::Msg>,
559 from: A,
560) -> Result<Transcript<A, Sends, Br::Child>, B::Error>
561where
562 A: Address,
563 Sends: SendAlgebra,
564 Br: BirthMode,
565 B: Behavior<Addr = A, Ph = Never, Sends = Sends, Birth = Br>,
566{
567 let mut sends = Sends::empty();
568 let mut creates = Vec::new();
569 let initial = behavior.init().await?;
570 sends.append(initial.sends);
571 creates.extend(initial.creates);
572 match initial.become_ {
573 Step::Continue => {}
574 Step::Goto(never) => match never {},
575 Step::Stop(exit) => {
576 return Ok(Transcript {
577 sends,
578 creates,
579 exit,
580 });
581 }
582 }
583 while let Some(received) = mailbox.recv().await {
584 let Received::User(message) = received else {
585 continue;
586 };
587 let actions = behavior.step(B::Event::user(from, message)).await?;
588 sends.append(actions.sends);
589 creates.extend(actions.creates);
590 match actions.become_ {
591 Step::Continue => {}
592 Step::Goto(never) => match never {},
593 Step::Stop(exit) => {
594 return Ok(Transcript {
595 sends,
596 creates,
597 exit,
598 });
599 }
600 }
601 }
602 Ok(Transcript {
603 sends,
604 creates,
605 exit: Exit::Collected,
606 })
607}