use crate::{queue::Message, utils::GenID}; use std::{ collections::HashMap, sync::{ mpsc::{channel, Receiver, Sender}, Arc, Mutex, }, thread::spawn, }; use uuid::Uuid; pub struct Request; impl Request { pub fn new() -> Self { Self {} } } #[cfg(test)] mod requests { use super::*; pub fn create_request() -> Request { Request::new() } } pub struct Reply; impl Reply { pub fn get_session(&self) -> String { "id".to_string() } pub fn get_content(&self) -> String { "Something goes here.".to_string() } } #[cfg(test)] mod replies { use super::*; pub fn create_reply() -> Reply { Reply {} } } #[derive(Clone)] pub struct ClientRegistry { registry: Arc>>>, } impl ClientRegistry { pub fn new() -> Self { Self { registry: Arc::new(Mutex::new(HashMap::new())), } } fn create_storage() -> Arc>>> { Arc::new(Mutex::new(HashMap::new())) } fn get_id<'a>( gen: &mut impl Iterator, data: &HashMap>, ) -> Uuid { let mut id = gen.next().unwrap(); while data.contains_key(&id) { id = gen.next().unwrap(); } id.clone() } pub fn add(&mut self, tx: Sender) -> Uuid { let id = Uuid::new_v4(); let mut reg = self.registry.lock().unwrap(); let mut gen_id = GenID::new(); let id = ClientRegistry::get_id(&mut gen_id, ®); reg.insert(id.clone(), tx); id } fn send(&mut self, id: &Uuid, msg: Reply) { let mut reg = self.registry.lock().unwrap(); let tx = reg.get(id).unwrap(); tx.send(msg).unwrap(); reg.remove(id).unwrap(); } } #[cfg(test)] mod clientregistries { use super::*; use std::{ sync::mpsc::{channel, Receiver}, time::Duration, }; static TIMEOUT: Duration = Duration::from_millis(500); #[test] fn create_client_registry() { let reg = ClientRegistry::new(); let data = reg.registry.lock().unwrap(); assert!(data.is_empty(), "needs to create an empty hashmap"); } #[test] fn send_from_client() { let mut reg = ClientRegistry::new(); let count = 10; let mut rxs: HashMap> = HashMap::new(); for _ in 0..count { let (tx, rx) = channel::(); let id = reg.add(tx); rxs.insert(id, rx); } assert_eq!(rxs.len(), count, "should have been {} receivers", count); for (id, rx) in rxs.iter() { let msg = Reply {}; reg.send(id, msg); rx.recv_timeout(TIMEOUT).unwrap(); } let data = reg.registry.lock().unwrap(); assert!(data.is_empty(), "should remove sender after sending"); } #[test] fn prevent_duplicates() { let mut reg = ClientRegistry::new(); let (tx, rx) = channel::(); let existing = reg.add(tx); let expected = Uuid::new_v4(); let ids = [existing.clone(), expected.clone()]; let data = reg.registry.lock().unwrap(); let result = ClientRegistry::get_id(&mut ids.into_iter(), &data); assert_eq!(result, expected); } } #[derive(Clone)] pub struct ClientLink; impl ClientLink { fn new() -> Self { Self {} } pub fn forward(&self, req: Request) -> Reply { Reply {} } } #[cfg(test)] mod clientlinks { use super::*; #[test] fn create_client_link() { ClientLink::new(); } } pub struct Client { rx: Receiver, } impl Client { fn new(rx: Receiver) -> Self { Self { rx: rx } } pub fn start() -> ClientLink { let (tx, rx) = channel(); spawn(move || { let client = Client::new(rx); client.listen(); }); ClientLink::new() } fn listen(&self) { loop { let req = self.rx.recv().unwrap(); //req.get_sender().send(Reply {}).unwrap(); } } } #[cfg(test)] mod clients { use super::*; use requests::create_request; #[test] fn start_client() { let link = Client::start(); let req = create_request(); link.forward(req); } }