1use std::fmt;
23
24pub struct EventBus<E: Clone + Send + 'static> {
29 tx: tokio::sync::broadcast::Sender<E>,
30}
31
32impl<E: Clone + Send + 'static> EventBus<E> {
33 pub fn new(capacity: usize) -> Self {
35 let (tx, _rx) = tokio::sync::broadcast::channel(capacity);
36 drop(_rx);
38 Self { tx }
39 }
40
41 pub fn subscribe(&self) -> tokio::sync::broadcast::Receiver<E> {
44 self.tx.subscribe()
45 }
46
47 pub fn publish(&self, event: E) -> anyhow::Result<()> {
52 let _ = self.tx.send(event);
53 Ok(())
54 }
55
56 pub fn subscriber_count(&self) -> usize {
58 self.tx.receiver_count()
59 }
60}
61
62impl<E: Clone + Send + 'static> Clone for EventBus<E> {
63 fn clone(&self) -> Self {
64 Self {
65 tx: self.tx.clone(),
66 }
67 }
68}
69
70impl<E: Clone + Send + 'static> fmt::Debug for EventBus<E> {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 f.debug_struct("EventBus")
73 .field("subscribers", &self.tx.receiver_count())
74 .finish()
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[derive(Debug, Clone, PartialEq, Eq)]
83 struct TestEvent {
84 name: String,
85 value: i32,
86 }
87
88 #[test]
89 fn test_new_bus() {
90 let bus: EventBus<TestEvent> = EventBus::new(16);
91 assert_eq!(bus.subscriber_count(), 0);
92 }
93
94 #[test]
95 fn test_publish_with_no_subscribers() {
96 let bus: EventBus<TestEvent> = EventBus::new(16);
97 assert!(
98 bus.publish(TestEvent {
99 name: "test".into(),
100 value: 1
101 })
102 .is_ok()
103 );
104 }
105
106 #[tokio::test]
107 async fn test_single_subscriber() {
108 let bus: EventBus<TestEvent> = EventBus::new(16);
109 let mut rx = bus.subscribe();
110 assert_eq!(bus.subscriber_count(), 1);
111
112 bus.publish(TestEvent {
113 name: "hello".into(),
114 value: 42,
115 })
116 .unwrap();
117
118 let event = rx.recv().await.unwrap();
119 assert_eq!(event.name, "hello");
120 assert_eq!(event.value, 42);
121 }
122
123 #[tokio::test]
124 async fn test_multiple_subscribers() {
125 let bus: EventBus<TestEvent> = EventBus::new(16);
126 let mut rx1 = bus.subscribe();
127 let mut rx2 = bus.subscribe();
128
129 bus.publish(TestEvent {
130 name: "broadcast".into(),
131 value: 99,
132 })
133 .unwrap();
134
135 let e1 = rx1.recv().await.unwrap();
136 let e2 = rx2.recv().await.unwrap();
137 assert_eq!(e1, e2);
138 }
139
140 #[tokio::test]
141 async fn test_late_subscriber_misses_events() {
142 let bus: EventBus<TestEvent> = EventBus::new(16);
143
144 bus.publish(TestEvent {
145 name: "early".into(),
146 value: 1,
147 })
148 .unwrap();
149
150 let mut rx = bus.subscribe();
152 assert!(rx.try_recv().is_err());
153 }
154
155 #[test]
156 fn test_clone() {
157 let bus: EventBus<TestEvent> = EventBus::new(16);
158 let bus2 = bus.clone();
159 assert_eq!(bus.subscriber_count(), 0);
161 assert_eq!(bus2.subscriber_count(), 0);
162
163 let _rx = bus.subscribe();
164 assert_eq!(bus2.subscriber_count(), 1);
166 }
167
168 #[tokio::test]
169 async fn test_generic_with_string() {
170 let bus: EventBus<String> = EventBus::new(64);
171 let mut rx = bus.subscribe();
172 bus.publish("hello world".into()).unwrap();
173 let msg = rx.recv().await.unwrap();
174 assert_eq!(msg, "hello world");
175 }
176}