use std::future::Future;
use crate::context::Context;
mod handle;
pub mod builder;
pub mod service;
pub mod spawnable;
pub(crate) mod restart_strategy;
pub(crate) use handle::{ActorHandle, JoinFuture};
pub use restart_strategy::RestartableActor;
pub type DynResult<T = ()> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
pub trait Actor: Sized + Send + 'static {
const NAME: &'static str = "hannibal::Actor";
#[allow(unused)]
fn started(&mut self, ctx: &mut Context<Self>) -> impl Future<Output = DynResult> + Send {
async { Ok(()) }
}
#[allow(unused)]
fn stopped(&mut self, ctx: &mut Context<Self>) -> impl Future<Output = ()> + Send {
async {}
}
#[allow(unused)]
fn cancelled(&mut self, ctx: &mut Context<Self>) -> impl Future<Output = ()> + Send {
async {}
}
}
#[cfg(test)]
pub mod tests {
pub struct Ping;
pub struct Pong;
impl crate::Message for Ping {
type Response = Pong;
}
pub struct Identify;
impl crate::Message for Identify {
type Response = usize;
}
use crate::{
Handler, Service,
actor::{Actor, Context},
};
#[derive(Debug)]
pub struct TokioActor<T: Send + Sync>(pub usize, pub std::marker::PhantomData<T>);
impl<T: Send + Sync + Default> TokioActor<T> {
pub fn new(value: usize) -> Self {
Self(value, Default::default())
}
}
thread_local! {
static COUNTER: std::cell::RefCell<usize> = const { std::cell::RefCell::new(0) };
}
impl<T: Send + Sync + Default> Default for TokioActor<T> {
fn default() -> Self {
let id = COUNTER.with(|c| {
let mut counter = c.borrow_mut();
let id = *counter;
*counter += 1;
id
});
log::info!("new default {} {id}", std::any::type_name::<Self>());
Self(id, Default::default())
}
}
impl<T: Send + Sync + Default + 'static> Actor for TokioActor<T> {}
impl<T: Send + Sync + Default + 'static> Service for TokioActor<T> {}
impl<T: Send + Sync + Default + 'static> Handler<Ping> for TokioActor<T> {
async fn handle(&mut self, _ctx: &mut Context<Self>, _msg: Ping) -> Pong {
Pong
}
}
impl<T: Send + Sync + Default + 'static> Handler<Identify> for TokioActor<T> {
async fn handle(&mut self, _ctx: &mut Context<Self>, _msg: Identify) -> usize {
self.0
}
}
}