summaryrefslogtreecommitdiff
path: root/lib/core/libimagstore/src/file_abstraction/stdio/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/core/libimagstore/src/file_abstraction/stdio/mod.rs')
-rw-r--r--lib/core/libimagstore/src/file_abstraction/stdio/mod.rs127
1 files changed, 127 insertions, 0 deletions
diff --git a/lib/core/libimagstore/src/file_abstraction/stdio/mod.rs b/lib/core/libimagstore/src/file_abstraction/stdio/mod.rs
new file mode 100644
index 0000000..e2ac5ec
--- /dev/null
+++ b/lib/core/libimagstore/src/file_abstraction/stdio/mod.rs
@@ -0,0 +1,127 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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::io::{Read, Write};
+use std::path::PathBuf;
+use std::sync::Arc;
+use std::sync::Mutex;
+use std::ops::Deref;
+use std::fmt::Debug;
+use std::fmt::Error as FmtError;
+use std::fmt::Formatter;
+
+use libimagerror::into::IntoError;
+
+use error::StoreErrorKind as SEK;
+use error::StoreError as SE;
+use super::FileAbstraction;
+use super::FileAbstractionInstance;
+use super::Drain;
+use super::InMemoryFileAbstraction;
+use store::Entry;
+
+pub mod mapper;
+pub mod out;
+use self::mapper::Mapper;
+use self::out::StdoutFileAbstraction;
+
+// Because this is not exported in super::inmemory;
+type Backend = Arc<Mutex<RefCell<HashMap<PathBuf, Entry>>>>;
+
+pub struct StdIoFileAbstraction<W: Write, M: Mapper>(StdoutFileAbstraction<W, M>);
+
+impl<W, M> StdIoFileAbstraction<W, M>
+ where M: Mapper,
+ W: Write
+{
+
+ pub fn new<R: Read>(in_stream: &mut R, out_stream: Rc<RefCell<W>>, mapper: M) -> Result<StdIoFileAbstraction<W, M>, SE> {
+ StdoutFileAbstraction::new(out_stream, mapper)
+ .and_then(|out| {
+ let fill_res = match out.backend().lock() {
+ Err(_) => Err(SEK::LockError.into_error()),
+ Ok(mut mtx) => out.mapper().read_to_fs(in_stream, mtx.get_mut())
+ };
+ let _ = try!(fill_res);
+
+ Ok(StdIoFileAbstraction(out))
+ })
+ }
+
+ pub fn backend(&self) -> &Backend {
+ self.0.backend()
+ }
+
+}
+
+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.0)
+ }
+}
+
+impl<W, M> Deref for StdIoFileAbstraction<W, M>
+ where M: Mapper,
+ W: Write
+{
+ type Target = StdoutFileAbstraction<W, M>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+// basically #[derive(FileAbstraction)]
+impl<W: Write, M: Mapper> FileAbstraction for StdIoFileAbstraction<W, M> {
+
+ fn remove_file(&self, path: &PathBuf) -> Result<(), SE> {
+ self.0.remove_file(path)
+ }
+
+ fn copy(&self, from: &PathBuf, to: &PathBuf) -> Result<(), SE> {
+ self.0.copy(from, to)
+ }
+
+ fn rename(&self, from: &PathBuf, to: &PathBuf) -> Result<(), SE> {
+ self.0.rename(from, to)
+ }
+
+ fn create_dir_all(&self, pb: &PathBuf) -> Result<(), SE> {
+ self.0.create_dir_all(pb)
+ }
+
+ fn new_instance(&self, p: PathBuf) -> Box<FileAbstractionInstance> {
+ self.0.new_instance(p)
+ }
+
+ fn drain(&self) -> Result<Drain, SE> {
+ self.0.drain()
+ }
+
+ fn fill(&mut self, d: Drain) -> Result<(), SE> {
+ self.0.fill(d)
+ }
+}
+