1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
use std::sync::Arc; pub use act_zero_macro::act_zero; use futures::task::{Spawn, SpawnError}; mod addr; pub mod async_fn; mod channel; pub mod remote; pub mod sync; pub mod utils; pub use addr::{Addr, AddrExt, WeakAddr}; pub use channel::{channel, Receiver, Sender, SenderExt}; use async_fn::{AsyncFnOnce, AsyncMutFnOnce}; use utils::IntoResult; pub struct Local<T: Actor> { actor: sync::RwLock<T>, } pub trait Handle<M: Send + 'static> { fn handle(&self, msg: M); } impl<T: Actor + Sync> Local<T> { pub fn send<F>(&self, f: F) where F: AsyncFnOnce<T> + Send + 'static, F::Output: IntoResult<(), T::Error>, { self.actor.run(f.map(|res, actor| { (if let Err(e) = res.into_result() { actor.errored(e) } else { false }) || actor.should_terminate() })); } pub fn send_mut<F>(&self, f: F) where F: AsyncMutFnOnce<T> + Send + 'static, F::Output: IntoResult<(), T::Error>, { self.actor.run_mut(f.map(|res, actor| { (if let Err(e) = res.into_result() { actor.errored_mut(e) } else { false }) || actor.should_terminate() })); } } pub trait Actor: Send + Sync + 'static { type Error: Send + 'static; fn started(&mut self, _addr: Addr<Local<Self>>) -> Result<(), Self::Error> where Self: Sized, { Ok(()) } fn errored(&self, _error: Self::Error) -> bool { false } fn errored_mut(&mut self, error: Self::Error) -> bool { self.errored(error); true } fn should_terminate(&self) -> bool { false } } pub fn spawn<S: Spawn, T: Actor>(spawner: &S, actor: T) -> Result<Addr<Local<T>>, SpawnError> { let addr = Addr(Some(Arc::new(Local { actor: sync::RwLock::new(spawner, actor)?, }))); async fn call_started<T: Actor>(actor: &mut T, addr: Addr<Local<T>>) -> Result<(), T::Error> { actor.started(addr) } addr.with(|inner| inner.send_mut(async_fn::Closure::new(call_started, addr.clone()))); Ok(addr) } #[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } }