1use std::collections::HashMap;
2
3use crate::{AnnounceConsumer, AnnounceProducer, BroadcastConsumer};
4use web_async::Lock;
5
6#[derive(Clone, Default)]
8pub struct Origin {
9 unique: AnnounceProducer,
11
12 routes: Lock<HashMap<String, BroadcastConsumer>>,
14}
15
16impl Origin {
17 pub fn new() -> Self {
18 Self::default()
19 }
20
21 pub fn publish<T: ToString>(&mut self, path: T, broadcast: BroadcastConsumer) {
23 let path = path.to_string();
24 self.routes.lock().insert(path.clone(), broadcast.clone());
25 self.unique.insert(&path);
26
27 let mut this = self.clone();
28 web_async::spawn(async move {
29 broadcast.closed().await;
31
32 let mut routes = this.routes.lock();
34
35 if let Some(existing) = routes.remove(&path) {
36 if !existing.ptr_eq(&broadcast) {
37 routes.insert(path.to_string(), broadcast.clone());
39 } else {
40 this.unique.remove(&path);
42 }
43 }
44 });
45 }
46
47 pub fn consume(&self, path: &str) -> Option<BroadcastConsumer> {
49 self.routes.lock().get(path).cloned()
51 }
52
53 pub fn announced(&self, prefix: &str) -> AnnounceConsumer {
57 self.unique.consume(prefix)
58 }
59}