Make backend generic over Read/Write

This commit is contained in:
Matthias Beyer 2017-06-17 23:06:19 +02:00
parent 73c1e79084
commit 91c427925b
3 changed files with 27 additions and 19 deletions

View file

@ -69,7 +69,7 @@ impl JsonMapper {
} }
impl Mapper for JsonMapper { impl Mapper for JsonMapper {
fn read_to_fs(&self, mut r: Box<Read>, hm: &mut HashMap<PathBuf, Cursor<Vec<u8>>>) -> Result<()> { fn read_to_fs<R: Read>(&self, r: &mut R, hm: &mut HashMap<PathBuf, Cursor<Vec<u8>>>) -> Result<()> {
let mut document = { let mut document = {
let mut s = String::new(); let mut s = String::new();
try!(r.read_to_string(&mut s).map_err_into(SEK::IoError)); try!(r.read_to_string(&mut s).map_err_into(SEK::IoError));
@ -102,7 +102,7 @@ impl Mapper for JsonMapper {
Ok(()) Ok(())
} }
fn fs_to_write(&self, hm: &mut HashMap<PathBuf, Cursor<Vec<u8>>>, out: &mut Write) -> Result<()> { fn fs_to_write<W: Write>(&self, hm: &mut HashMap<PathBuf, Cursor<Vec<u8>>>, out: &mut W) -> Result<()> {
#[derive(Serialize)] #[derive(Serialize)]
struct OutDocument { struct OutDocument {
version: String, version: String,
@ -155,11 +155,11 @@ mod test {
} }
} }
"#; "#;
let json = Cursor::new(String::from(json).into_bytes()); let mut json = Cursor::new(String::from(json).into_bytes());
let mapper = JsonMapper::new(); let mapper = JsonMapper::new();
let mut hm = HashMap::new(); let mut hm = HashMap::new();
let io_res = mapper.read_to_fs(Box::new(json), &mut hm); let io_res = mapper.read_to_fs(&mut json, &mut hm);
assert!(io_res.is_ok()); assert!(io_res.is_ok());
assert_eq!(1, hm.len()); // we should have exactly one entry assert_eq!(1, hm.len()); // we should have exactly one entry

View file

@ -24,8 +24,8 @@ use std::path::PathBuf;
use store::Result; use store::Result;
pub trait Mapper { pub trait Mapper {
fn read_to_fs(&self, Box<Read>, &mut HashMap<PathBuf, Cursor<Vec<u8>>>) -> Result<()>; fn read_to_fs<R: Read>(&self, &mut R, &mut HashMap<PathBuf, Cursor<Vec<u8>>>) -> Result<()>;
fn fs_to_write(&self, &mut HashMap<PathBuf, Cursor<Vec<u8>>>, &mut Write) -> Result<()>; fn fs_to_write<W: Write>(&self, &mut HashMap<PathBuf, Cursor<Vec<u8>>>, &mut W) -> Result<()>;
} }
pub mod json; pub mod json;

View file

@ -17,6 +17,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
// //
use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt::Debug; use std::fmt::Debug;
@ -43,25 +44,27 @@ use self::mapper::Mapper;
// Because this is not exported in super::inmemory; // Because this is not exported in super::inmemory;
type Backend = Arc<Mutex<RefCell<HashMap<PathBuf, Cursor<Vec<u8>>>>>>; type Backend = Arc<Mutex<RefCell<HashMap<PathBuf, Cursor<Vec<u8>>>>>>;
pub struct StdIoFileAbstraction<M: Mapper> { pub struct StdIoFileAbstraction<W: Write, M: Mapper> {
mapper: M, mapper: M,
mem: InMemoryFileAbstraction, mem: InMemoryFileAbstraction,
out: Box<Write>, out: Rc<RefCell<W>>,
} }
impl<M> Debug for StdIoFileAbstraction<M> impl<W, M> Debug for StdIoFileAbstraction<W, M>
where M: Mapper where M: Mapper,
W: Write
{ {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
write!(f, "StdIoFileAbstraction({:?}", self.mem) write!(f, "StdIoFileAbstraction({:?}", self.mem)
} }
} }
impl<M> StdIoFileAbstraction<M> impl<W, M> StdIoFileAbstraction<W, M>
where M: Mapper where M: Mapper,
W: Write
{ {
pub fn new(in_stream: Box<Read>, out_stream: Box<Write>, mapper: M) -> Result<StdIoFileAbstraction<M>, SE> { pub fn new<R: Read>(in_stream: &mut R, out_stream: Rc<RefCell<W>>, mapper: M) -> Result<StdIoFileAbstraction<W, M>, SE> {
let mem = InMemoryFileAbstraction::new(); let mem = InMemoryFileAbstraction::new();
{ {
@ -85,13 +88,18 @@ impl<M> StdIoFileAbstraction<M>
} }
impl<M> Drop for StdIoFileAbstraction<M> impl<W, M> Drop for StdIoFileAbstraction<W, M>
where M: Mapper where M: Mapper,
W: Write
{ {
fn drop(&mut self) { fn drop(&mut self) {
use std::ops::DerefMut;
let fill_res = match self.mem.backend().lock() { let fill_res = match self.mem.backend().lock() {
Err(_) => Err(SEK::LockError.into_error()), Err(_) => Err(SEK::LockError.into_error()),
Ok(mut mtx) => self.mapper.fs_to_write(mtx.get_mut(), &mut *self.out) Ok(mut mtx) => {
self.mapper.fs_to_write(mtx.get_mut(), self.out.borrow_mut().deref_mut())
},
}; };
// We can do nothing but end this here with a trace. // We can do nothing but end this here with a trace.
@ -101,7 +109,7 @@ impl<M> Drop for StdIoFileAbstraction<M>
} }
} }
impl<M: Mapper> FileAbstraction for StdIoFileAbstraction<M> { impl<W: Write, M: Mapper> FileAbstraction for StdIoFileAbstraction<W, M> {
fn remove_file(&self, path: &PathBuf) -> Result<(), SE> { fn remove_file(&self, path: &PathBuf) -> Result<(), SE> {
self.mem.remove_file(path) self.mem.remove_file(path)