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
use crate::handlers::Action;
use crate::ids::Id;
use crate::linkage::recipient::ActionRecipient;
use anyhow::Error;
use std::collections::HashMap;
#[derive(Debug)]
pub struct Distributor<T> {
recipients: HashMap<Id, Box<dyn ActionRecipient<T>>>,
}
impl<T> Default for Distributor<T> {
fn default() -> Self {
Self {
recipients: HashMap::new(),
}
}
}
impl<T> Distributor<T> {
pub fn new() -> Self {
Self::default()
}
}
impl<T> Distributor<T>
where
T: Action + Clone,
{
pub fn insert(&mut self, recipient: Box<dyn ActionRecipient<T>>) {
let id = recipient.id_ref().to_owned();
self.recipients.insert(id, recipient);
}
pub fn remove(&mut self, id: &Id) -> Option<Box<dyn ActionRecipient<T>>> {
self.recipients.remove(id)
}
pub async fn act_all(&mut self, action: T) -> Result<(), Error> {
let futs = self
.recipients
.values_mut()
.map(|recipient| recipient.act(action.clone()));
let err = futures::future::join_all(futs)
.await
.into_iter()
.find(Result::is_err);
if let Some(Err(err)) = err {
Err(err)
} else {
Ok(())
}
}
pub fn len(&self) -> usize {
self.recipients.len()
}
pub fn is_empty(&self) -> bool {
self.recipients.is_empty()
}
}