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
|
use std::collections::HashMap;
use jid::BareJID;
use tokio::sync::mpsc::{self, Receiver};
use uuid::Uuid;
use crate::message::MacawMessage;
pub struct MessageSubscriptions {
all: HashMap<Uuid, mpsc::Sender<(BareJID, MacawMessage)>>,
subset: HashMap<BareJID, HashMap<Uuid, mpsc::Sender<MacawMessage>>>,
}
impl MessageSubscriptions {
pub fn new() -> Self {
Self {
all: HashMap::new(),
subset: HashMap::new(),
}
}
pub async fn broadcast(&mut self, to: BareJID, message: MacawMessage) {
// subscriptions to all
let mut removals = Vec::new();
for (id, sender) in &self.all {
match sender.send((to.clone(), message.clone())).await {
Ok(_) => {}
Err(_) => {
removals.push(*id);
}
}
}
for removal in removals {
self.all.remove(&removal);
}
// subscriptions to specific chat
if let Some(subscribers) = self.subset.get_mut(&to) {
let mut removals = Vec::new();
for (id, sender) in &*subscribers {
match sender.send(message.clone()).await {
Ok(_) => {}
Err(_) => {
removals.push(*id);
}
}
}
for removal in removals {
subscribers.remove(&removal);
}
if subscribers.is_empty() {
self.subset.remove(&to);
}
}
}
pub fn subscribe_all(&mut self) -> (Uuid, Receiver<(BareJID, MacawMessage)>) {
let (send, recv) = mpsc::channel(10);
let id = Uuid::new_v4();
self.all.insert(id, send);
(id, recv)
}
pub fn subscribe_chat(&mut self, chat: BareJID) -> (Uuid, Receiver<MacawMessage>) {
let (send, recv) = mpsc::channel(10);
let id = Uuid::new_v4();
if let Some(chat_subscribers) = self.subset.get_mut(&chat) {
chat_subscribers.insert(id, send);
} else {
let hash_map = HashMap::from([(id, send)]);
self.subset.insert(chat, hash_map);
}
(id, recv)
}
pub fn unsubscribe_all(&mut self, sub_id: Uuid) {
self.all.remove(&sub_id);
}
pub fn unsubscribe_chat(&mut self, sub_id: Uuid, chat: BareJID) {
if let Some(chat_subs) = self.subset.get_mut(&chat) {
chat_subs.remove(&sub_id);
}
}
}
|