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)]
35pub enum Route<A: Address> {
36 Global(A),
37 Child(A::Nonce),
38}
39
40pub struct Recipient<A: Address, M> {
42 route: Route<A>,
43 message: PhantomData<fn(M)>,
44}
45
46impl<A: Address, M> Copy for Recipient<A, M> {}
47
48impl<A: Address, M> Clone for Recipient<A, M> {
49 fn clone(&self) -> Self {
50 *self
51 }
52}
53
54impl<A: Address, M> Recipient<A, M> {
55 #[must_use]
56 pub fn global(address: A) -> Self {
57 Self::from_route(Route::Global(address))
58 }
59
60 #[must_use]
61 pub fn child(nonce: A::Nonce) -> Self {
62 Self::from_route(Route::Child(nonce))
63 }
64
65 #[must_use]
66 pub fn route(self) -> Route<A> {
67 self.route
68 }
69
70 const fn from_route(route: Route<A>) -> Self {
71 Self {
72 route,
73 message: PhantomData,
74 }
75 }
76}
77
78#[derive(Clone, PartialEq, Eq)]
80pub struct Delivery<A: Address, M> {
81 pub to: Recipient<A, M>,
82 pub message: M,
83}
84
85impl<A: Address, M> Delivery<A, M> {
86 #[must_use]
87 pub fn new(to: Recipient<A, M>, message: M) -> Self {
88 Self { to, message }
89 }
90}
91
92impl<A: Address, M> PartialEq for Recipient<A, M> {
93 fn eq(&self, other: &Self) -> bool {
94 self.route == other.route
95 }
96}
97
98impl<A: Address, M> Eq for Recipient<A, M> {}
99
100impl<A: Address + core::fmt::Debug, M> core::fmt::Debug for Recipient<A, M>
101where
102 A::Nonce: core::fmt::Debug,
103{
104 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
105 self.route.fmt(f)
106 }
107}
108
109#[derive(Debug, Clone, PartialEq, Eq)]
111pub struct SendProduct<L, R> {
112 pub inner: L,
113 pub own: R,
114}
115
116pub trait SendAlgebra: Sized {
118 fn empty() -> Self;
119 fn append(&mut self, other: Self);
120}
121
122impl<T> SendAlgebra for Vec<T> {
123 fn empty() -> Self {
124 Vec::new()
125 }
126
127 fn append(&mut self, mut other: Self) {
128 Vec::append(self, &mut other);
129 }
130}
131
132impl<L: SendAlgebra, R: SendAlgebra> SendAlgebra for SendProduct<L, R> {
133 fn empty() -> Self {
134 Self {
135 inner: L::empty(),
136 own: R::empty(),
137 }
138 }
139
140 fn append(&mut self, other: Self) {
141 self.inner.append(other.inner);
142 self.own.append(other.own);
143 }
144}
145
146#[derive(Debug, Clone, PartialEq, Eq)]
153pub struct ServiceSends<M> {
154 requests: Vec<M>,
155}
156
157impl<M> ServiceSends<M> {
158 #[must_use]
159 pub fn new(requests: Vec<M>) -> Self {
160 Self { requests }
161 }
162
163 #[must_use]
164 pub fn one(request: M) -> Self {
165 Self::new(vec![request])
166 }
167
168 #[must_use]
169 pub fn as_slice(&self) -> &[M] {
170 &self.requests
171 }
172
173 pub fn iter(&self) -> core::slice::Iter<'_, M> {
174 self.requests.iter()
175 }
176
177 #[must_use]
178 pub fn len(&self) -> usize {
179 self.requests.len()
180 }
181
182 #[must_use]
183 pub fn is_empty(&self) -> bool {
184 self.requests.is_empty()
185 }
186
187 pub fn extend(&mut self, requests: impl IntoIterator<Item = M>) {
188 self.requests.extend(requests);
189 }
190
191 #[must_use]
192 pub fn into_requests(self) -> Vec<M> {
193 self.requests
194 }
195}
196
197impl<M> core::ops::Index<usize> for ServiceSends<M> {
198 type Output = M;
199
200 fn index(&self, index: usize) -> &Self::Output {
201 &self.requests[index]
202 }
203}
204
205impl<M> IntoIterator for ServiceSends<M> {
206 type Item = M;
207 type IntoIter = std::vec::IntoIter<M>;
208
209 fn into_iter(self) -> Self::IntoIter {
210 self.requests.into_iter()
211 }
212}
213
214impl<M> SendAlgebra for ServiceSends<M> {
215 fn empty() -> Self {
216 Self::new(Vec::new())
217 }
218
219 fn append(&mut self, mut other: Self) {
220 self.requests.append(&mut other.requests);
221 }
222}
223
224#[derive(Debug, Clone, PartialEq, Eq)]
227pub struct Create<A: Address, New> {
228 pub nonce: A::Nonce,
229 pub child: New,
230}
231
232pub trait BirthMode {
234 type Child;
235}
236
237#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
239pub struct NoBirths;
240
241impl BirthMode for NoBirths {
242 type Child = Never;
243}
244
245#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
247pub struct Births<C>(PhantomData<fn() -> C>);
248
249impl<C> BirthMode for Births<C> {
250 type Child = C;
251}
252
253pub type Become<A, Ph = Never> = Step<Ph, Exit<A>>;
254
255pub struct Actions<A: Address, Ph, Sends, Birth: BirthMode> {
268 pub sends: Sends,
269 pub creates: Vec<Create<A, Birth::Child>>,
270 pub become_: Become<A, Ph>,
271}
272
273impl<A: Address, Ph, Sends: SendAlgebra, Birth: BirthMode> Actions<A, Ph, Sends, Birth> {
274 #[must_use]
275 pub fn just(become_: Become<A, Ph>) -> Self {
276 Self {
277 sends: Sends::empty(),
278 creates: Vec::new(),
279 become_,
280 }
281 }
282
283 #[must_use]
284 pub fn cont() -> Self {
285 Self::just(Step::Continue)
286 }
287
288 #[must_use]
289 pub fn stop(exit: Exit<A>) -> Self {
290 Self::just(Step::Stop(exit))
291 }
292
293 #[must_use]
294 pub fn goto(phase: Ph) -> Self {
295 Self::just(Step::Goto(phase))
296 }
297}
298
299pub type Acted<A, Ph, Sends, Birth, E> = Result<Actions<A, Ph, Sends, Birth>, E>;
300
301#[derive(Debug, Clone, PartialEq, Eq)]
303pub struct User<A, M> {
304 pub from: A,
305 pub message: M,
306}
307
308pub trait UserEvent: Sized {
310 type Addr: Address;
311 type Message;
312
313 fn user(from: Self::Addr, message: Self::Message) -> Self;
314 fn into_user(self) -> Result<User<Self::Addr, Self::Message>, Self>;
319}
320
321pub type StateActed<A, Out, Birth, Err> = Acted<A, Never, Vec<Delivery<A, Out>>, Birth, Err>;
322
323pub trait State<Out = Never, Birth = NoBirths, Err = Never>
324where
325 Birth: BirthMode,
326{
327 type Addr: Address;
328 type Msg;
329
330 #[allow(
335 clippy::type_complexity,
336 reason = "the alias exposes all state protocol seats"
337 )]
338 fn handle(
339 &mut self,
340 from: Self::Addr,
341 message: Self::Msg,
342 ) -> StateActed<Self::Addr, Out, Birth, Err>;
343}
344
345pub trait Behavior {
348 type Addr: Address;
349 type Msg;
350 type Event: UserEvent<Addr = Self::Addr, Message = Self::Msg>;
351 type Sends: SendAlgebra;
352 type Ph;
353 type Error;
354 type Birth: BirthMode;
355 type Effect;
356 type Done;
357
358 fn init(&mut self) -> impl Future<Output = Result<Self::Effect, Self::Error>> + Send;
359
360 fn step(
361 &mut self,
362 event: Self::Event,
363 ) -> impl Future<Output = Result<Self::Effect, Self::Error>> + Send;
364}
365
366pub struct Base<S: State<O, Br, E>, O = Never, Br: BirthMode = NoBirths, E = Never> {
367 state: S,
368 marker: PhantomData<fn(O, Br, E)>,
369}
370
371impl<S: State<O, Br, E>, O, Br: BirthMode, E> Base<S, O, Br, E> {
372 #[must_use]
373 pub fn new(state: S) -> Self {
374 Self {
375 state,
376 marker: PhantomData,
377 }
378 }
379
380 #[must_use]
381 pub fn state(&self) -> &S {
382 &self.state
383 }
384}
385
386pub type Transition<S, A, M, O, Br, E> =
387 fn(&mut S, A, M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E>;
388
389pub struct FnState<S, A: Address, M, O = Never, Br: BirthMode = NoBirths, E = Never> {
390 pub state: S,
391 pub handle: Transition<S, A, M, O, Br, E>,
392}
393
394impl<S, A: Address, M, O, Br: BirthMode, E> State<O, Br, E> for FnState<S, A, M, O, Br, E> {
395 type Addr = A;
396 type Msg = M;
397
398 fn handle(&mut self, from: A, message: M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E> {
399 (self.handle)(&mut self.state, from, message)
400 }
401}
402
403impl<S, A: Address, M, O, Br: BirthMode, E> Base<FnState<S, A, M, O, Br, E>, O, Br, E> {
404 #[must_use]
405 pub fn from_fn(state: S, handle: Transition<S, A, M, O, Br, E>) -> Self {
406 Self::new(FnState { state, handle })
407 }
408}
409
410impl<A: Address, M> UserEvent for User<A, M> {
411 type Addr = A;
412 type Message = M;
413
414 fn user(from: A, message: M) -> Self {
415 Self { from, message }
416 }
417
418 fn into_user(self) -> Result<Self, Self> {
419 Ok(self)
420 }
421}
422
423impl<A: Address, M> TimeEvent for User<A, M> {
424 fn time_reached(_: TimeReached) -> Option<Self> {
425 None
426 }
427}
428
429impl<A: Address, M> PeerEvent<A> for User<A, M> {
430 fn peer_stopped(_: PeerStopped<A>) -> Option<Self> {
431 None
432 }
433}
434
435impl<A: Address, M> ChildEvent<A> for User<A, M> {
436 fn child_stopped(_: ChildStopped<A>) -> Option<Self> {
437 None
438 }
439}
440
441impl<S, O, Br, E> Behavior for Base<S, O, Br, E>
442where
443 S: State<O, Br, E> + Send,
444 S::Addr: Send,
445 S::Msg: Send,
446 Br: BirthMode,
447 Br::Child: Send,
448 E: Send,
449{
450 type Addr = S::Addr;
451 type Msg = S::Msg;
452 type Event = User<S::Addr, S::Msg>;
453 type Sends = Vec<Delivery<S::Addr, O>>;
454 type Ph = Never;
455 type Error = E;
456 type Birth = Br;
457 type Effect = Actions<S::Addr, Never, Self::Sends, Br>;
458 type Done = Exit<S::Addr>;
459
460 async fn init(&mut self) -> Result<Self::Effect, E> {
461 Ok(Actions::cont())
462 }
463
464 async fn step(&mut self, event: Self::Event) -> Result<Self::Effect, E> {
465 self.state.handle(event.from, event.message)
466 }
467}
468
469pub struct Transcript<A: Address, Sends, New> {
470 pub sends: Sends,
471 pub creates: Vec<Create<A, New>>,
472 pub exit: Exit<A>,
473}
474
475pub async fn run<B, C, A, Sends, Br>(
480 mut behavior: B,
481 mut mailbox: Consumer<C, B::Msg>,
482 from: A,
483) -> Result<Transcript<A, Sends, Br::Child>, B::Error>
484where
485 A: Address,
486 Sends: SendAlgebra,
487 Br: BirthMode,
488 B: Behavior<
489 Addr = A,
490 Ph = Never,
491 Sends = Sends,
492 Birth = Br,
493 Effect = Actions<A, Never, Sends, Br>,
494 Done = Exit<A>,
495 >,
496{
497 let mut sends = Sends::empty();
498 let mut creates = Vec::new();
499 let initial = behavior.init().await?;
500 sends.append(initial.sends);
501 creates.extend(initial.creates);
502 match initial.become_ {
503 Step::Continue => {}
504 Step::Goto(never) => match never {},
505 Step::Stop(exit) => {
506 return Ok(Transcript {
507 sends,
508 creates,
509 exit,
510 });
511 }
512 }
513 while let Some(received) = mailbox.recv().await {
514 let Received::User(message) = received else {
515 continue;
516 };
517 let actions = behavior.step(B::Event::user(from, message)).await?;
518 sends.append(actions.sends);
519 creates.extend(actions.creates);
520 match actions.become_ {
521 Step::Continue => {}
522 Step::Goto(never) => match never {},
523 Step::Stop(exit) => {
524 return Ok(Transcript {
525 sends,
526 creates,
527 exit,
528 });
529 }
530 }
531 }
532 Ok(Transcript {
533 sends,
534 creates,
535 exit: Exit::Collected,
536 })
537}