diff --git a/src/data/database.rs b/src/data/database.rs index d3b4b81..b6be3b3 100644 --- a/src/data/database.rs +++ b/src/data/database.rs @@ -29,12 +29,12 @@ mod errora { } } -struct Database { +pub struct Database { tables: HashMap, } impl Database { - fn new() -> Self { + pub fn new() -> Self { Self { tables: HashMap::new(), } diff --git a/src/data/mod.rs b/src/data/mod.rs index 45bf7b5..dbd0695 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -2,3 +2,99 @@ pub mod database; pub mod id; mod record; pub mod table; + +use crate::{data::database::Database, error::MTTError}; +use std::{collections::HashMap, fmt, ops::Deref}; + +#[derive(Debug, Clone)] +pub enum UniError { + DuplicateDB(String), +} + +impl fmt::Display for UniError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + UniError::DuplicateDB(data) => write!(f, "database '{}' already exists", data), + } + } +} + +#[cfg(test)] +mod errors { + use super::*; + + #[test] + fn duplicate_database() { + let name = "name"; + let err = UniError::DuplicateDB(name.to_string()); + assert_eq!( + err.to_string(), + format!("database '{}' already exists", name) + ); + } +} + +struct Universe { + databases: HashMap, +} + +impl Universe { + fn new() -> Self { + Self { + databases: HashMap::new(), + } + } + + fn add_database(&mut self, name: &str, db: Database) -> Result<(), MTTError> { + match self.databases.get(name) { + Some(_) => { + let err = UniError::DuplicateDB(name.to_string()); + Err(err.into()) + } + None => { + self.databases.insert(name.to_string(), db); + Ok(()) + } + } + } +} + +impl Deref for Universe { + type Target = HashMap; + + fn deref(&self) -> &Self::Target { + &self.databases + } +} + +#[cfg(test)] +mod universes { + use super::*; + + #[test] + fn create_universe() { + let uni = Universe::new(); + assert_eq!(uni.len(), 0); + } + + #[test] + fn add_database() { + let mut uni = Universe::new(); + let db = Database::new(); + uni.add_database("barney", db).unwrap(); + assert_eq!(uni.len(), 1); + } + + #[test] + fn no_duplicate_dbs() { + let mut uni = Universe::new(); + let db1 = Database::new(); + let db2 = Database::new(); + let name = "duplicate"; + uni.add_database("barney", db2).unwrap(); + match uni.add_database("barney", db1) { + Ok(_) => unreachable!("should have been an error"), + Err(err) => {} + } + } +} diff --git a/src/error.rs b/src/error.rs index 0e7660c..c16bb79 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,4 @@ -use crate::data::{database::DBError, id::IDError, table::TBLError}; +use crate::data::{database::DBError, id::IDError, table::TBLError, UniError}; use std::{error::Error, fmt}; #[derive(Debug)] @@ -6,6 +6,7 @@ pub enum ErrorType { DBErr(DBError), IDErr(IDError), TBLErr(TBLError), + UniErr(UniError), } impl From for ErrorType { @@ -26,12 +27,19 @@ impl From for ErrorType { } } +impl From for ErrorType { + fn from(value: UniError) -> Self { + ErrorType::UniErr(value) + } +} + impl fmt::Display for ErrorType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ErrorType::DBErr(data) => write!(f, "database: {}", data), ErrorType::IDErr(data) => write!(f, "id: {}", data), ErrorType::TBLErr(data) => write!(f, "table: {}", data), + ErrorType::UniErr(data) => write!(f, "global: {}", data), } } } @@ -60,6 +68,13 @@ mod errortypes { let result = ErrorType::from(err.clone()); assert_eq!(result.to_string(), format!("table: {}", err)); } + + #[test] + fn universal_error() { + let err = UniError::DuplicateDB("bad".to_string()); + let result = ErrorType::from(err.clone()); + assert_eq!(result.to_string(), format!("global: {}", err)); + } } #[derive(Debug)] @@ -109,6 +124,12 @@ impl From for MTTError { } } +impl From for MTTError { + fn from(value: UniError) -> Self { + Self { err: value.into() } + } +} + #[cfg(test)] mod errors { use super::*; @@ -142,4 +163,11 @@ mod errors { let err = MTTError::from(error.clone()); assert_eq!(err.to_string(), ErrorType::TBLErr(error).to_string()); } + + #[test] + fn from_global_error() { + let error = UniError::DuplicateDB(rand_str()); + let err = MTTError::from(error.clone()); + assert_eq!(err.to_string(), ErrorType::UniErr(error).to_string()); + } }