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

pub struct Store<M, S> {
    key: i64,
    model: M,
    update: fn(S, M) -> M,
    subscriptions: Vec<Subscribe<M>>,
}

pub struct Subscribe<M> {
    key: i64,
    subscribe: fn(&M),
}

impl<M: Clone + PartialEq, S> Store<M, S> {
    pub fn new(model: M, update: fn(S, M) -> M) -> Store<M, S> {
        Store {
            key: 0,
            model: model,
            update: update,
            subscriptions: vec![],
        }
    }

    pub fn dispatch(&mut self, msg: S) {
        let new = (self.update)(msg, self.model.clone());
        if new != self.model {
            self.model = new;
            self.run();
        }
    }

    pub fn run(&self) {
        for sub in &self.subscriptions {
            (sub.subscribe)(&self.model)
        }
    }

    pub fn subscribe(&mut self, sub: fn(&M)) -> i64 {
        self.key += 1;
        self.subscriptions.push(Subscribe {
            key: self.key,
            subscribe: sub,
        });
        return self.key;
    }

    pub fn unsubscribe(&mut self, sub: i64) {
        let index = self.subscriptions.iter().position(|x| x.key == sub);
        if let Some(i) = index {
            self.subscriptions.remove(i);
        }
    }
}