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 {
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 s = String::new();
try!(r.read_to_string(&mut s).map_err_into(SEK::IoError));
@ -102,7 +102,7 @@ impl Mapper for JsonMapper {
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)]
struct OutDocument {
version: String,
@ -155,11 +155,11 @@ mod test {
}
}
"#;
let json = Cursor::new(String::from(json).into_bytes());
let mapper = JsonMapper::new();
let mut hm = HashMap::new();
let mut json = Cursor::new(String::from(json).into_bytes());
let mapper = JsonMapper::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_eq!(1, hm.len()); // we should have exactly one entry

View file

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

View file

@ -17,6 +17,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
use std::fmt::Debug;
@ -43,25 +44,27 @@ use self::mapper::Mapper;
// Because this is not exported in super::inmemory;
type Backend = Arc<Mutex<RefCell<HashMap<PathBuf, Cursor<Vec<u8>>>>>>;
pub struct StdIoFileAbstraction<M: Mapper> {
pub struct StdIoFileAbstraction<W: Write, M: Mapper> {
mapper: M,
mem: InMemoryFileAbstraction,
out: Box<Write>,
out: Rc<RefCell<W>>,
}
impl<M> Debug for StdIoFileAbstraction<M>
where M: Mapper
impl<W, M> Debug for StdIoFileAbstraction<W, M>
where M: Mapper,
W: Write
{
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
write!(f, "StdIoFileAbstraction({:?}", self.mem)
}
}
impl<M> StdIoFileAbstraction<M>
where M: Mapper
impl<W, M> StdIoFileAbstraction<W, M>
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();
{
@ -85,13 +88,18 @@ impl<M> StdIoFileAbstraction<M>
}
impl<M> Drop for StdIoFileAbstraction<M>
where M: Mapper
impl<W, M> Drop for StdIoFileAbstraction<W, M>
where M: Mapper,
W: Write
{
fn drop(&mut self) {
use std::ops::DerefMut;
let fill_res = match self.mem.backend().lock() {
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.
@ -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> {
self.mem.remove_file(path)