use heph::actor::{self, NewActor};
use heph::actor_ref::ActorRef;
use heph::supervisor::Supervisor;
pub mod options;
pub(crate) use private::{AddActorError, PrivateSpawn};
#[doc(no_inline)]
pub use options::{ActorOptions, FutureOptions, SyncActorOptions};
pub trait Spawn<S, NA, RT>: PrivateSpawn<S, NA, RT> {
fn try_spawn(
&mut self,
supervisor: S,
new_actor: NA,
arg: NA::Argument,
options: ActorOptions,
) -> Result<ActorRef<NA::Message>, NA::Error>
where
S: Supervisor<NA>,
NA: NewActor<RuntimeAccess = RT>,
{
self.try_spawn_setup(supervisor, new_actor, |_| Ok(arg), options)
.map_err(|err| match err {
AddActorError::NewActor(err) => err,
AddActorError::<_, !>::ArgFn(_) => unreachable!(),
})
}
fn spawn(
&mut self,
supervisor: S,
new_actor: NA,
arg: NA::Argument,
options: ActorOptions,
) -> ActorRef<NA::Message>
where
S: Supervisor<NA>,
NA: NewActor<Error = !, RuntimeAccess = RT>,
{
self.try_spawn_setup(supervisor, new_actor, |_| Ok(arg), options)
.unwrap_or_else(|_: AddActorError<!, !>| unreachable!())
}
}
mod private {
use heph::actor::{self, NewActor};
use heph::actor_ref::ActorRef;
use heph::supervisor::Supervisor;
use crate::spawn::ActorOptions;
pub trait PrivateSpawn<S, NA, RT> {
#[allow(clippy::type_complexity)] fn try_spawn_setup<ArgFn, E>(
&mut self,
supervisor: S,
new_actor: NA,
arg_fn: ArgFn,
options: ActorOptions,
) -> Result<ActorRef<NA::Message>, AddActorError<NA::Error, E>>
where
S: Supervisor<NA>,
NA: NewActor<RuntimeAccess = RT>,
ArgFn: FnOnce(&mut actor::Context<NA::Message, RT>) -> Result<NA::Argument, E>;
}
#[derive(Debug)]
pub enum AddActorError<NewActorE, ArgFnE> {
NewActor(NewActorE),
ArgFn(ArgFnE),
}
}
impl<M, RT, S, NA, RT2> Spawn<S, NA, RT2> for actor::Context<M, RT> where RT: Spawn<S, NA, RT2> {}
impl<M, RT, S, NA, RT2> PrivateSpawn<S, NA, RT2> for actor::Context<M, RT>
where
RT: PrivateSpawn<S, NA, RT2>,
{
fn try_spawn_setup<ArgFn, E>(
&mut self,
supervisor: S,
new_actor: NA,
arg_fn: ArgFn,
options: ActorOptions,
) -> Result<ActorRef<NA::Message>, AddActorError<NA::Error, E>>
where
S: Supervisor<NA>,
NA: NewActor<RuntimeAccess = RT2>,
ArgFn: FnOnce(&mut actor::Context<NA::Message, RT2>) -> Result<NA::Argument, E>,
{
self.runtime()
.try_spawn_setup(supervisor, new_actor, arg_fn, options)
}
}