use super::{Data, Database, ErrorCode, MTTError}; use std::collections::HashMap; #[derive(Clone, Debug)] pub struct Store { data: HashMap>, } impl Store { 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::DuplicateDatabase(db_name))), None => { self.data.insert(db_name, Data::from_data(Database::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::DuplicateDatabase(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 storage { use super::*; #[test] fn create_new() { let store = Store::new(); let expected: Vec = Vec::new(); assert_eq!(store.list(), expected); } #[test] fn add_db_by_str() { let mut store = Store::new(); let name = "Melvin"; store.add(name).unwrap(); let output = store.get(name); assert!(output.is_some(), "Get returned none."); } #[test] fn add_db_by_string() { let mut store = Store::new(); let name = "Marvin"; store.add(name.to_string()).unwrap(); let output = store.get(name); assert!(output.is_some(), "Get returned none."); } #[test] fn fail_on_duplicates() -> Result<(), MTTError> { let mut store = Store::new(); let name = "Mickie"; store.add(name).unwrap(); match store.add(name) { Ok(_) => Err(MTTError::new("duplicates should error")), Err(err) => match err.code { ErrorCode::DuplicateDatabase(db_name) => { assert_eq!(db_name, name); Ok(()) } _ => Err(MTTError::new(format!("{:?} is not DuplicateDatabase", err))), }, } } #[test] fn add_using_cache_id() { let mut store = Store::new(); let name = "fred"; let id = "12345"; store.add_by_id(name, id).unwrap(); let output = store.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 store = Store::new(); let name = "barney"; let id = "67890"; store.add_by_id(name.to_string(), id).unwrap(); let output = store.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 store = Store::new(); let name = "betty"; store.add_by_id(name, "fghij").unwrap(); match store.add_by_id(name, "klmno") { Ok(_) => assert!(false, "Duplicates should error."), Err(err) => match err.code { ErrorCode::DuplicateDatabase(db_name) => assert_eq!(db_name, name), _ => assert!(false, "{:?} is not DuplicateDatabase", err), }, } } #[test] fn add_by_cache_id_string() { let mut store = Store::new(); let name = "wilma"; let id = "abcdef"; store.add_by_id(name, id.to_string()).unwrap(); let output = store.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 store = Store::new(); match store.get("missing") { Some(_) => Err(MTTError::new("Should have returned None.")), None => Ok(()), } } #[test] fn get_list() { let mut store = Store::new(); let mut ids = ["one", "two", "three", "four", "five"]; for name in ids { store.add(name.to_string()).unwrap(); } ids.sort(); assert_eq!(store.list(), ids); } }