From 07fc00fa932e5825e548e102f11b99554b9f822c Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Sat, 6 Aug 2022 12:03:47 -0400 Subject: [PATCH] Added a table to the database. --- src/morethantext/error.rs | 90 ++++++++++++++++++++++++++++++++++++--- src/morethantext/mod.rs | 56 +++++++++++++++++++++--- 2 files changed, 135 insertions(+), 11 deletions(-) diff --git a/src/morethantext/error.rs b/src/morethantext/error.rs index 7ab1497..6d58580 100644 --- a/src/morethantext/error.rs +++ b/src/morethantext/error.rs @@ -5,6 +5,24 @@ pub enum MTTError { Generic(Generic), } +impl MTTError { + pub fn new(detail: S) -> Self + where + S: Into, + { + Generic::new(detail).into() + } + + pub fn add_source(&mut self, source: E) + where + E: Into, + { + match self { + MTTError::Generic(err) => err.add_source(source), + } + } +} + impl Error for MTTError { fn source(&self) -> Option<&(dyn Error + 'static)> { match self { @@ -34,9 +52,12 @@ pub struct Generic { } impl Generic { - fn new(detail: &str) -> Self { + fn new(detail: S) -> Self + where + S: Into, + { Self { - detail: detail.to_string(), + detail: detail.into(), source: None, } } @@ -65,11 +86,58 @@ impl fmt::Display for Generic { } #[cfg(test)] -mod generics { +mod mtterror { use super::*; #[test] - fn new_error() { + fn create_with_str() { + let detail = "Something"; + let err = MTTError::new(detail); + assert!( + err.to_string() == detail, + "\n\nGot: {}\nWant: {}\n\n", + err.to_string(), + detail + ); + assert!( + err.source().is_none(), + "Error source should initialoze to None." + ); + } + + #[test] + fn create_with_string() { + let detail = "massive".to_string(); + let err = MTTError::new(detail.clone()); + assert!( + err.to_string() == detail, + "\n\nGot: {}\nWant: {}\n\n", + err.to_string(), + detail + ); + } + + #[test] + fn with_source() { + let mut err = MTTError::new("the error"); + let detail = "This is the cause"; + let src = MTTError::new(detail); + err.add_source(src); + assert!( + err.source().unwrap().to_string() == detail, + "/n/nGot: {}\nWant: {}\n\n", + err.source().unwrap().to_string(), + detail + ); + } +} + +#[cfg(test)] +mod generic { + use super::*; + + #[test] + fn create_with_str() { let detail = "new error"; let err = Generic::new(detail); assert!( @@ -92,7 +160,19 @@ mod generics { } #[test] - fn error_with_source() { + fn create_with_string() { + let detail = "some error".to_string(); + let err = Generic::new(detail.clone()); + assert!( + err.to_string() == detail, + "\n\nGot: {}\nWant: {}\n\n", + err.to_string(), + detail + ); + } + + #[test] + fn with_source() { let par_detail = "parent error"; let cld_detail = "child error"; let par_err = Generic::new(par_detail); diff --git a/src/morethantext/mod.rs b/src/morethantext/mod.rs index 665fbe9..fe57ba9 100644 --- a/src/morethantext/mod.rs +++ b/src/morethantext/mod.rs @@ -1,16 +1,37 @@ +pub mod error; + +use async_std::sync::{Arc, RwLock}; +use error::MTTError; +use std::collections::HashMap; + #[derive(Clone)] -pub struct MoreThanText; +pub struct MoreThanText { + tables: Arc>>, +} impl MoreThanText { pub async fn new() -> Self { - Self {} + Self { + tables: Arc::new(RwLock::new(HashMap::new())), + } + } + + pub async fn new_table(&self, name: &str) -> Result { + let mut tables = self.tables.write().await; + match tables.get(name) { + Some(_) => Err(MTTError::new(format!("table {} already exists", name))), + None => { + tables.insert(name.to_string(), Table::new().await); + Ok(Table::new().await) + } + } } } -struct Table; +pub struct Table; impl Table { - async fn new() -> Self { + pub async fn new() -> Self { Self {} } } @@ -20,8 +41,31 @@ mod database { use super::*; #[async_std::test] - async fn create() { - MoreThanText::new().await; + async fn create_table() { + let db = MoreThanText::new().await; + db.new_table("william").await.unwrap(); + } + + #[async_std::test] + async fn table_names_are_unique() -> Result<(), String> { + let db = MoreThanText::new().await; + let name = "alexandar"; + let msg = format!("table {} already exists", name); + db.new_table(name).await.unwrap(); + match db.new_table(name).await { + Ok(_) => Err("Duplicate table names are not allowed.".to_string()), + Err(err) => { + if err.to_string() == msg { + Ok(()) + } else { + Err(format!( + "Error message is incorrect: Got: '{}' Want: '{}'", + err.to_string(), + msg + )) + } + } + } } }