/// https://z0ltan.wordpress.com/2017/06/23/the-observer-pattern-in-rust/
extern crate rand;
trait Observable<T> {
fn register(&mut self, observer: Box<Observer<Item = T>>);
}
trait Observer {
type Item;
fn notify(&self, val: &Self::Item);
}
struct EvenCounter {
counter: u32,
observers: Vec<Box<Observer<Item = u32>>>,
}
impl EvenCounter {
fn new() -> Self {
EvenCounter {
counter: 0u32,
observers: Vec::new(),
}
}
fn run(&mut self) {
loop {
use std::thread;
use std::time::Duration;
thread::sleep(Duration::from_millis(self.get_rand_duration()));
self.counter += 1;
if self.counter % 2 == 0 {
for observer in self.observers.iter() {
observer.notify(&self.counter);
}
}
}
}
fn get_rand_duration(&self) -> u64 {
use rand::{Rng, thread_rng};
let mut rng = thread_rng();
rng.gen_range(0, 1000)
}
}
impl Observable<u32> for EvenCounter {
fn register(&mut self, observer: Box<Observer<Item = u32>>) {
self.observers.push(observer);
}
}
struct EvenObserver {
name: String,
}
impl EvenObserver {
fn new(name: String) -> Self {
EvenObserver { name }
}
fn name(&self) -> &str {
&self.name
}
}
impl Observer for EvenObserver {
type Item = u32;
fn notify(&self, val: &Self::Item) {
println!("'{}' got: {}", self.name(), val);
}
}
fn main() {
let mut foo = EvenCounter::new();
let (bar, baz, quux) = (Box::new(EvenObserver::new("bar".to_string())),
Box::new(EvenObserver::new("baz".to_string())),
Box::new(EvenObserver::new("quux".to_string())));
foo.register(bar);
foo.register(baz);
foo.register(quux);
foo.run();
}