1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
#![feature(doc_cfg)] //! ## Example //! //! ```rust //! use hive_pubsub::{Hive, PubSub}; //! //! let mut hive = Hive::new( //! |users, data| { //! println!("Received data! [{:?}]: {}.", users, data); //! } //! ); //! //! hive.subscribe_multiple(1, vec! [ 2, 5 ]).unwrap(); //! hive.subscribe_multiple(3, vec! [ 2, 6 ]).unwrap(); //! hive.subscribe_multiple(4, vec! [ 2, 5 ]).unwrap(); //! //! hive.drop_topic(&6).unwrap(); //! hive.publish(&6, "This will not appear.".to_string()).unwrap(); //! hive.publish(&2, "This will appear for all three clients.".to_string()).unwrap(); //! //! hive.drop_client(&3).unwrap(); //! hive.publish(&2, "This will appear for two of the clients.".to_string()).unwrap(); //! hive.publish(&5, "This will also appear for two of the clients.".to_string()).unwrap(); //! ``` //! //! ## Example, for use with MongoDB. //! //! This example only works with MongoDB and the sync feature enabled. This is for compatibilty reasons down the line, feel free to fork and change a few links to add async compat. //! //! ```no_run //! use std::env::var; //! use mongodb::sync::Client; //! use std::sync::mpsc::channel; //! //! use hive_pubsub::{PubSub}; //! use hive_pubsub::backend::mongo::{MongodbPubSub, listen_thread}; //! //! // You'll want to have some sort of worker which can //! // handle incoming messages and deal with them accordingly. //! // Here we are just using a channel with predictable data //! // so we can just use assert_eq!(). //! let ( sender, receiver ) = channel(); //! //! let client = Client::with_uri_str("mongodb+srv://example.com").unwrap(); //! let mut hive = MongodbPubSub::<i32, i32, String>::new( //! move |_ids, data| { //! // We just send the data into the channel. //! sender.send(data).unwrap(); //! }, //! client.database("hive").collection("pubsub") //! ); //! //! // We need to subscribe to the topic to get any data. //! hive.subscribe(0, 0).unwrap(); //! //! // This is a helper function which spawns a new thread //! // and starts listening, it simply calls hive.listen() //! // in a loop { }. It is recommended you use your own //! // implementation for better error handling, although //! // any errors will be logged. //! listen_thread(hive.clone()); //! //! // We are setting source here to make the hive instance //! // accept incoming data. Since `source` is just a String, //! // it means we just cloned the original value above and //! // are now replacing it. //! hive.set_source("1234".to_string()); //! //! // Hence, we publish our data. //! hive.publish(&0, "My data.".to_string()).unwrap(); //! //! // And we should receive it back twice. //! assert_eq!(receiver.recv().unwrap(), "My data."); //! assert_eq!(receiver.recv().unwrap(), "My data."); //! ``` //! //! ## Design //! //! Hive is designed to be slotted into any server application to act as a middle-man between you and your clients, it will automatically distribute any notifications you give it to all relevant connected clients and other nodes. //! //! <p align="center"> //! <img src="https://gitlab.insrt.uk/insert/hive/-/raw/master/assets/concept.png" /> //! </p> //! //! <script>console.log("hive-pubsub, crated by insrt.uk")</script> mod hive; mod types; pub mod backend; pub use hive::Hive; pub use types::PubSub; #[cfg(test)] mod tests { use crate::{Hive, PubSub}; #[test] fn simple() { let hive = Hive::new( |users, data| { println!("We received data! For {:?}, data: {}.", users, data); } ); hive.subscribe_multiple("0001".to_string(), vec! [ "0002".to_string(), "0005".to_string() ]).unwrap(); hive.subscribe_multiple("0003".to_string(), vec! [ "0002".to_string(), "0006".to_string() ]).unwrap(); hive.subscribe_multiple("0004".to_string(), vec! [ "0002".to_string(), "0005".to_string() ]).unwrap(); hive.drop_topic(&"0006".to_string()).unwrap(); hive.publish(&"0006".to_string(), "This will not appear.".to_string()).unwrap(); hive.publish(&"0002".to_string(), "This will appear for all three clients.".to_string()).unwrap(); hive.drop_client(&"0003".to_string()).unwrap(); hive.publish(&"0002".to_string(), "This will appear for two of the clients.".to_string()).unwrap(); hive.publish(&"0005".to_string(), "This will also appear for two of the clients.".to_string()).unwrap(); } #[test] fn generics() { let hive: Hive<i32, u32, String> = Hive::new( |users, data| { println!("We received data! For {:?}, data: {}.", users, data); } ); hive.subscribe_multiple(5, vec! [ 2, 3 ]).unwrap(); hive.publish(&2, "This will appear for one of the clients.".to_string()).unwrap(); } #[test] #[cfg(feature = "test")] fn mongo() { dotenv::dotenv().ok(); use std::env::var; use mongodb::sync::Client; use std::sync::mpsc::channel; use crate::{PubSub}; use crate::backend::mongo::{MongodbPubSub, listen_thread}; // You'll want to have some sort of worker which can // handle incoming messages and deal with them accordingly. // Here we are just using a channel with predictable data // so we can just use assert_eq!(). let ( sender, receiver ) = channel(); let client = Client::with_uri_str(&var("MONGODB_URI").expect("Specify MONGODB_URI in .env or pass in.")).unwrap(); let mut hive = MongodbPubSub::<i32, i32, String>::new( move |_ids, data| { // We just send the data into the channel. sender.send(data).unwrap(); }, client.database("hive").collection("pubsub") ); // We need to subscribe to the topic to get any data. hive.subscribe(0, 0).unwrap(); // This is a helper function which spawns a new thread // and starts listening, it simply calls hive.listen() // in a loop { }. It is recommended you use your own // implementation for better error handling, although // any errors will be logged. listen_thread(hive.clone()); // We are setting source here to make the hive instance // accept incoming data. Since `source` is just a String, // it means we just cloned the original value above and // are now replacing it. hive.set_source("1234".to_string()); // Hence, we publish our data. hive.publish(&0, "My data.".to_string()).unwrap(); // And we should receive it back twice. assert_eq!(receiver.recv().unwrap(), "My data."); assert_eq!(receiver.recv().unwrap(), "My data."); } }