From c26089caed9b96fc748a920f26eb33b56e741e3c Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Sat, 24 Jun 2023 10:48:35 -0400 Subject: [PATCH] Protect against duplicate databases. --- src/morethantext/error.rs | 14 +++++++++++ src/morethantext/store.rs | 49 +++++++++++++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/morethantext/error.rs b/src/morethantext/error.rs index f4e080a..641f604 100644 --- a/src/morethantext/error.rs +++ b/src/morethantext/error.rs @@ -6,6 +6,8 @@ pub enum ErrorCode { Undefined(String), // Cache IDNotFound(String), + // Store + DuplicateDatabase(String), } impl fmt::Display for ErrorCode { @@ -13,6 +15,7 @@ impl fmt::Display for ErrorCode { match self { ErrorCode::Undefined(msg) => write!(f, "{}", msg), ErrorCode::IDNotFound(id) => write!(f, "ID '{}' not found", id), + ErrorCode::DuplicateDatabase(name) => write!(f, "database '{}' already exists", name), } } } @@ -37,6 +40,17 @@ mod errorcodes { assert_eq!(err.to_string(), format!("ID '{}' not found", item)); } } + + #[test] + fn duplicate_database() { + for item in ITEMS { + let err = ErrorCode::DuplicateDatabase(item.to_string()); + assert_eq!( + err.to_string(), + format!("database '{}' already exists", item) + ); + } + } } #[derive(Debug)] diff --git a/src/morethantext/store.rs b/src/morethantext/store.rs index 25c7cf4..361e1ca 100644 --- a/src/morethantext/store.rs +++ b/src/morethantext/store.rs @@ -1,4 +1,4 @@ -use super::{Data, Database}; +use super::{Data, Database, ErrorCode, MTTError}; use std::collections::HashMap; #[derive(Clone, Debug)] @@ -13,9 +13,18 @@ impl Store { } } - pub fn add(&mut self, name: &str) { - let storage = Data::from_data(Database::new()); - self.data.insert(name.to_string(), storage); + 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 get(&self, name: &str) -> Option<&Data> { @@ -29,7 +38,7 @@ impl Store { #[cfg(test)] mod storage { - use super::{super::MTTError, *}; + use super::*; #[test] fn create_new() { @@ -39,14 +48,40 @@ mod storage { } #[test] - fn add_database() { + fn add_db_by_str() { let mut store = Store::new(); let name = "Melvin"; - store.add(name); + 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 get_bad_database() -> Result<(), MTTError> { let store = Store::new();