use super::{Data, ErrorCode, MTTError, Table}; use std::collections::HashMap; #[derive(Clone, Debug)] pub struct Database { data: HashMap>, } impl Database { pub fn new() -> Self { Self { data: HashMap::new(), } } pub fn add(&mut self, name: S) -> Result<(), MTTError> where S: Into, { let db_name = name.into(); match self.get(&db_name) { Some(_) => Err(MTTError::from_code(ErrorCode::DuplicateTable(db_name))), None => { self.data.insert(db_name, Data::from_data(Table::new())); Ok(()) } } } pub fn add_by_id(&mut self, name: S, id: D) -> Result<(), MTTError> where S: Into, D: Into, { let db_name = name.into(); match self.get(&db_name) { Some(_) => Err(MTTError::from_code(ErrorCode::DuplicateTable(db_name))), None => { self.data.insert(db_name, Data::from_id(id.into())); Ok(()) } } } pub fn get(&self, name: &str) -> Option<&Data> { self.data.get(name) } pub fn list(&self) -> Vec { let mut names = Vec::new(); for name in self.data.keys() { names.push(name.to_string()); } names.sort(); names } } #[cfg(test)] mod databases { use super::*; #[test] fn create_new() { let db = Database::new(); let expected: Vec = Vec::new(); assert_eq!(db.list(), expected); } #[test] fn add_db_by_str() { let mut db = Database::new(); let name = "Melvin"; db.add(name).unwrap(); let output = db.get(name); assert!(output.is_some(), "Get returned none."); } #[test] fn add_db_by_string() { let mut db = Database::new(); let name = "Marvin"; db.add(name.to_string()).unwrap(); let output = db.get(name); assert!(output.is_some(), "Get returned none."); } #[test] fn fail_on_duplicates() -> Result<(), MTTError> { let mut db = Database::new(); let name = "Mickie"; db.add(name).unwrap(); match db.add(name) { Ok(_) => Err(MTTError::new("duplicates should error")), Err(err) => match err.code { ErrorCode::DuplicateTable(db_name) => { assert_eq!(db_name, name); Ok(()) } _ => Err(MTTError::new(format!("{:?} is not DuplicateTable", err))), }, } } #[test] fn add_using_cache_id() { let mut db = Database::new(); let name = "fred"; let id = "12345"; db.add_by_id(name, id).unwrap(); let output = db.get(name).unwrap(); assert!(output.data.is_none(), "there should be no data"); assert_eq!(output.id, Some(id.to_string())); } #[test] fn add_by_cache_id_name_string() { let mut db = Database::new(); let name = "barney"; let id = "67890"; db.add_by_id(name.to_string(), id).unwrap(); let output = db.get(name).unwrap(); assert!(output.data.is_none(), "there should be no data"); assert_eq!(output.id, Some(id.to_string())); } #[test] fn no_duplicate_databases_for_add_by_id() { let mut db = Database::new(); let name = "betty"; db.add_by_id(name, "fghij").unwrap(); match db.add_by_id(name, "klmno") { Ok(_) => assert!(false, "Duplicates should error."), Err(err) => match err.code { ErrorCode::DuplicateTable(db_name) => assert_eq!(db_name, name), _ => assert!(false, "{:?} is not DuplicateTable", err), }, } } #[test] fn add_by_cache_id_string() { let mut db = Database::new(); let name = "wilma"; let id = "abcdef"; db.add_by_id(name, id.to_string()).unwrap(); let output = db.get(name).unwrap(); assert!(output.data.is_none(), "there should be no data"); assert_eq!(output.id, Some(id.to_string())); } #[test] fn get_bad_database() -> Result<(), MTTError> { let db = Database::new(); match db.get("missing") { Some(_) => Err(MTTError::new("Should have returned None.")), None => Ok(()), } } #[test] fn get_list() { let mut db = Database::new(); let mut ids = ["one", "two", "three", "four", "five"]; for name in ids { db.add(name.to_string()).unwrap(); } ids.sort(); assert_eq!(db.list(), ids); } }