Created
December 17, 2018 20:53
-
-
Save CrowdHailer/f9f158f258799c35842a26ce67f85c6d to your computer and use it in GitHub Desktop.
Revisions
-
CrowdHailer created this gist
Dec 17, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,94 @@ mod actor { extern crate typemap; #[derive(Debug)] pub struct Envelop<For: Actor> { // TODO make fields private pub address: For::Id, pub message: For::Message } // This is more a description of the protocol than the Actor pub trait Actor { type Id; type Message; // This could be extracted to a Worker<Message> // For static dispatch an mocking just have an enum of real vs mocked // type State; fn init() -> Self; fn handle(self, message: Self::Message) -> (Deliverables, Self); } pub type Deliverables = Vec<Box<dyn Deliverable>>; pub trait Deliverable { fn deliver(self, states: &mut typemap::TypeMap); } pub struct System {states: typemap::TypeMap} impl System { pub fn new() -> Self { Self{states: typemap::TypeMap::new()} } pub fn apply<T: Actor + typemap::Key>(self, envelop: Envelop<T>) -> T { let actor = self.states.remove::<T>(); match actor { Some(actor) => actor, None => T::init() }.handle(envelop.message) } } } extern crate typemap; #[cfg(test)] mod tests { use crate::actor::{Actor, Envelop, Deliverables, System}; #[derive(Debug)] struct NormalCounter(i32); #[derive(Debug)] enum CounterMessage { Increment() } impl Actor for NormalCounter { type Id = (); type Message = CounterMessage; fn init() -> Self { NormalCounter(0) } fn handle(self, _: CounterMessage) -> (Deliverables, Self) { let updated = NormalCounter(self.0 + 1); // let messages = value; (vec![], updated) } } impl typemap::Key for NormalCounter { type Value = NormalCounter; } impl Envelop<NormalCounter> { fn deliver(self, system: System) -> NormalCounter { system.apply::<NormalCounter>(self) } } // #[derive(Debug)] #[test] fn it_works() { // let counter = NormalCounter::init(); // let counter = counter.handle(CounterMessage::Increment()); // println!("{:?}", counter); let system = System::new(); // println!("{:?}", system); let envelop: Envelop<NormalCounter> = Envelop{address: (), message: CounterMessage::Increment()}; println!("{:?}", envelop); envelop.deliver(system); assert_eq!(2 + 2, 3); } }