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
extern crate serde_json;
use std::collections::HashMap;
use std::rc::Rc;

pub struct MessageExchange {
   boxes: HashMap<String, Vec<Inbox>>
}
impl MessageExchange {
   pub fn new() -> MessageExchange {
      MessageExchange {
         boxes: HashMap::new()
      }
   }
   pub fn publish(self, descriptor_prefix: &str) -> Outbox {
      Outbox {
         message_exchange: Box::new(self),
         descriptor_prefix: descriptor_prefix.to_string()
      }
   }
   pub fn subscribe(&mut self, selector_prefix: &str, inbox: &Inbox) {
      if !self.boxes.contains_key(selector_prefix) {
         self.boxes.insert(selector_prefix.to_string(), Vec::new());
      }
      self.boxes.get_mut(selector_prefix).unwrap().push((*inbox).clone());
   }
}

pub struct Outbox {
   message_exchange: Box<MessageExchange>,
   descriptor_prefix: String
}
impl Outbox {
   pub fn push(&self, descriptor_suffix: &str, msg: &serde_json::Value) {
       if let Some(inboxes) = self.message_exchange.boxes.get(&self.descriptor_prefix) {
          for inbox in inboxes.iter() {
             if descriptor_suffix == inbox.selector_suffix {
                (inbox.callback)(msg);
             }
          }
       }
   }
}

#[derive(Clone)]
pub struct Inbox {
   selector_suffix: String,
   callback: Rc<Box<dyn Fn(&serde_json::Value)>>
}
impl Inbox {
   pub fn new<F>(selector_suffix: &str, callback: F) -> Inbox
   where F: 'static + Fn(&serde_json::Value)
   {
      Inbox {
         selector_suffix: selector_suffix.to_string(),
         callback: Rc::new(Box::new(callback))
      }
   }
}