morethantext/src/lib.rs

306 lines
6.3 KiB
Rust
Raw Normal View History

2024-11-06 21:05:52 -05:00
mod client;
2024-11-09 12:45:19 -05:00
mod data;
2024-11-15 13:37:11 -05:00
mod error;
2024-11-06 21:05:52 -05:00
mod message;
mod router;
mod session;
2024-05-05 23:18:42 -04:00
2024-11-06 21:05:52 -05:00
use client::{Client, ClientMsg};
use message::{Message, MsgData};
use router::Router;
use session::{Session, SessionData, SessionMsg};
2025-02-11 11:33:54 -05:00
use std::{
collections::HashMap,
ops::Deref,
sync::mpsc::{channel, Sender},
};
2024-03-19 19:54:14 -04:00
2025-02-09 15:48:13 -05:00
struct Request;
2025-02-10 08:05:59 -05:00
enum Field {
Static(String),
}
impl From<String> for Field {
fn from(value: String) -> Self {
Field::Static(value)
}
}
impl From<&str> for Field {
fn from(value: &str) -> Self {
2025-02-11 11:33:54 -05:00
Field::Static(value.into())
2025-02-10 08:05:59 -05:00
}
}
#[cfg(test)]
mod fields {
use super::*;
#[test]
fn string_to_field() {
let entries = ["test1".to_string(), "test2".to_string()];
for data in entries {
match data.clone().into() {
Field::Static(result) => assert_eq!(result, data),
}
}
}
#[test]
fn str_to_field() {
let entries = ["test1", "test2"];
for data in entries {
match data.into() {
Field::Static(result) => assert_eq!(result, data),
}
}
}
}
2025-02-11 11:33:54 -05:00
struct Record {
data: HashMap<String, Field>,
}
impl Record {
fn new() -> Self {
Self {
data: HashMap::new(),
}
}
fn add<S, F>(&mut self, name: S, data: F)
where
S: Into<String>,
F: Into<Field>,
{
self.data.insert(name.into(), data.into());
}
}
impl Deref for Record {
type Target = HashMap<String, Field>;
fn deref(&self) -> &Self::Target {
&self.data
}
}
#[cfg(test)]
mod records {
use super::*;
#[test]
fn initialize() {
let rec = Record::new();
assert!(rec.is_empty());
}
#[test]
fn bad_get_return() {
let rec = Record::new();
match rec.get("empty") {
Some(_) => unreachable!("Should_have returned a None"),
None => {}
}
}
#[test]
fn add_data() {
let name = "name1x";
let data = "data1";
let mut rec = Record::new();
rec.add(name, data);
match rec.get(name) {
None => unreachable!("Should return data"),
Some(result) => match result {
Field::Static(txt) => assert_eq!(txt, data),
},
}
}
#[test]
fn add_data_strings() {
let name = "field".to_string();
let data = "info".to_string();
let mut rec = Record::new();
rec.add(name.clone(), data.clone());
match rec.get(&name) {
None => unreachable!("Should return data"),
Some(result) => match result {
Field::Static(txt) => assert_eq!(txt, &data),
},
}
}
}
2025-02-09 15:48:13 -05:00
struct Response {
2025-02-11 11:33:54 -05:00
data: HashMap<String, Vec<Field>>,
2025-02-09 15:48:13 -05:00
}
impl Response {
fn new() -> Self {
Self {
2025-02-11 11:33:54 -05:00
data: HashMap::new(),
2025-02-09 15:48:13 -05:00
}
}
fn count(&self) -> usize {
0
}
}
#[cfg(test)]
mod responses {
use super::*;
#[test]
fn create_response() {
let res = Response::new();
2025-02-11 11:33:54 -05:00
assert!(res.data.is_empty());
2025-02-09 15:48:13 -05:00
assert_eq!(res.count(), 0);
}
}
2024-11-06 21:05:52 -05:00
/// 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
2024-03-19 19:54:14 -04:00
pub struct MoreThanText {
2024-11-06 21:05:52 -05:00
session: Option<SessionData>,
tx: Sender<Message>,
2024-03-19 19:54:14 -04:00
}
impl MoreThanText {
2024-05-12 14:10:36 -04:00
/// Create a MoreThanText database.
///
/// Example:
///
/// ```
/// use morethantext::MoreThanText;
///
2024-11-06 21:05:52 -05:00
/// MoreThanText::new();
2024-05-12 14:10:36 -04:00
/// ```
2024-11-06 21:05:52 -05:00
pub fn new() -> Self {
2024-03-19 19:54:14 -04:00
let (tx, rx) = channel();
2024-11-06 21:05:52 -05:00
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,
}
2024-05-12 14:10:36 -04:00
}
/// Opens an existing or new session with the database.
///
/// If the string is None, incorrect, or expired,
2024-11-06 21:05:52 -05:00
/// a new session will be created.
2024-05-12 14:10:36 -04:00
///
/// Example:
///
/// ```
/// use morethantext::MoreThanText;
///
2024-11-06 21:05:52 -05:00
/// let mut mtt = MoreThanText::new();
2024-05-12 14:10:36 -04:00
/// mtt.open_session(None);
/// mtt.open_session(Some("7b1ff340-7dfa-4f29-b144-601384e54423".to_string()));
/// ```
pub fn open_session(&mut self, id: Option<String>) {
let (tx, rx) = channel();
2024-11-06 21:05:52 -05:00
let req = ClientMsg::OpenSession(id, tx);
let msg = Message::new(&req);
self.tx.send(msg).unwrap();
match rx.recv().unwrap().get_message() {
2024-11-09 12:45:19 -05:00
MsgData::Session(data) => match data {
SessionMsg::Opened(sess) => self.session = Some(sess.clone()),
_ => {}
2024-11-06 21:05:52 -05:00
},
2024-11-09 12:45:19 -05:00
_ => {}
2024-11-06 21:05:52 -05:00
};
2024-03-19 19:54:14 -04:00
}
2024-05-12 14:10:36 -04:00
/// Get the session id
///
/// Example:
///
/// ```
/// use morethantext::MoreThanText;
///
2024-11-06 21:05:52 -05:00
/// let mut mtt = MoreThanText::new();
/// let id = mtt.get_id();
2024-05-12 14:10:36 -04:00
/// ```
pub fn get_id(&self) -> String {
2024-11-06 21:05:52 -05:00
match &self.session {
Some(id) => id.to_string(),
None => "".to_string(),
2024-05-12 14:10:36 -04:00
}
2024-03-19 19:54:14 -04:00
}
}
2024-11-06 21:28:44 -05:00
impl Clone for MoreThanText {
fn clone(&self) -> Self {
Self {
2024-11-09 12:45:19 -05:00
session: None,
tx: self.tx.clone(),
2024-11-06 21:28:44 -05:00
}
}
}
2024-03-19 19:54:14 -04:00
#[cfg(test)]
2024-05-12 14:10:36 -04:00
mod mtt_client {
2024-03-19 19:54:14 -04:00
use super::*;
#[test]
2024-11-06 21:05:52 -05:00
fn default_values() {
let mtt = MoreThanText::new();
assert!(mtt.session.is_none());
2024-03-19 19:54:14 -04:00
}
#[test]
2024-11-06 21:05:52 -05:00
fn new_session() {
let mut mtt = MoreThanText::new();
2024-05-12 14:10:36 -04:00
mtt.open_session(None);
2024-11-06 21:05:52 -05:00
assert!(mtt.session.is_some());
2024-03-19 19:54:14 -04:00
}
2024-05-05 23:18:42 -04:00
#[test]
2024-11-06 21:05:52 -05:00
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);
2024-05-05 23:18:42 -04:00
}
2024-11-06 21:28:44 -05:00
#[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());
}
2024-05-05 23:18:42 -04:00
}