use core::marker::PhantomData;
use super::user_event::{EventInput, User, UserEvent};
use crate::actor::{Address, BirthMode, Delivery, NoBirths};
use crate::effects::{Acted, Actions, SendAlgebra};
use crate::next::Never;
pub type StateActed<A, Out, Birth, Err> = Acted<A, Never, Vec<Delivery<A, Out>>, Birth, Err>;
pub type BehaviorActed<B> = Acted<
<B as Behavior>::Addr,
<B as Behavior>::Ph,
<B as Behavior>::Sends,
<B as Behavior>::Birth,
<B as Behavior>::Error,
>;
pub trait Handler<Out = Never, Birth = NoBirths, Err = Never>
where
Birth: BirthMode,
{
type Addr: Address;
type Msg;
#[allow(
clippy::type_complexity,
reason = "the alias exposes all state protocol seats"
)]
fn receive(
&mut self,
from: Self::Addr,
message: Self::Msg,
) -> StateActed<Self::Addr, Out, Birth, Err>;
}
pub trait Behavior {
type Addr: Address;
type Msg;
type Event: UserEvent<Addr = Self::Addr, Message = Self::Msg>;
type Sends: SendAlgebra;
type Ph;
type Error;
type Birth: BirthMode;
fn init(&mut self) -> BehaviorActed<Self>;
fn transition(&mut self, event: Self::Event) -> BehaviorActed<Self>;
fn receive(&mut self, from: Self::Addr, message: Self::Msg) -> BehaviorActed<Self>
where
Self: Sized,
{
self.transition(Self::Event::user(from, message))
}
fn on<Input>(&mut self, input: Input) -> BehaviorActed<Self>
where
Self: Sized,
Self::Event: EventInput<Input>,
{
self.transition(Self::Event::inject(input))
}
}
pub fn delegate_transition<B: Behavior>(behavior: &mut B, event: B::Event) -> BehaviorActed<B> {
behavior.transition(event)
}
pub struct Pure<S: Handler<O, Br, E>, O = Never, Br: BirthMode = NoBirths, E = Never> {
state: S,
marker: PhantomData<fn(O, Br, E)>,
}
impl<S: Handler<O, Br, E>, O, Br: BirthMode, E> Pure<S, O, Br, E> {
#[must_use]
pub fn new(state: S) -> Self {
Self {
state,
marker: PhantomData,
}
}
#[must_use]
pub fn state(&self) -> &S {
&self.state
}
}
pub struct FoldFn<
S,
A: Address,
M,
O = Never,
Br: BirthMode = NoBirths,
E = Never,
F = fn(&mut S, A, M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E>,
> {
pub state: S,
pub transition: F,
#[allow(
clippy::type_complexity,
reason = "the marker retains the complete inferred behavior signature"
)]
marker: PhantomData<fn(A, M, O, Br, E)>,
}
pub struct BehaviorFn<S, A: Address, M, Sends, Br: BirthMode, E, I, F> {
state: S,
initialize: I,
transition: F,
#[allow(
clippy::type_complexity,
reason = "the marker retains the complete inferred behavior signature"
)]
marker: PhantomData<fn(A, M, Sends, Br, E)>,
}
impl<S, A: Address, M, Sends, Br: BirthMode, E, I, F> BehaviorFn<S, A, M, Sends, Br, E, I, F>
where
Sends: SendAlgebra,
I: FnMut(&mut S) -> Acted<A, Never, Sends, Br, E>,
F: FnMut(&mut S, A, M) -> Acted<A, Never, Sends, Br, E>,
{
#[must_use]
pub fn new(state: S, initialize: I, transition: F) -> Self {
Self {
state,
initialize,
transition,
marker: PhantomData,
}
}
#[must_use]
pub fn state(&self) -> &S {
&self.state
}
}
impl<S, A: Address, M, Sends, Br: BirthMode, E, I, F> Behavior
for BehaviorFn<S, A, M, Sends, Br, E, I, F>
where
Sends: SendAlgebra,
I: FnMut(&mut S) -> Acted<A, Never, Sends, Br, E>,
F: FnMut(&mut S, A, M) -> Acted<A, Never, Sends, Br, E>,
{
type Addr = A;
type Msg = M;
type Event = User<A, M>;
type Sends = Sends;
type Ph = Never;
type Error = E;
type Birth = Br;
fn init(&mut self) -> BehaviorActed<Self> {
(self.initialize)(&mut self.state)
}
fn transition(&mut self, event: Self::Event) -> BehaviorActed<Self> {
(self.transition)(&mut self.state, event.from, event.message)
}
}
impl<S, F, A: Address, M, O, Br: BirthMode, E> Handler<O, Br, E> for FoldFn<S, A, M, O, Br, E, F>
where
F: FnMut(&mut S, A, M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E>,
{
type Addr = A;
type Msg = M;
fn receive(&mut self, from: A, message: M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E> {
(self.transition)(&mut self.state, from, message)
}
}
impl<S, F, A: Address, M, O, Br: BirthMode, E> Pure<FoldFn<S, A, M, O, Br, E, F>, O, Br, E>
where
F: FnMut(&mut S, A, M) -> Acted<A, Never, Vec<Delivery<A, O>>, Br, E>,
{
#[must_use]
pub fn from_fn(state: S, transition: F) -> Self {
Self::new(FoldFn {
state,
transition,
marker: PhantomData,
})
}
}
impl<S, O, Br, E> Behavior for Pure<S, O, Br, E>
where
S: Handler<O, Br, E>,
Br: BirthMode,
{
type Addr = S::Addr;
type Msg = S::Msg;
type Event = User<S::Addr, S::Msg>;
type Sends = Vec<Delivery<S::Addr, O>>;
type Ph = Never;
type Error = E;
type Birth = Br;
fn init(&mut self) -> StateActed<S::Addr, O, Br, E> {
Ok(Actions::cont())
}
fn transition(&mut self, event: Self::Event) -> StateActed<S::Addr, O, Br, E> {
self.state.receive(event.from, event.message)
}
}