diff --git a/src/client.rs b/src/client.rs index 9280d15..77f9733 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,4 +1,4 @@ -use crate::{queue::Message, utils::GenID}; +use crate::{queue::{Message, MsgType}, utils::GenID}; use std::{ collections::HashMap, sync::{ @@ -142,52 +142,94 @@ mod clientregistries { } #[derive(Clone)] -pub struct ClientLink; +pub struct ClientLink { + tx: Sender, + registry: ClientRegistry, +} impl ClientLink { - fn new() -> Self { - Self {} + fn new(tx: Sender, registry: ClientRegistry) -> Self { + Self { + tx: tx, + registry: registry, + } } - pub fn forward(&self, req: Request) -> Reply { - Reply {} + pub fn send(&mut self, req: Request) -> Receiver { + let (tx, rx) = channel(); + let mut msg = Message::new(MsgType::ClientRequest); + let id = self.registry.add(tx); + msg.add_data("tx_id", id); + self.tx.send(msg).unwrap(); + rx } } #[cfg(test)] mod clientlinks { use super::*; + use std::time::Duration; + + static TIMEOUT: Duration = Duration::from_millis(500); #[test] fn create_client_link() { - ClientLink::new(); + let (tx, rx) = channel(); + let mut registry = ClientRegistry::new(); + let mut link = ClientLink::new(tx, registry.clone()); + let req = Request::new(); + let rx_client = link.send(req); + let msg = rx.recv_timeout(TIMEOUT).unwrap(); + match msg.get_class() { + MsgType::ClientRequest => {}, + _ => unreachable!("should have been a client request"), + } + match msg.get_data().get("tx_id") { + Some(result) => { + let id = result.to_uuid().unwrap(); + registry.send(&id, Reply {}); + rx_client.recv().unwrap(); + }, + None => unreachable!("should have had a seender id"), + } } } pub struct Client { + registry: ClientRegistry, rx: Receiver, } impl Client { fn new(rx: Receiver) -> Self { - Self { rx: rx } + Self { + registry: ClientRegistry::new(), + rx: rx + } } pub fn start() -> ClientLink { let (tx, rx) = channel(); + let mut client = Client::new(rx); + let link = ClientLink::new(tx, client.get_registry()); spawn(move || { - let client = Client::new(rx); client.listen(); }); - ClientLink::new() + link } - fn listen(&self) { + fn listen(&mut self) { loop { - let req = self.rx.recv().unwrap(); - //req.get_sender().send(Reply {}).unwrap(); + let msg = self.rx.recv().unwrap(); + let id = msg.get_data().get("tx_id").unwrap().to_uuid().unwrap(); + let reply = Reply {}; + self.registry.send(&id, reply); } } + + fn get_registry(&self) -> ClientRegistry { + self.registry.clone() + } } #[cfg(test)] @@ -197,8 +239,8 @@ mod clients { #[test] fn start_client() { - let link = Client::start(); + let mut link = Client::start(); let req = create_request(); - link.forward(req); + link.send(req); } } diff --git a/src/field.rs b/src/field.rs index 5476f82..307f986 100644 --- a/src/field.rs +++ b/src/field.rs @@ -8,6 +8,15 @@ pub enum Field { Uuid(Uuid), } +impl Field { + pub fn to_uuid(&self) -> Result { + match self { + Field::Uuid(data) => Ok(data.clone()), + _ => Err("not a uuid".to_string()), + } + } +} + impl From for Field { fn from(value: String) -> Self { match Uuid::try_from(value.as_str()) { @@ -121,4 +130,24 @@ mod fields { let input: Field = result.clone().into(); assert_eq!(input.to_string(), result); } + + #[test] + fn field_to_uuid() { + let id = Uuid::new_v4(); + let field: Field = id.into(); + match field.to_uuid() { + Ok(result) => assert_eq!(result, id), + Err(_) => unreachable!("did not convert to uuid"), + } + } + + #[test] + fn not_uuid_field_to_uuid() { + let text = "Not a uuid."; + let field: Field = text.into(); + match field.to_uuid() { + Ok(_) => unreachable!("should return an error"), + Err(_) => {}, + } + } } diff --git a/src/lib.rs b/src/lib.rs index c12c9bc..2787807 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,8 @@ impl MoreThanText { F: Into, { let req = Request::new(); - self.client_link.forward(req) + let rx = self.client_link.send(req); + rx.recv().unwrap() /* let req = Request::new(tx); self.tx.send(req.into()).unwrap(); diff --git a/src/queue.rs b/src/queue.rs index 4aa7368..cfecb23 100644 --- a/src/queue.rs +++ b/src/queue.rs @@ -9,7 +9,7 @@ use std::{ }; use uuid::Uuid; -enum MsgType { +pub enum MsgType { ClientMessage, ClientRequest, NewClientMessage, @@ -23,10 +23,10 @@ pub struct Message { } impl Message { - pub fn new() -> Self { + pub fn new(msg_type: MsgType) -> Self { Self { id: Uuid::nil(), - class: MsgType::NoOp, + class: msg_type, data: HashMap::new(), } } @@ -39,11 +39,11 @@ impl Message { } } - fn get_class(&self) -> &MsgType { + pub fn get_class(&self) -> &MsgType { &self.class } - fn add_data(&mut self, name: S, data: F) + pub fn add_data(&mut self, name: S, data: F) where S: Into, F: Into, @@ -51,14 +51,14 @@ impl Message { self.data.insert(name.into(), data.into()); } - fn get_data(&self) -> &HashMap { + pub fn get_data(&self) -> &HashMap { &self.data } } impl From for Message { fn from(value: Request) -> Self { - let msg = Message::new(); + let msg = Message::new(MsgType::ClientRequest); msg.reply(MsgType::ClientRequest) } } @@ -69,7 +69,7 @@ mod messages { #[test] fn new_message() { - let msg = Message::new(); + let msg = Message::new(MsgType::NoOp); assert_eq!(msg.id, Uuid::nil()); match msg.class { MsgType::NoOp => (), @@ -81,7 +81,7 @@ mod messages { #[test] fn create_reply() { let id = Uuid::new_v4(); - let mut msg = Message::new(); + let mut msg = Message::new(MsgType::NoOp); msg.id = id.clone(); let data = MsgType::NewClientMessage; let result = msg.reply(data); @@ -94,7 +94,7 @@ mod messages { #[test] fn get_message_type() { - let msg = Message::new(); + let msg = Message::new(MsgType::NoOp); match msg.get_class() { MsgType::NoOp => {} _ => unreachable!("should have bneen noopn"), @@ -103,7 +103,7 @@ mod messages { #[test] fn add_data() { - let mut msg = Message::new(); + let mut msg = Message::new(MsgType::NoOp); let one = "one"; let two = "two".to_string(); msg.add_data(one, one); @@ -168,7 +168,7 @@ mod queues { #[test] fn get_new_client_message() { let (tx, rx) = start_queue(); - let initial = Message::new(); + let initial = Message::new(MsgType::NoOp); let msg = initial.reply(MsgType::NewClientMessage); tx.send(msg).unwrap(); let msg = rx.recv_timeout(TIMEOUT).unwrap(); @@ -181,7 +181,7 @@ mod queues { #[test] fn new_client_messages_are_unique() { let (tx, rx) = start_queue(); - let msg = Message::new(); + let msg = Message::new(MsgType::NoOp); let mut ids: Vec = Vec::new(); for _ in 0..10 { tx.send(msg.reply(MsgType::NewClientMessage)).unwrap();