Make backend generic over Read/Write
This commit is contained in:
parent
73c1e79084
commit
91c427925b
3 changed files with 27 additions and 19 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue