use async_std::sync::{Arc, RwLock}; use std::{collections::HashMap, fmt, str::FromStr}; #[derive(Clone, PartialEq)] pub enum Field { Table, } impl fmt::Display for Field { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Field::Table => write!(f, "table"), } } } impl FromStr for Field { type Err = (); fn from_str(input: &str) -> Result { match input { "table" => Ok(Field::Table), _ => Err(()), } } } pub struct Table { fields: Arc>>, } impl Table { pub async fn new() -> Self { Self { fields: Arc::new(RwLock::new(HashMap::new())), } } pub async fn add_field(&self, name: &str, ftype: &str) { let mut fmap = self.fields.write().await; fmap.insert(name.to_string(), Field::from_str(ftype).unwrap()); } pub async fn fields(&self) -> HashMap { let fmap = self.fields.read().await; fmap.clone() } } pub struct Database; impl Database { pub async fn new() -> Self { Self {} } pub async fn add_table(&self, _name: String) -> Table { Table::new().await } } #[cfg(test)] mod tables { use super::*; #[async_std::test] async fn new_table() { Table::new().await; } #[async_std::test] async fn add_field() { let table = Table::new().await; let mut expected: HashMap = HashMap::new(); expected.insert("stan".to_string(), Field::Table); expected.insert("lee".to_string(), Field::Table); table.add_field("stan", "table").await; table.add_field("lee", "table").await; let output = table.fields().await; assert!(output == expected, "Table did not get the fields added."); } } #[cfg(test)] mod databases { use super::*; #[async_std::test] async fn new_database() { Database::new().await; } #[async_std::test] async fn add_table() { let db = Database::new().await; db.add_table("fred".to_string()).await; } } #[cfg(test)] mod fields { use super::*; fn get_field_map() -> HashMap { let mut fields: HashMap = HashMap::new(); fields.insert("table".to_string(), Field::Table); return fields; } #[test] fn convert_to_string() { for (key, value) in get_field_map().iter() { assert!(key == &value.to_string(), "\n\nGot: {}\nWant: {}\n\n", value.to_string(), key); } } #[test] fn convert_from_string() { for (key, value) in get_field_map().iter() { assert!(&Field::from_str(key).unwrap() == value, "\n\nDid not return a Field::{}", key); } } #[test] fn convert_from_string_error() -> Result<(), String> { match Field::from_str("jkljkl") { Ok(_) => Err("Field jkljkl should not exist.".to_string()), Err(_) => Ok(()), } } }