Skip to main content

behavior/fold/
behavior.rs

1//! Pure behavior folds from one typed event to explicit transition actions.
2
3use core::future::Future;
4use core::marker::PhantomData;
5
6use super::user_event::{User, UserEvent};
7use crate::actor::{Address, BirthMode, Delivery, NoBirths};
8use crate::transition::{Acted, Actions, SendAlgebra};
9use crate::verdict::Never;
10
11pub type StateActed<A, Out, Birth, Err> = Acted<A, Never, Vec<Delivery<A, Out>>, Birth, Err>;
12
13/// The only successful effect shape admitted by a [`Behavior`] implementation.
14pub type BehaviorActed<B> = Acted<
15    <B as Behavior>::Addr,
16    <B as Behavior>::Ph,
17    <B as Behavior>::Sends,
18    <B as Behavior>::Birth,
19    <B as Behavior>::Error,
20>;
21
22pub trait State<Out = Never, Birth = NoBirths, Err = Never>
23where
24    Birth: BirthMode,
25{
26    type Addr: Address;
27    type Msg;
28
29    /// Fold a user message into Bombay's typed actor transition effects.
30    ///
31    /// # Errors
32    /// Returns the state's declared controlled failure.
33    #[allow(
34        clippy::type_complexity,
35        reason = "the alias exposes all state protocol seats"
36    )]
37    fn handle(
38        &mut self,
39        from: Self::Addr,
40        message: Self::Msg,
41    ) -> StateActed<Self::Addr, Out, Birth, Err>;
42}
43
44/// A composed pure behavior. `Event` is the complete accepted protocol;
45/// every successful transition returns the declared [`Actions`] value.
46pub trait Behavior {
47    type Addr: Address;
48    type Msg;
49    type Event: UserEvent<Addr = Self::Addr, Message = Self::Msg>;
50    type Sends: SendAlgebra;
51    type Ph;
52    type Error;
53    type Birth: BirthMode;
54
55    fn init(&mut self) -> impl Future<Output = BehaviorActed<Self>> + Send;
56    fn step(&mut self, event: Self::Event) -> impl Future<Output = BehaviorActed<Self>> + Send;
57}
58
59pub struct Base<S: State<O, Br, E>, O = Never, Br: BirthMode = NoBirths, E = Never> {
60    state: S,
61    marker: PhantomData<fn(O, Br, E)>,
62}
63
64impl<S: State<O, Br, E>, O, Br: BirthMode, E> Base<S, O, Br, E> {
65    #[must_use]
66    pub fn new(state: S) -> Self {
67        Self {
68            state,
69            marker: PhantomData,
70        }
71    }
72    #[must_use]
73    pub fn state(&self) -> &S {
74        &self.state
75    }
76}
77
78pub type Transition<S, A, M, O, Br, E> =
79    fn(&mut S, A, M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E>;
80
81pub struct FnState<S, A: Address, M, O = Never, Br: BirthMode = NoBirths, E = Never> {
82    pub state: S,
83    pub handle: Transition<S, A, M, O, Br, E>,
84}
85
86impl<S, A: Address, M, O, Br: BirthMode, E> State<O, Br, E> for FnState<S, A, M, O, Br, E> {
87    type Addr = A;
88    type Msg = M;
89
90    fn handle(&mut self, from: A, message: M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E> {
91        (self.handle)(&mut self.state, from, message)
92    }
93}
94
95impl<S, A: Address, M, O, Br: BirthMode, E> Base<FnState<S, A, M, O, Br, E>, O, Br, E> {
96    #[must_use]
97    pub fn from_fn(state: S, handle: Transition<S, A, M, O, Br, E>) -> Self {
98        Self::new(FnState { state, handle })
99    }
100}
101
102impl<S, O, Br, E> Behavior for Base<S, O, Br, E>
103where
104    S: State<O, Br, E> + Send,
105    S::Addr: Send,
106    S::Msg: Send,
107    Br: BirthMode,
108    Br::Child: Send,
109    E: Send,
110{
111    type Addr = S::Addr;
112    type Msg = S::Msg;
113    type Event = User<S::Addr, S::Msg>;
114    type Sends = Vec<Delivery<S::Addr, O>>;
115    type Ph = Never;
116    type Error = E;
117    type Birth = Br;
118
119    async fn init(&mut self) -> StateActed<S::Addr, O, Br, E> {
120        Ok(Actions::cont())
121    }
122
123    async fn step(&mut self, event: Self::Event) -> StateActed<S::Addr, O, Br, E> {
124        self.state.handle(event.from, event.message)
125    }
126}