pub mod context;
pub mod handle;
pub(crate) mod panic;
pub mod runtime;
pub mod supervision;
use std::future::{Future, IntoFuture};
use std::pin::Pin;
use std::sync::Arc;
use crate::error::{ActorError, ActorResult, SpawnError};
use crate::system::ActorSystem;
use crate::types::{ChildEvent, Envelope, StopReason};
use context::ActorContext;
use runtime::ActorConfig;
use supervision::SupervisionConfig;
pub trait Actor: Sized + Send + 'static {
type Message: Send + 'static;
type Response: Send + 'static;
fn pre_start(
&mut self,
_ctx: &mut ActorContext<Self>,
) -> impl Future<Output = ActorResult<()>> + Send {
async { Ok(()) }
}
fn on_started(
&mut self,
_ctx: &mut ActorContext<Self>,
) -> impl Future<Output = ActorResult<()>> + Send {
async { Ok(()) }
}
fn handle(
&mut self,
msg: Self::Message,
ctx: &mut ActorContext<Self>,
) -> impl Future<Output = ActorResult<Self::Response>> + Send;
fn pre_stop(
&mut self,
_reason: &StopReason,
_ctx: &mut ActorContext<Self>,
) -> impl Future<Output = bool> + Send {
async { true }
}
fn on_stopped(
&mut self,
_reason: &StopReason,
_ctx: &mut ActorContext<Self>,
) -> impl Future<Output = ActorResult<()>> + Send {
async { Ok(()) }
}
fn on_child_stopped(
&mut self,
_event: &ChildEvent,
_ctx: &mut ActorContext<Self>,
) -> impl Future<Output = ActorResult<()>> + Send {
async { Ok(()) }
}
fn handle_failure(&mut self, _error: ActorError) {}
}
pub type ActorEnvelope<A> = Envelope<<A as Actor>::Message, <A as Actor>::Response>;
pub struct SpawnBuilder<A: Actor> {
actor: A,
name: Option<String>,
system: Option<Arc<ActorSystem>>,
config: ActorConfig,
}
impl<A: Actor> SpawnBuilder<A> {
pub fn named(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn on_system(mut self, system: &Arc<ActorSystem>) -> Self {
self.system = Some(Arc::clone(system));
self
}
pub fn with_config(mut self, config: ActorConfig) -> Self {
self.config = config;
self
}
pub fn supervisor(mut self) -> Self {
self.config = self.config.supervisor();
self
}
pub fn with_supervision(mut self, sup: SupervisionConfig) -> Self {
self.config = self.config.with_supervision(sup);
self
}
}
impl<A: Actor> IntoFuture for SpawnBuilder<A> {
type Output = Result<handle::ActorHandle<A>, SpawnError>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move {
let id_str = self
.name
.clone()
.unwrap_or_else(|| uuid::Uuid::new_v4().to_string());
runtime::into_actor(id_str, self.actor, self.config, self.name, self.system)
})
}
}
pub trait ActorExt: Actor + Sized {
fn spawn(self) -> SpawnBuilder<Self> {
SpawnBuilder {
actor: self,
name: None,
system: None,
config: ActorConfig::default(),
}
}
}
impl<T> ActorExt for T where T: Actor {}