Added a basic commit function.
This commit is contained in:
		@@ -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<String, Store>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Cache {
 | 
			
		||||
    pub async fn new<P>(_dir: P) -> Self
 | 
			
		||||
    where
 | 
			
		||||
        P: Into<PathBuf>,
 | 
			
		||||
    {
 | 
			
		||||
        Self {}
 | 
			
		||||
        let mut data = HashMap::new();
 | 
			
		||||
        data.insert(ENTRY.to_string(), Store::new());
 | 
			
		||||
        Self { data: data }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn listen(&self, listener: Receiver<ToCache>) {
 | 
			
		||||
    pub async fn listen(&mut self, listener: Receiver<ToCache>) {
 | 
			
		||||
        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<String>,
 | 
			
		||||
    {
 | 
			
		||||
        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();
 | 
			
		||||
 
 | 
			
		||||
@@ -16,18 +16,20 @@ use store::Store;
 | 
			
		||||
const ENTRY: &str = "EntryPoint";
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct CacheGet {
 | 
			
		||||
    id: String,
 | 
			
		||||
pub struct ToCacheMsg<D> {
 | 
			
		||||
    data: D,
 | 
			
		||||
    result: Sender<FromCache>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub enum ToCache {
 | 
			
		||||
    Get(CacheGet),
 | 
			
		||||
    Get(ToCacheMsg<String>),
 | 
			
		||||
    Commit(ToCacheMsg<Store>),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub enum FromCache {
 | 
			
		||||
    Ok,
 | 
			
		||||
    Str(Store),
 | 
			
		||||
    Error(MTTError),
 | 
			
		||||
}
 | 
			
		||||
@@ -73,14 +75,29 @@ impl MoreThanText {
 | 
			
		||||
 | 
			
		||||
    async fn session(&self) -> Result<Store, MTTError> {
 | 
			
		||||
        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<String> = 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<P>(dir: P) -> Result<MoreThanText, MTTError>
 | 
			
		||||
@@ -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))
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user