event_emitter_rs/lib.rs
1/*!
2[](https://crates.io/crates/event-emitter-rs)
3
4A simple EventEmitter implementation.
5
6Allows you to subscribe to events with callbacks and also fire those events.
7Events are in the form of (strings, value) and callbacks are in the form of closures that take in a value parameter.
8
9# Getting Started
10
11```
12use event_emitter_rs::EventEmitter;
13let mut event_emitter = EventEmitter::new();
14
15// This will print <"Hello world!"> whenever the <"Say Hello"> event is emitted
16event_emitter.on("Say Hello", |value: ()| println!("Hello world!"));
17event_emitter.emit("Say Hello", ());
18// >> "Hello world!"
19```
20
21# Basic Usage
22
23We can emit and listen to values of any type so long as they implement the serde Serialize and Deserialize traits.
24A single EventEmitter instance can have listeners to values of multiple types.
25
26```
27use event_emitter_rs::EventEmitter;
28use serde::{Deserialize, Serialize};
29let mut event_emitter = EventEmitter::new();
30
31event_emitter.on("Add three", |number: f32| println!("{}", number + 3.0));
32event_emitter.emit("Add three", 5.0 as f32);
33event_emitter.emit("Add three", 4.0 as f32);
34// >> "8.0"
35// >> "7.0"
36
37// Using a more advanced value type such as a struct by implementing the serde traits
38#[derive(Serialize, Deserialize)]
39struct Date {
40 month: String,
41 day: String,
42}
43
44event_emitter.on("LOG_DATE", |date: Date| {
45 println!("Month: {} - Day: {}", date.month, date.day)
46});
47event_emitter.emit("LOG_DATE", Date {
48 month: "January".to_string(),
49 day: "Tuesday".to_string()
50});
51// >> "Month: January - Day: Tuesday"
52```
53
54Removing listeners is also easy
55
56```
57use event_emitter_rs::EventEmitter;
58let mut event_emitter = EventEmitter::new();
59
60let listener_id = event_emitter.on("Hello", |_: ()| println!("Hello World"));
61match event_emitter.remove_listener(&listener_id) {
62 Some(listener_id) => print!("Removed event listener!"),
63 None => print!("No event listener of that id exists")
64}
65```
66# Creating a Global EventEmitter
67
68It's likely that you'll want to have a single EventEmitter instance that can be shared accross files;
69
70After all, one of the main points of using an EventEmitter is to avoid passing down a value through several nested functions/types and having a global subscription service.
71
72```
73// global_event_emitter.rs
74use std::sync::Mutex;
75use crate::EventEmitter;
76
77// Use lazy_static! because the size of EventEmitter is not known at compile time
78lazy_static! {
79 // Export the emitter with `pub` keyword
80 pub static ref EVENT_EMITTER: Mutex<EventEmitter> = Mutex::new(EventEmitter::new());
81}
82```
83
84Then we can import this instance into multiple files.
85
86```
87// main.rs
88#[macro_use]
89extern crate lazy_static;
90
91mod global_event_emitter;
92use global_event_emitter::EVENT_EMITTER;
93
94fn main() {
95 // We need to maintain a lock through the mutex so we can avoid data races
96 EVENT_EMITTER.lock().unwrap().on("Hello", |_: ()| println!("hello there!"));
97 EVENT_EMITTER.lock().unwrap().emit("Hello", ());
98}
99```
100
101And in another file we can now listen to the <"Hello"> event in main.rs by adding a listener to the global event emitter.
102
103```
104// some_random_file.rs
105use crate::global_event_emitter::EVENT_EMITTER;
106
107fn random_function() {
108 // When the <"Hello"> event is emitted in main.rs then print <"Random stuff!">
109 EVENT_EMITTER.lock().unwrap().on("Hello", |_: ()| println!("Random stuff!"));
110}
111```
112*/
113
114//#[cfg(test)]
115mod tests;
116
117use std::collections::HashMap;
118use std::thread;
119use std::sync::Arc;
120use serde::{Deserialize, Serialize};
121
122#[macro_use]
123extern crate lazy_static;
124
125use bincode;
126
127use uuid::Uuid;
128
129pub struct Listener {
130 callback: Arc<dyn Fn(Vec<u8>) + Sync + Send + 'static>,
131 limit: Option<u64>,
132 id: String,
133}
134
135#[derive(Default)]
136pub struct EventEmitter {
137 pub listeners: HashMap<String, Vec<Listener>>
138}
139
140impl EventEmitter {
141 // Potentially may want to add features here in the future so keep it like this
142 pub fn new() -> Self {
143 Self {
144 ..Self::default()
145 }
146 }
147
148 /// Adds an event listener with a callback that will get called whenever the given event is emitted.
149 /// Returns the id of the newly added listener.
150 ///
151 /// # Example
152 ///
153 /// ```
154 /// use event_emitter_rs::EventEmitter;
155 /// let mut event_emitter = EventEmitter::new();
156 ///
157 /// // This will print <"Hello world!"> whenever the <"Some event"> event is emitted
158 /// // The type of the `value` parameter for the closure MUST be specified and, if you plan to use the `value`, the `value` type
159 /// // MUST also match the type that is being emitted (here we just use a throwaway `()` type since we don't care about using the `value`)
160 /// event_emitter.on("Some event", |value: ()| println!("Hello world!"));
161 /// ```
162 pub fn on<F, T>(&mut self, event: &str, callback: F) -> String
163 where
164 for<'de> T: Deserialize<'de>,
165 F: Fn(T) + 'static + Sync + Send
166 {
167 let id = self.on_limited(event, None, callback);
168 return id;
169 }
170
171 /// Emits an event of the given parameters and executes each callback that is listening to that event asynchronously by spawning a new thread for each callback.
172 ///
173 /// # Example
174 ///
175 /// ```
176 /// use event_emitter_rs::EventEmitter;
177 /// let mut event_emitter = EventEmitter::new();
178 ///
179 /// // Emits the <"Some event"> event and a value <"Hello programmer">
180 /// // The value can be of any type as long as it implements the serde Serialize trait
181 /// event_emitter.emit("Some event", "Hello programmer!");
182 /// ```
183 pub fn emit<T>(&mut self, event: &str, value: T) -> Vec<thread::JoinHandle<()>>
184 where T: Serialize
185 {
186 let mut callback_handlers: Vec<thread::JoinHandle<()>> = Vec::new();
187
188 if let Some(listeners) = self.listeners.get_mut(event) {
189 let bytes: Vec<u8> = bincode::serialize(&value).unwrap();
190
191 let mut listeners_to_remove: Vec<usize> = Vec::new();
192 for (index, listener) in listeners.iter_mut().enumerate() {
193 let cloned_bytes = bytes.clone();
194 let callback = Arc::clone(&listener.callback);
195
196 match listener.limit {
197 None => {
198 callback_handlers.push(thread::spawn(move || {
199 callback(cloned_bytes);
200 }));
201 },
202 Some(limit) => {
203 if limit != 0 {
204 callback_handlers.push(thread::spawn(move || {
205 callback(cloned_bytes);
206 }));
207 listener.limit = Some(limit - 1);
208 } else {
209 listeners_to_remove.push(index);
210 }
211 }
212 }
213 }
214
215 // Reverse here so we don't mess up the ordering of the vector
216 for index in listeners_to_remove.into_iter().rev() {
217 listeners.remove(index);
218 }
219 }
220
221 return callback_handlers;
222 }
223
224 /// Removes an event listener with the given id
225 ///
226 /// # Example
227 ///
228 /// ```
229 /// use event_emitter_rs::EventEmitter;
230 /// let mut event_emitter = EventEmitter::new();
231 /// let listener_id = event_emitter.on("Some event", |value: ()| println!("Hello world!"));
232 ///
233 /// // Removes the listener that we just added
234 /// event_emitter.remove_listener(&listener_id);
235 /// ```
236 pub fn remove_listener(&mut self, id_to_delete: &str) -> Option<String> {
237 for (_, event_listeners) in self.listeners.iter_mut() {
238 if let Some(index) = event_listeners.iter().position(|listener| listener.id == id_to_delete) {
239 event_listeners.remove(index);
240 return Some(id_to_delete.to_string());
241 }
242 }
243
244 return None;
245 }
246
247 /// Adds an event listener that will only execute the listener x amount of times - Then the listener will be deleted.
248 /// Returns the id of the newly added listener.
249 ///
250 /// # Example
251 ///
252 /// ```
253 /// use event_emitter_rs::EventEmitter;
254 /// let mut event_emitter = EventEmitter::new();
255 ///
256 /// // Listener will be executed 3 times. After the third time, the listener will be deleted.
257 /// event_emitter.on_limited("Some event", Some(3), |value: ()| println!("Hello world!"));
258 /// event_emitter.emit("Some event", ()); // 1 >> "Hello world!"
259 /// event_emitter.emit("Some event", ()); // 2 >> "Hello world!"
260 /// event_emitter.emit("Some event", ()); // 3 >> "Hello world!"
261 /// event_emitter.emit("Some event", ()); // 4 >> <Nothing happens here because listener was deleted after the 3rd call>
262 /// ```
263 pub fn on_limited<F, T>(&mut self, event: &str, limit: Option<u64>, callback: F) -> String
264 where
265 for<'de> T: Deserialize<'de>,
266 F: Fn(T) + 'static + Sync + Send
267 {
268 let id = Uuid::new_v4().to_string();
269 let parsed_callback = move |bytes: Vec<u8>| {
270 let value: T = bincode::deserialize(&bytes).unwrap();
271 callback(value);
272 };
273
274 let listener = Listener {
275 id: id.clone(),
276 limit,
277 callback: Arc::new(parsed_callback),
278 };
279
280 match self.listeners.get_mut(event) {
281 Some(callbacks) => { callbacks.push(listener); },
282 None => { self.listeners.insert(event.to_string(), vec![listener]); }
283 }
284
285 return id;
286 }
287
288 /// Adds an event listener that will only execute the callback once - Then the listener will be deleted.
289 /// Returns the id of the newly added listener.
290 ///
291 /// # Example
292 ///
293 /// ```
294 /// use event_emitter_rs::EventEmitter;
295 /// let mut event_emitter = EventEmitter::new();
296 ///
297 /// event_emitter.once("Some event", |value: ()| println!("Hello world!"));
298 /// event_emitter.emit("Some event", ()); // First event is emitted and the listener's callback is called once
299 /// // >> "Hello world!"
300 ///
301 /// event_emitter.emit("Some event", ());
302 /// // >> <Nothing happens here since listener was deleted>
303 /// ```
304 pub fn once<F, T>(&mut self, event: &str, callback: F) -> String
305 where
306 for<'de> T: Deserialize<'de>,
307 F: Fn(T) + 'static + Sync + Send
308 {
309 let id = self.on_limited(event, Some(1), callback);
310 return id;
311 }
312
313 /// NOT IMPLEMENTED!
314 /// Emits an event of the given parameters in a synchronous fashion.
315 /// Instead of executing each callback in a newly spawned thread, it will execute each callback in the order that they were inserted.
316 ///
317 /// # Example
318 ///
319 /// ```
320 /// use event_emitter_rs::EventEmitter;
321 /// let mut event_emitter = EventEmitter::new();
322 ///
323 /// event_emitter.on("Some event", |value: ()| println!("1")); // Guaranteed to be executed first
324 /// event_emitter.on("Some event", |value: ()| println!("2")); // Will not execute this until the first callback has finished executing
325 /// event_emitter.on("Some event", |value: ()| println!("3")); // Will not execute this until the second callback has finished executing
326 ///
327 /// // Emits the <"Some event"> event and a value <"Hello programmer">
328 /// // The value can be of any type
329 /// event_emitter.sync_emit("Some event", "Hello programmer!");
330 /// ```
331 pub fn sync_emit<T>(&self, event: &str, value: T)
332 where T: Serialize
333 {
334 }
335}