From 52011a59b2118f183268eb620eca35fd841bf294 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 18 Jun 2017 11:16:27 +0200 Subject: [PATCH] Move serialize/deserialize calls of Entry to backend --- libimagstore/src/file_abstraction/fs.rs | 15 +++++--- libimagstore/src/file_abstraction/inmemory.rs | 10 ++++-- libimagstore/src/file_abstraction/mod.rs | 35 ++++++++++++++----- libimagstore/src/store.rs | 8 ++--- 4 files changed, 47 insertions(+), 21 deletions(-) diff --git a/libimagstore/src/file_abstraction/fs.rs b/libimagstore/src/file_abstraction/fs.rs index 4210a2e5..b8770f1b 100644 --- a/libimagstore/src/file_abstraction/fs.rs +++ b/libimagstore/src/file_abstraction/fs.rs @@ -25,6 +25,8 @@ use error::{MapErrInto, StoreError as SE, StoreErrorKind as SEK}; use super::FileAbstraction; use super::FileAbstractionInstance; +use store::Entry; +use storeid::StoreId; #[derive(Debug)] pub enum FSFileAbstractionInstance { @@ -37,7 +39,7 @@ impl FileAbstractionInstance for FSFileAbstractionInstance { /** * Get the content behind this file */ - fn get_file_content(&mut self) -> Result { + fn get_file_content(&mut self, id: StoreId) -> Result { debug!("Getting lazy file: {:?}", self); let (file, path) = match *self { FSFileAbstractionInstance::File(ref mut f, _) => return { @@ -50,6 +52,7 @@ impl FileAbstractionInstance for FSFileAbstractionInstance { f.read_to_string(&mut s) .map_err_into(SEK::IoError) .map(|_| s) + .and_then(|s| Entry::from_str(id, &s)) }, FSFileAbstractionInstance::Absent(ref p) => (try!(open_file(p).map_err_into(SEK::FileNotFound)), p.clone()), @@ -60,6 +63,7 @@ impl FileAbstractionInstance for FSFileAbstractionInstance { f.read_to_string(&mut s) .map_err_into(SEK::IoError) .map(|_| s) + .and_then(|s| Entry::from_str(id, &s)) } else { unreachable!() } @@ -68,22 +72,25 @@ impl FileAbstractionInstance for FSFileAbstractionInstance { /** * Write the content of this file */ - fn write_file_content(&mut self, buf: &[u8]) -> Result<(), SE> { + fn write_file_content(&mut self, buf: &Entry) -> Result<(), SE> { use std::io::Write; + + let buf = buf.to_str().into_bytes(); + let (file, path) = match *self { FSFileAbstractionInstance::File(ref mut f, _) => return { // We seek to the beginning of the file since we expect each // access to the file to be in a different context try!(f.seek(SeekFrom::Start(0)) .map_err_into(SEK::FileNotCreated)); - f.write_all(buf).map_err_into(SEK::FileNotWritten) + f.write_all(&buf).map_err_into(SEK::FileNotWritten) }, FSFileAbstractionInstance::Absent(ref p) => (try!(create_file(p).map_err_into(SEK::FileNotCreated)), p.clone()), }; *self = FSFileAbstractionInstance::File(file, path); if let FSFileAbstractionInstance::File(ref mut f, _) = *self { - return f.write_all(buf).map_err_into(SEK::FileNotWritten); + return f.write_all(&buf).map_err_into(SEK::FileNotWritten); } unreachable!(); } diff --git a/libimagstore/src/file_abstraction/inmemory.rs b/libimagstore/src/file_abstraction/inmemory.rs index c93e3679..1323d070 100644 --- a/libimagstore/src/file_abstraction/inmemory.rs +++ b/libimagstore/src/file_abstraction/inmemory.rs @@ -32,6 +32,8 @@ use libimagerror::into::IntoError; use super::FileAbstraction; use super::FileAbstractionInstance; use error::MapErrInto; +use store::Entry; +use storeid::StoreId; type Backend = Arc>>>>>; @@ -60,7 +62,7 @@ impl FileAbstractionInstance for InMemoryFileAbstractionInstance { /** * Get the mutable file behind a InMemoryFileAbstraction object */ - fn get_file_content(&mut self) -> Result { + fn get_file_content(&mut self, id: StoreId) -> Result { debug!("Getting lazy file: {:?}", self); let p = self.absent_path.clone(); @@ -74,6 +76,7 @@ impl FileAbstractionInstance for InMemoryFileAbstractionInstance { t.read_to_string(&mut s) .map_err_into(SEK::IoError) .map(|_| s) + .and_then(|s| Entry::from_str(id, &s)) }) } @@ -81,7 +84,8 @@ impl FileAbstractionInstance for InMemoryFileAbstractionInstance { } } - fn write_file_content(&mut self, buf: &[u8]) -> Result<(), SE> { + fn write_file_content(&mut self, buf: &Entry) -> Result<(), SE> { + let buf = buf.to_str().into_bytes(); match *self { InMemoryFileAbstractionInstance { ref absent_path, .. } => { let mut mtx = self.fs_abstraction.lock().expect("Locking Mutex failed"); @@ -90,7 +94,7 @@ impl FileAbstractionInstance for InMemoryFileAbstractionInstance { if let Some(ref mut cur) = backend.get_mut(absent_path) { let mut vec = cur.get_mut(); vec.clear(); - vec.extend_from_slice(buf); + vec.extend_from_slice(&buf); return Ok(()); } let vec = Vec::from(buf); diff --git a/libimagstore/src/file_abstraction/mod.rs b/libimagstore/src/file_abstraction/mod.rs index 82e3ce95..9fb30f89 100644 --- a/libimagstore/src/file_abstraction/mod.rs +++ b/libimagstore/src/file_abstraction/mod.rs @@ -21,7 +21,8 @@ use std::path::PathBuf; use std::fmt::Debug; use error::StoreError as SE; - +use store::Entry; +use storeid::StoreId; mod fs; mod inmemory; @@ -44,27 +45,43 @@ pub trait FileAbstraction : Debug { /// An abstraction trait over actions on files pub trait FileAbstractionInstance : Debug { - fn get_file_content(&mut self) -> Result; - fn write_file_content(&mut self, buf: &[u8]) -> Result<(), SE>; + + /// Get the contents of the FileAbstractionInstance, as Entry object. + /// + /// The `StoreId` is passed because the backend does not know where the Entry lives, but the + /// Entry type itself must be constructed with the id. + fn get_file_content(&mut self, id: StoreId) -> Result; + fn write_file_content(&mut self, buf: &Entry) -> Result<(), SE>; } #[cfg(test)] mod test { + use std::path::PathBuf; + use super::FileAbstractionInstance; use super::inmemory::InMemoryFileAbstraction; use super::inmemory::InMemoryFileAbstractionInstance; - use std::path::PathBuf; + use storeid::StoreId; + use store::Entry; #[test] fn lazy_file() { let fs = InMemoryFileAbstraction::new(); - let mut path = PathBuf::from("/tests"); + let mut path = PathBuf::from("tests"); path.set_file_name("test1"); - let mut lf = InMemoryFileAbstractionInstance::new(fs.backend().clone(), path); - lf.write_file_content(b"Hello World").unwrap(); - let bah = lf.get_file_content().unwrap(); - assert_eq!(bah, "Hello World"); + let mut lf = InMemoryFileAbstractionInstance::new(fs.backend().clone(), path.clone()); + + let loca = StoreId::new_baseless(path).unwrap(); + let file = Entry::from_str(loca.clone(), r#"--- +[imag] +version = "0.3.0" +--- +Hello World"#).unwrap(); + + lf.write_file_content(&file).unwrap(); + let bah = lf.get_file_content(loca).unwrap(); + assert_eq!(bah.get_content(), "Hello World"); } } diff --git a/libimagstore/src/store.rs b/libimagstore/src/store.rs index 41c3b85b..b3d10cfc 100644 --- a/libimagstore/src/store.rs +++ b/libimagstore/src/store.rs @@ -158,13 +158,11 @@ impl StoreEntry { } fn get_entry(&mut self) -> Result { - let id = &self.id.clone(); if !self.is_borrowed() { self.file - .get_file_content() - .and_then(|content| Entry::from_str(id.clone(), &content)) + .get_file_content(self.id.clone()) .or_else(|err| if err.err_type() == SEK::FileNotFound { - Ok(Entry::new(id.clone())) + Ok(Entry::new(self.id.clone())) } else { Err(err) }) @@ -176,7 +174,7 @@ impl StoreEntry { fn write_entry(&mut self, entry: &Entry) -> Result<()> { if self.is_borrowed() { assert_eq!(self.id, entry.location); - self.file.write_file_content(entry.to_str().as_bytes()) + self.file.write_file_content(entry) .map_err_into(SEK::FileError) .map(|_| ()) } else {