From 05d445c58b6916b0ec8828c7400a681b895e4e3f Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Thu, 29 Jun 2023 00:17:49 -0400 Subject: [PATCH] Added a basic commit function. --- src/morethantext/cache.rs | 53 +++++++++++++++++++++++++++++---------- src/morethantext/mod.rs | 41 +++++++++++++++++++++++++----- 2 files changed, 75 insertions(+), 19 deletions(-) diff --git a/src/morethantext/cache.rs b/src/morethantext/cache.rs index 6f27d40..0056b72 100644 --- a/src/morethantext/cache.rs +++ b/src/morethantext/cache.rs @@ -1,21 +1,29 @@ use super::{ErrorCode, FromCache, MTTError, Store, ToCache, ENTRY}; use async_std::{channel::Receiver, path::PathBuf}; +use std::collections::HashMap; -pub struct Cache; +pub struct Cache { + data: HashMap, +} impl Cache { pub async fn new

(_dir: P) -> Self where P: Into, { - Self {} + let mut data = HashMap::new(); + data.insert(ENTRY.to_string(), Store::new()); + Self { data: data } } - pub async fn listen(&self, listener: Receiver) { + pub async fn listen(&mut self, listener: Receiver) { loop { match listener.recv().await.unwrap() { ToCache::Get(data) => { - data.result.send(self.get(data.id)).await.unwrap(); + data.result.send(self.get(data.data)).await.unwrap(); + } + ToCache::Commit(data) => { + data.result.send(self.commit(data.data)).await.unwrap(); } } } @@ -26,12 +34,16 @@ impl Cache { S: Into, { let idd = id.into(); - if idd == ENTRY { - FromCache::Str(Store::new()) - } else { - FromCache::Error(MTTError::from_code(ErrorCode::IDNotFound(idd))) + match self.data.get(&idd) { + Some(store) => FromCache::Str(store.clone()), + None => FromCache::Error(MTTError::from_code(ErrorCode::IDNotFound(idd))), } } + + pub fn commit(&mut self, data: Store) -> FromCache { + self.data.insert(ENTRY.to_string(), data).unwrap(); + FromCache::Ok + } } #[cfg(test)] @@ -80,12 +92,27 @@ mod engine { } Ok(()) } + + #[async_std::test] + async fn commit_database() { + let dir = tempdir().unwrap(); + let mut cache = Cache::new(dir.path()).await; + let mut store = Store::new(); + let db = "garfield"; + store.add(db).unwrap(); + cache.commit(store.clone()); + let output = cache.get(ENTRY); + match output { + FromCache::Str(result) => assert_eq!(result.list(), store.list()), + _ => assert!(false, "{:?} is not FromCache::Str", output), + } + } } #[cfg(test)] mod messages { use super::{ - super::{start_db, CacheGet}, + super::{start_db, ToCacheMsg}, *, }; use async_std::channel::unbounded; @@ -97,8 +124,8 @@ mod messages { let mtt = start_db(dir.path()).await.unwrap(); let in_s = mtt.to_cache.clone(); let (out_s, out_r) = unbounded(); - let msg = CacheGet { - id: ENTRY.to_string(), + let msg = ToCacheMsg { + data: ENTRY.to_string(), result: out_s, }; in_s.send(ToCache::Get(msg)).await.unwrap(); @@ -115,8 +142,8 @@ mod messages { let mtt = start_db(dir.path()).await.unwrap(); let in_s = mtt.to_cache.clone(); let (out_s, out_r) = unbounded(); - let msg = CacheGet { - id: "bad_id!".to_string(), + let msg = ToCacheMsg { + data: "bad_id!".to_string(), result: out_s, }; in_s.send(ToCache::Get(msg)).await.unwrap(); diff --git a/src/morethantext/mod.rs b/src/morethantext/mod.rs index 2cefbf9..6e73459 100644 --- a/src/morethantext/mod.rs +++ b/src/morethantext/mod.rs @@ -16,18 +16,20 @@ use store::Store; const ENTRY: &str = "EntryPoint"; #[derive(Debug)] -pub struct CacheGet { - id: String, +pub struct ToCacheMsg { + data: D, result: Sender, } #[derive(Debug)] pub enum ToCache { - Get(CacheGet), + Get(ToCacheMsg), + Commit(ToCacheMsg), } #[derive(Debug)] pub enum FromCache { + Ok, Str(Store), Error(MTTError), } @@ -73,14 +75,29 @@ impl MoreThanText { async fn session(&self) -> Result { let (s, r) = unbounded(); - let msg = CacheGet { - id: ENTRY.to_string(), + let msg = ToCacheMsg { + data: ENTRY.to_string(), result: s, }; self.to_cache.send(ToCache::Get(msg)).await.unwrap(); match r.recv().await.unwrap() { FromCache::Str(store) => Ok(store), FromCache::Error(err) => Err(err), + _ => unreachable!(), + } + } + + async fn commit(&self, store: Store) -> Result<(), MTTError> { + let (s, r) = unbounded(); + let msg = ToCacheMsg { + data: store, + result: s, + }; + self.to_cache.send(ToCache::Commit(msg)).await.unwrap(); + match r.recv().await.unwrap() { + FromCache::Ok => Ok(()), + FromCache::Error(err) => Err(err), + _ => unreachable!(), } } } @@ -100,6 +117,18 @@ mod mtt { let expected: Vec = Vec::new(); assert_eq!(store.list(), expected); } + + #[async_std::test] + async fn commit_db() { + let dir = tempdir().unwrap(); + let db = "fred"; + let mtt = start_db(dir.path()).await.unwrap(); + let mut store = mtt.session().await.unwrap(); + store.add(db).unwrap(); + mtt.commit(store).await.unwrap(); + let store2 = mtt.session().await.unwrap(); + assert_eq!(store2.list(), [db]); + } } pub async fn start_db

(dir: P) -> Result @@ -109,7 +138,7 @@ where let path = dir.into(); let (s, r) = unbounded(); spawn(async move { - let cache = Cache::new(path).await; + let mut cache = Cache::new(path).await; cache.listen(r).await; }); Ok(MoreThanText::new(s))