pub mod error; use async_std::{fs::create_dir, path::Path}; use error::DBError; use rand::{distributions::Alphanumeric, thread_rng, Rng}; const DATA: &str = "data"; enum CacheEntry { Raw(String), } #[derive(Clone)] pub struct MoreThanText; impl MoreThanText { pub async fn new(dir: &str) -> Result { let data_dir = Path::new(dir).join(DATA); if !data_dir.is_dir().await { match create_dir(data_dir).await { Ok(_) => (), Err(err) => { let mut error = DBError::new("failed to create data directory"); error.add_source(err); return Err(error); } } } Ok(Self {}) } async fn add_entry(&self, _entry: CacheEntry) -> String { let id: String = thread_rng().sample_iter(&Alphanumeric).take(32).collect(); return id; } } #[cfg(test)] mod setup { use super::*; use tempfile::{tempdir, TempDir}; pub struct MTT { pub db: MoreThanText, pub dir: TempDir, } impl MTT { pub async fn new() -> Self { let dir = tempdir().unwrap(); let db = MoreThanText::new(dir.path().to_str().unwrap()) .await .unwrap(); Self { db: db, dir: dir } } } } #[cfg(test)] mod init { use super::*; use std::error::Error; use tempfile::tempdir; #[async_std::test] async fn create_data_dir() { let dir = tempdir().unwrap(); MoreThanText::new(dir.path().to_str().unwrap()) .await .unwrap(); let data_dir = dir.path().join(DATA); assert!(data_dir.is_dir(), "Did not create the data directory."); dir.close().unwrap(); } #[async_std::test] async fn existing_data_dir() { let dir = tempdir().unwrap(); let data_dir = dir.path().join(DATA); create_dir(data_dir).await.unwrap(); MoreThanText::new(dir.path().to_str().unwrap()) .await .unwrap(); dir.close().unwrap(); } #[async_std::test] async fn bad_data_dir() { match MoreThanText::new("kljsdgfhslkfrh").await { Ok(_) => assert!(false, "This test should fail to create a data directory"), Err(err) => { assert_eq!(err.to_string(), "failed to create data directory"); assert!(err.source().is_some(), "Must include the source error."); } }; } } #[cfg(test)] mod cache { use super::*; use setup::MTT; #[async_std::test] async fn ids_are_random() { let mtt = MTT::new().await; let data1 = CacheEntry::Raw("one".to_string()); let data2 = CacheEntry::Raw("two".to_string()); let id1 = mtt.db.add_entry(data1).await; let id2 = mtt.db.add_entry(data2).await; assert_ne!(id1, id2, "Ids should be unique.") } }