1use alloc::string::{String, ToString};
5
6use crate::channel::{self, Publisher, Subscribable, Subscriber};
7use hashbrown::HashMap;
8use spin::Mutex;
9
10pub struct Photon<T: Copy + Send + 'static> {
23 topics: Mutex<HashMap<String, TopicEntry<T>>>,
24 default_capacity: usize,
25}
26
27struct TopicEntry<T: Copy + Send> {
28 subscribable: Subscribable<T>,
29 publisher: Option<Publisher<T>>,
30}
31
32impl<T: Copy + Send + 'static> Photon<T> {
33 pub fn new(capacity: usize) -> Self {
35 Photon {
36 topics: Mutex::new(HashMap::new()),
37 default_capacity: capacity,
38 }
39 }
40
41 pub fn publisher(&self, topic: &str) -> Publisher<T> {
46 let mut topics = self.topics.lock();
47 let entry = topics
48 .entry(topic.to_string())
49 .or_insert_with(|| Self::make_entry(self.default_capacity));
50 entry
51 .publisher
52 .take()
53 .unwrap_or_else(|| panic!("publisher already taken for topic '{}'", topic))
54 }
55
56 pub fn subscribe(&self, topic: &str) -> Subscriber<T> {
58 let mut topics = self.topics.lock();
59 let entry = topics
60 .entry(topic.to_string())
61 .or_insert_with(|| Self::make_entry(self.default_capacity));
62 entry.subscribable.subscribe()
63 }
64
65 pub fn subscribable(&self, topic: &str) -> Subscribable<T> {
67 let mut topics = self.topics.lock();
68 let entry = topics
69 .entry(topic.to_string())
70 .or_insert_with(|| Self::make_entry(self.default_capacity));
71 entry.subscribable.clone()
72 }
73
74 fn make_entry(capacity: usize) -> TopicEntry<T> {
75 let (pub_, sub_) = channel::channel(capacity);
76 TopicEntry {
77 subscribable: sub_,
78 publisher: Some(pub_),
79 }
80 }
81}