Completed the trip to client and back.
This commit is contained in:
		@@ -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;
 | 
			
		||||
 | 
			
		||||
impl ClientLink {
 | 
			
		||||
    fn new() -> Self {
 | 
			
		||||
        Self {}
 | 
			
		||||
pub struct ClientLink {
 | 
			
		||||
    tx: Sender<Message>,
 | 
			
		||||
    registry: ClientRegistry,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    pub fn forward(&self, req: Request) -> Reply {
 | 
			
		||||
        Reply {}
 | 
			
		||||
impl ClientLink {
 | 
			
		||||
    fn new(tx: Sender<Message>, registry: ClientRegistry) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            tx: tx,
 | 
			
		||||
            registry: registry,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn send(&mut self, req: Request) -> Receiver<Reply> {
 | 
			
		||||
        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<Message>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Client {
 | 
			
		||||
    fn new(rx: Receiver<Message>) -> 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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								src/field.rs
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/field.rs
									
									
									
									
									
								
							@@ -8,6 +8,15 @@ pub enum Field {
 | 
			
		||||
    Uuid(Uuid),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Field {
 | 
			
		||||
    pub fn to_uuid(&self) -> Result<Uuid, String> {
 | 
			
		||||
        match self {
 | 
			
		||||
            Field::Uuid(data) => Ok(data.clone()),
 | 
			
		||||
            _ => Err("not a uuid".to_string()),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<String> 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(_) => {},
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,8 @@ impl MoreThanText {
 | 
			
		||||
        F: Into<Field>,
 | 
			
		||||
    {
 | 
			
		||||
        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();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								src/queue.rs
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								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<S, F>(&mut self, name: S, data: F)
 | 
			
		||||
    pub fn add_data<S, F>(&mut self, name: S, data: F)
 | 
			
		||||
    where
 | 
			
		||||
        S: Into<String>,
 | 
			
		||||
        F: Into<Field>,
 | 
			
		||||
@@ -51,14 +51,14 @@ impl Message {
 | 
			
		||||
        self.data.insert(name.into(), data.into());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn get_data(&self) -> &HashMap<String, Field> {
 | 
			
		||||
    pub fn get_data(&self) -> &HashMap<String, Field> {
 | 
			
		||||
        &self.data
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<Request> 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<Uuid> = Vec::new();
 | 
			
		||||
        for _ in 0..10 {
 | 
			
		||||
            tx.send(msg.reply(MsgType::NewClientMessage)).unwrap();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user