diff --git a/src/morethantext/mod.rs b/src/morethantext/mod.rs index 08588a3..99c019e 100644 --- a/src/morethantext/mod.rs +++ b/src/morethantext/mod.rs @@ -11,8 +11,11 @@ const ENTRY: &str = "EntryPoint"; enum ErrorCode { // General Undefined(String), - // Cache Entry + // Cache EntryNotFound(String), + InvalidCommitData, + // Store + DatabaseAlreadyExists(String), } impl fmt::Display for ErrorCode { @@ -20,6 +23,10 @@ impl fmt::Display for ErrorCode { match self { ErrorCode::Undefined(msg) => write!(f, "{}", msg), ErrorCode::EntryNotFound(id) => write!(f, "entry '{}' was not found", id), + ErrorCode::InvalidCommitData => write!(f, "commit data was not a database store"), + ErrorCode::DatabaseAlreadyExists(name) => { + write!(f, "database '{}' already exists", name) + } } } } @@ -44,6 +51,23 @@ mod errorcodes { assert_eq!(err.to_string(), format!("entry '{}' was not found", item)); } } + + #[test] + fn invalid_commit_data() { + let err = ErrorCode::InvalidCommitData; + assert_eq!(err.to_string(), "commit data was not a database store"); + } + + #[test] + fn database_already_exists() { + for item in ITEMS { + let err = ErrorCode::DatabaseAlreadyExists(item.to_string()); + assert_eq!( + err.to_string(), + format!("database '{}' already exists", item) + ); + } + } } #[derive(Debug)] @@ -117,11 +141,109 @@ mod errors { } #[derive(Clone, Debug)] -struct Store; +struct Storage { + id: Option, + data: Option, + // delete: bool, +} + +impl Storage { + fn from_id(id: S) -> Self + where + S: Into, + { + Self { + id: Some(id.into()), + data: None, + } + } + + fn from_datatype(dt: DataType) -> Self { + Self { + id: None, + data: Some(dt), + } + } +} + +#[cfg(test)] +mod storage { + use super::*; + + #[test] + fn from_id_with_str() { + let ids = ["first", "second"]; + for id in ids { + let output = Storage::from_id(id); + assert_eq!(output.id, Some(id.to_string())); + assert!( + output.data.is_none(), + "The storage data should have been Non." + ); + } + } + + #[test] + fn from_id_with_string() { + let id = "my_id".to_string(); + let output = Storage::from_id(id.clone()); + assert_eq!(output.id, Some(id)); + } + + #[test] + fn from_store() { + let output = Storage::from_datatype(DataType::new("store")); + assert!(output.id.is_none(), "id should be None."); + assert!(output.data.is_some(), "There should be data"); + let result = output.data.unwrap(); + match result { + DataType::DBMap(_) => (), + _ => assert!(false, "{:?} should have been DataType::DBMap.", result), + } + } + + #[test] + fn from_database() { + let output = Storage::from_datatype(DataType::new("database")); + let result = output.data.unwrap(); + match result { + DataType::TableMap(_) => (), + _ => assert!(false, "{:?} should have been DataType::TableMap.", result), + } + } +} + +#[derive(Clone, Debug)] +struct Store { + data: HashMap, +} impl Store { fn new() -> Self { - Self {} + Self { + data: HashMap::new(), + } + } + + fn add_new(&mut self, name: S) -> Result<(), MTTError> + where + S: Into, + { + let dbname = name.into(); + match self.get(&dbname) { + Some(_) => Err(MTTError::from_code(ErrorCode::DatabaseAlreadyExists( + dbname, + ))), + None => { + self.data + .insert(dbname, Storage::from_datatype(DataType::new("database"))); + Ok(()) + } + } + } + + fn get(&self, name: &str) -> Option<&Storage> { + self.data.get(name) } } @@ -130,8 +252,68 @@ mod stores { use super::*; #[test] - fn create() { - Store::new(); + fn get_no_database() -> Result<(), MTTError> { + let store = Store::new(); + match store.get("missing_name") { + Some(_) => Err(MTTError::new("should have returned None")), + None => Ok(()), + } + } + + #[test] + fn add_database_str() { + let mut store = Store::new(); + let names = ["first", "second"]; + for name in names { + store.add_new(name).unwrap(); + let output = store.get(name).unwrap(); + assert!(output.data.is_some(), "There should be a data type."); + match output.data.clone().unwrap() { + DataType::TableMap(_) => (), + _ => assert!( + false, + "{:?} should have been DataType::TableMap.", + output.data + ), + } + assert!(output.id.is_none(), "Should not have an id."); + } + } + + #[test] + fn add_database_string() { + let mut store = Store::new(); + let name = "third".to_string(); + store.add_new(name.clone()).unwrap(); + let output = store.get(&name).unwrap(); + match output.data.clone().unwrap() { + DataType::TableMap(_) => (), + _ => assert!( + false, + "{:?} should have been DataType::TableMap.", + output.data + ), + } + } + + #[test] + fn no_duplicate_database_names() -> Result<(), MTTError> { + let mut store = Store::new(); + let name = "duplicate"; + store.add_new(name).unwrap(); + match store.add_new(name) { + Ok(_) => Err(MTTError::new("should have been an error")), + Err(err) => match err.code { + ErrorCode::DatabaseAlreadyExists(dbname) => { + assert_eq!(dbname, name); + Ok(()) + } + _ => Err(MTTError::new(format!( + "{:?} should have been DatabaseAlreadyExists.", + err.code + ))), + }, + } } } @@ -207,11 +389,19 @@ struct CacheQuery { struct CacheCommit { reply: Sender, + // data: DataType, } impl CacheCommit { - fn new(channel: Sender) -> Self { - Self { reply: channel } + fn new(data: DataType, channel: Sender) -> Result { + match data { + DataType::DBMap(_) => (), + _ => return Err(MTTError::from_code(ErrorCode::InvalidCommitData)), + } + Ok(Self { + // data: data, + reply: channel, + }) } } @@ -219,9 +409,27 @@ mod commits { use super::*; #[test] - fn create() { + fn create() -> Result<(), MTTError> { let (s, _) = unbounded(); - CacheCommit::new(s); + match CacheCommit::new(DataType::new("store"), s) { + Ok(_) => Ok(()), + Err(err) => Err(err), + } + } + + #[test] + fn bad_data_type() -> Result<(), MTTError> { + let (s, _) = unbounded(); + match CacheCommit::new(DataType::new("database"), s) { + Ok(_) => Err(MTTError::new("CacheCommit::new did not return error")), + Err(err) => match err.code { + ErrorCode::InvalidCommitData => Ok(()), + _ => Err(MTTError::new(format!( + "{:?} is not the correct error", + err.code + ))), + }, + } } } @@ -363,7 +571,7 @@ mod caches { let dir = tempdir().unwrap(); let s_cache = start_cache(dir.path()).await; let (s, r) = unbounded(); - let msg = ToCache::Commit(CacheCommit::new(s)); + let msg = ToCache::Commit(CacheCommit::new(DataType::new("store"), s).unwrap()); s_cache.send(msg).await.unwrap(); let result = r.recv().await.unwrap(); match result {