mod client; mod data; mod error; mod message; mod router; mod session; use client::{Client, ClientMsg}; use message::{Message, MsgData}; use router::Router; use session::{Session, SessionData, SessionMsg}; use std::sync::mpsc::{channel, Sender}; struct Request; struct Record; struct Response { headers: Vec, records: Vec, } impl Response { fn new() -> Self { Self { headers: Vec::new(), records: Vec::new(), } } fn count(&self) -> usize { 0 } fn add_header(&mut self, name: S) where S: Into { self.headers.push(name.into()); } } #[cfg(test)] mod responses { use super::*; #[test] fn create_response() { let res = Response::new(); assert!(res.headers.is_empty()); assert!(res.records.is_empty()); assert_eq!(res.count(), 0); } #[test] fn addA_header() { let mut res = Response::new(); res.add_header("one"); assert_eq!(res.headers, ["one"]); res.add_header("two".to_string()); assert_eq!(res.headers, ["one", "two"]); } } /// Support functions for Messages. pub trait Msg { fn to_msgdata(&self) -> MsgData; } #[cfg(test)] mod test_message { use super::*; pub enum Tester { Test1, Test2, } impl Msg for Tester { fn to_msgdata(&self) -> MsgData { match self { Tester::Test1 => MsgData::Test1, Tester::Test2 => MsgData::Test2, } } } } /// Application client to MoreThanText pub struct MoreThanText { session: Option, tx: Sender, } impl MoreThanText { /// Create a MoreThanText database. /// /// Example: /// /// ``` /// use morethantext::MoreThanText; /// /// MoreThanText::new(); /// ``` pub fn new() -> Self { let (tx, rx) = channel(); let mut senders = Vec::new(); senders.push(Client::start(tx.clone())); senders.push(Session::start(tx.clone())); Router::start(senders, rx); Self { session: None, tx: tx, } } /// Opens an existing or new session with the database. /// /// If the string is None, incorrect, or expired, /// a new session will be created. /// /// Example: /// /// ``` /// use morethantext::MoreThanText; /// /// let mut mtt = MoreThanText::new(); /// mtt.open_session(None); /// mtt.open_session(Some("7b1ff340-7dfa-4f29-b144-601384e54423".to_string())); /// ``` pub fn open_session(&mut self, id: Option) { let (tx, rx) = channel(); let req = ClientMsg::OpenSession(id, tx); let msg = Message::new(&req); self.tx.send(msg).unwrap(); match rx.recv().unwrap().get_message() { MsgData::Session(data) => match data { SessionMsg::Opened(sess) => self.session = Some(sess.clone()), _ => {} }, _ => {} }; } /// Get the session id /// /// Example: /// /// ``` /// use morethantext::MoreThanText; /// /// let mut mtt = MoreThanText::new(); /// let id = mtt.get_id(); /// ``` pub fn get_id(&self) -> String { match &self.session { Some(id) => id.to_string(), None => "".to_string(), } } } impl Clone for MoreThanText { fn clone(&self) -> Self { Self { session: None, tx: self.tx.clone(), } } } #[cfg(test)] mod mtt_client { use super::*; #[test] fn default_values() { let mtt = MoreThanText::new(); assert!(mtt.session.is_none()); } #[test] fn new_session() { let mut mtt = MoreThanText::new(); mtt.open_session(None); assert!(mtt.session.is_some()); } #[test] fn session_ids_are_unique() { let mut mtt = MoreThanText::new(); mtt.open_session(None); let id1 = mtt.get_id(); mtt.open_session(None); assert_ne!(mtt.get_id(), id1); } #[test] fn cloned_clients_have_no_session() { let mut mtt = MoreThanText::new(); mtt.open_session(None); let result = mtt.clone(); assert!(result.session.is_none()); } }