From 447f2610ef4b9b312f8c73dec9fdc19fed61036c Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 17 Jun 2017 18:50:28 +0200 Subject: [PATCH] Make StdIo backend abstract over IO->"fs"->IO mapper --- libimagstore/src/file_abstraction.rs | 73 +++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/libimagstore/src/file_abstraction.rs b/libimagstore/src/file_abstraction.rs index 69d309c7..ad4697d8 100644 --- a/libimagstore/src/file_abstraction.rs +++ b/libimagstore/src/file_abstraction.rs @@ -387,6 +387,10 @@ mod stdio { use std::sync::Arc; use std::sync::Mutex; + use libimagerror::into::IntoError; + use libimagerror::trace::*; + + use error::StoreErrorKind as SEK; use error::StoreError as SE; use super::FileAbstraction; use super::FileAbstractionInstance; @@ -395,26 +399,55 @@ mod stdio { // Because this is not exported in super::inmemory; type Backend = Arc>>>>>; - pub struct StdIoFileAbstraction { - mem: InMemoryFileAbstraction, - stdin: Box, - stdout: Box, + mod mapper { + use std::collections::HashMap; + use std::io::Cursor; + use std::io::{Read, Write}; + use std::path::PathBuf; + use store::Result; + + pub trait Mapper { + fn read_to_fs(&self, Box, &mut HashMap>>) -> Result<()>; + fn fs_to_write(&self, &mut HashMap>>, &mut Write) -> Result<()>; + } } - impl Debug for StdIoFileAbstraction { + use self::mapper::Mapper; + + pub struct StdIoFileAbstraction { + mapper: M, + mem: InMemoryFileAbstraction, + out: Box, + } + + impl Debug for StdIoFileAbstraction + where M: Mapper + { fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { write!(f, "StdIoFileAbstraction({:?}", self.mem) } } - impl StdIoFileAbstraction { + impl StdIoFileAbstraction + where M: Mapper + { - pub fn new(in_stream: Box, out_stream: Box) -> StdIoFileAbstraction { - StdIoFileAbstraction { - mem: InMemoryFileAbstraction::new(), - stdin: in_stream, - stdout: out_stream + pub fn new(in_stream: Box, out_stream: Box, mapper: M) -> Result, SE> { + let mem = InMemoryFileAbstraction::new(); + + { + let fill_res = match mem.backend().lock() { + Err(_) => Err(SEK::LockError.into_error()), + Ok(mut mtx) => mapper.read_to_fs(in_stream, mtx.get_mut()) + }; + let _ = try!(fill_res); } + + Ok(StdIoFileAbstraction { + mapper: mapper, + mem: mem, + out: out_stream, + }) } pub fn backend(&self) -> &Backend { @@ -423,7 +456,23 @@ mod stdio { } - impl FileAbstraction for StdIoFileAbstraction { + impl Drop for StdIoFileAbstraction + where M: Mapper + { + fn drop(&mut self) { + 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) + }; + + // We can do nothing but end this here with a trace. + // As this drop gets called when imag almost exits, there is no point in exit()ing here + // again. + let _ = fill_res.map_err_trace(); + } + } + + impl FileAbstraction for StdIoFileAbstraction { fn remove_file(&self, path: &PathBuf) -> Result<(), SE> { self.mem.remove_file(path)