Protect against duplicate databases.
This commit is contained in:
		@@ -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)]
 | 
			
		||||
 
 | 
			
		||||
@@ -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<S>(&mut self, name: S) -> Result<(), MTTError>
 | 
			
		||||
    where
 | 
			
		||||
        S: Into<String>,
 | 
			
		||||
    {
 | 
			
		||||
        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<Database>> {
 | 
			
		||||
@@ -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();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user