use std::fmt::Debug;
use std::hash::{Hash, Hasher};
use std::rc::Rc;
use downcast_rs::{impl_downcast, Downcast};
use dyn_clone::{clone_trait_object, DynClone};
use crate::{Context, Message};
pub trait Process: DynClone {
fn on_message(&mut self, msg: Message, from: String, ctx: &mut Context) -> Result<(), String>;
fn on_local_message(&mut self, msg: Message, ctx: &mut Context) -> Result<(), String>;
fn on_timer(&mut self, timer: String, ctx: &mut Context) -> Result<(), String>;
fn max_size(&mut self) -> u64 {
0
}
fn state(&self) -> Result<Rc<dyn ProcessState>, String> {
Ok(Rc::new(EmptyProcessState {}))
}
fn set_state(&mut self, _state: Rc<dyn ProcessState>) -> Result<(), String> {
Ok(())
}
}
clone_trait_object!(Process);
pub trait ProcessState: Downcast + Debug {
fn hash_with_dyn(&self, hasher: &mut dyn Hasher);
fn eq_with_dyn(&self, other: &dyn ProcessState) -> bool;
}
impl_downcast!(ProcessState);
#[derive(Debug, Hash, Eq, PartialEq)]
pub struct EmptyProcessState {}
pub type StringProcessState = String;
impl<T: Hash + Eq + Debug + 'static> ProcessState for T {
fn hash_with_dyn(&self, mut hasher: &mut dyn Hasher) {
self.hash(&mut hasher);
}
fn eq_with_dyn(&self, other: &dyn ProcessState) -> bool {
if let Some(other) = other.downcast_ref::<T>() {
self.eq(other)
} else {
false
}
}
}