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 if !topics.contains_key(topic) {
48 topics.insert(topic.to_string(), Self::make_entry(self.default_capacity));
49 }
50 let entry = topics.get_mut(topic).unwrap();
51 entry
52 .publisher
53 .take()
54 .unwrap_or_else(|| panic!("publisher already taken for topic '{}'", topic))
55 }
56
57 pub fn subscribe(&self, topic: &str) -> Subscriber<T> {
59 let mut topics = self.topics.lock();
60 if !topics.contains_key(topic) {
61 topics.insert(topic.to_string(), Self::make_entry(self.default_capacity));
62 }
63 let entry = topics.get_mut(topic).unwrap();
64 entry.subscribable.subscribe()
65 }
66
67 pub fn subscribable(&self, topic: &str) -> Subscribable<T> {
69 let mut topics = self.topics.lock();
70 if !topics.contains_key(topic) {
71 topics.insert(topic.to_string(), Self::make_entry(self.default_capacity));
72 }
73 let entry = topics.get_mut(topic).unwrap();
74 entry.subscribable.clone()
75 }
76
77 fn make_entry(capacity: usize) -> TopicEntry<T> {
78 let (pub_, sub_) = channel::channel(capacity);
79 TopicEntry {
80 subscribable: sub_,
81 publisher: Some(pub_),
82 }
83 }
84}