From be74afd0317547785bb9e5320232d3f71bd067cb Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 24 Apr 2018 22:01:14 +0200 Subject: [PATCH 1/5] Remove "dump" subcommand --- bin/core/imag-store/src/dump.rs | 39 --------------------------------- bin/core/imag-store/src/main.rs | 11 ++++------ bin/core/imag-store/src/ui.rs | 5 ----- 3 files changed, 4 insertions(+), 51 deletions(-) delete mode 100644 bin/core/imag-store/src/dump.rs diff --git a/bin/core/imag-store/src/dump.rs b/bin/core/imag-store/src/dump.rs deleted file mode 100644 index 0de05e24..00000000 --- a/bin/core/imag-store/src/dump.rs +++ /dev/null @@ -1,39 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer 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::process::exit; - -use libimagrt::runtime::Runtime; -use libimagerror::trace::*; - -pub fn dump(rt: &mut Runtime) { - rt.store() - .entries() - .map_err_trace_exit_unwrap(1) - .for_each(|elem| { - debug!("Working on {:?}", elem); - rt.store().get(elem).map_err_trace_exit_unwrap(1); - }); - - if let Err(_) = rt.store_backend_to_stdout().map_err_trace() { - error!("Loading Store IO backend failed"); - exit(1); - } -} - diff --git a/bin/core/imag-store/src/main.rs b/bin/core/imag-store/src/main.rs index 64297a67..6a907965 100644 --- a/bin/core/imag-store/src/main.rs +++ b/bin/core/imag-store/src/main.rs @@ -54,7 +54,6 @@ use libimagerror::trace::MapErrTrace; mod create; mod delete; -mod dump; mod error; mod get; mod retrieve; @@ -67,7 +66,6 @@ use std::ops::Deref; use create::create; use delete::delete; -use dump::dump; use get::get; use retrieve::retrieve; use ui::build_ui; @@ -76,10 +74,10 @@ use verify::verify; fn main() { let version = make_imag_version!(); - let mut rt = generate_runtime_setup("imag-store", - &version, - "Direct interface to the store. Use with great care!", - build_ui); + let rt = generate_runtime_setup("imag-store", + &version, + "Direct interface to the store. Use with great care!", + build_ui); let command = rt.cli().subcommand_name().map(String::from); @@ -92,7 +90,6 @@ fn main() { "retrieve" => retrieve(&rt), "update" => update(&rt), "verify" => verify(&rt), - "dump" => dump(&mut rt), other => { debug!("Unknown command"); let _ = rt.handle_unknown_subcommand("imag-store", other, rt.cli()) diff --git a/bin/core/imag-store/src/ui.rs b/bin/core/imag-store/src/ui.rs index b44665b7..693f5605 100644 --- a/bin/core/imag-store/src/ui.rs +++ b/bin/core/imag-store/src/ui.rs @@ -190,9 +190,4 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .about("Verify the store") .version("0.1") ) - - .subcommand(SubCommand::with_name("dump") - .about("Dump the complete store to stdout. Currently does only support JSON") - .version("0.1") - ) } From ba453323ba5049ab0e3d1814d0900c496ee97173 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 24 Apr 2018 22:02:16 +0200 Subject: [PATCH 2/5] Remove support for changing store backend --- lib/core/libimagrt/src/runtime.rs | 44 ------------------------------- 1 file changed, 44 deletions(-) diff --git a/lib/core/libimagrt/src/runtime.rs b/lib/core/libimagrt/src/runtime.rs index e3f8a01b..994bfa5b 100644 --- a/lib/core/libimagrt/src/runtime.rs +++ b/lib/core/libimagrt/src/runtime.rs @@ -368,50 +368,6 @@ impl<'a> Runtime<'a> { &self.store } - /// Change the store backend to stdout - /// - /// For the documentation on purpose and cavecats, have a look at the documentation of the - /// `Store::reset_backend()` function. - /// - pub fn store_backend_to_stdio(&mut self) -> Result<(), RuntimeError> { - use libimagstore::file_abstraction::stdio::*; - use libimagstore::file_abstraction::stdio::mapper::json::JsonMapper; - use std::rc::Rc; - use std::cell::RefCell; - - let mut input = ::std::io::stdin(); - let output = ::std::io::stdout(); - let output = Rc::new(RefCell::new(output)); - let mapper = JsonMapper::new(); - - StdIoFileAbstraction::new(&mut input, output, mapper) - .chain_err(|| RuntimeErrorKind::Instantiate) - .and_then(|backend| { - self.store - .reset_backend(Box::new(backend)) - .chain_err(|| RuntimeErrorKind::Instantiate) - }) - } - - pub fn store_backend_to_stdout(&mut self) -> Result<(), RuntimeError> { - use libimagstore::file_abstraction::stdio::mapper::json::JsonMapper; - use libimagstore::file_abstraction::stdio::out::StdoutFileAbstraction; - use std::rc::Rc; - use std::cell::RefCell; - - let output = ::std::io::stdout(); - let output = Rc::new(RefCell::new(output)); - let mapper = JsonMapper::new(); - - StdoutFileAbstraction::new(output, mapper) - .chain_err(|| RuntimeErrorKind::Instantiate) - .and_then(|backend| { - self.store - .reset_backend(Box::new(backend)) - .chain_err(|| RuntimeErrorKind::Instantiate) - }) - } - /// Get a editor command object which can be called to open the $EDITOR pub fn editor(&self) -> Result, RuntimeError> { self.cli() From 19e0471f5b7234c6e09371e3264072ed8fdcc5e1 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 24 Apr 2018 22:03:20 +0200 Subject: [PATCH 3/5] Remove tests with JsonMapper in backend --- lib/core/libimagstore/src/store.rs | 189 ----------------------------- 1 file changed, 189 deletions(-) diff --git a/lib/core/libimagstore/src/store.rs b/lib/core/libimagstore/src/store.rs index aa08bd66..dd1b1f76 100644 --- a/lib/core/libimagstore/src/store.rs +++ b/lib/core/libimagstore/src/store.rs @@ -1208,96 +1208,6 @@ mod store_tests { } } - #[test] - fn test_store_create_with_io_backend() { - use std::io::Cursor; - use std::rc::Rc; - use std::cell::RefCell; - use serde_json::Value; - - //let sink = vec![]; - //let output : Cursor<&mut [u8]> = Cursor::new(&mut sink); - //let output = Rc::new(RefCell::new(output)); - let output = Rc::new(RefCell::new(vec![])); - - { - let store = { - use file_abstraction::stdio::StdIoFileAbstraction; - use file_abstraction::stdio::mapper::json::JsonMapper; - - // Lets have an empty store as input - let mut input = Cursor::new(format!(r#" - {{ "version": "{}", - "store": {{}} - }} - "#, env!("CARGO_PKG_VERSION"))); - - let mapper = JsonMapper::new(); - let backend = StdIoFileAbstraction::new(&mut input, output.clone(), mapper).unwrap(); - let backend = Box::new(backend); - - Store::new_with_backend(PathBuf::from("/"), &None, backend).unwrap() - }; - - for n in 1..100 { - let s = format!("test-{}", n); - let entry = store.create(PathBuf::from(s.clone())).unwrap(); - assert!(entry.verify().is_ok()); - let loc = entry.get_location().clone().into_pathbuf().unwrap(); - assert!(loc.starts_with("/")); - assert!(loc.ends_with(s)); - } - } - - let vec = Rc::try_unwrap(output).unwrap().into_inner(); - - let errstr = format!("Not UTF8: '{:?}'", vec); - let string = String::from_utf8(vec); - assert!(string.is_ok(), errstr); - let string = string.unwrap(); - - assert!(!string.is_empty(), format!("Expected not to be empty: '{}'", string)); - - let json : ::serde_json::Value = ::serde_json::from_str(&string).unwrap(); - - match json { - Value::Object(ref map) => { - assert!(map.get("version").is_some(), format!("No 'version' in JSON")); - match map.get("version").unwrap() { - &Value::String(ref s) => assert_eq!(env!("CARGO_PKG_VERSION"), s), - _ => panic!("Wrong type in JSON at 'version'"), - } - - assert!(map.get("store").is_some(), format!("No 'store' in JSON")); - match map.get("store").unwrap() { - &Value::Object(ref objs) => { - for n in 1..100 { - let s = format!("/test-{}", n); - assert!(objs.get(&s).is_some(), format!("No entry: '{}'", s)); - match objs.get(&s).unwrap() { - &Value::Object(ref entry) => { - match entry.get("header").unwrap() { - &Value::Object(_) => assert!(true), - _ => panic!("Wrong type in JSON at 'store.'{}'.header'", s), - } - - match entry.get("content").unwrap() { - &Value::String(_) => assert!(true), - _ => panic!("Wrong type in JSON at 'store.'{}'.content'", s), - } - }, - _ => panic!("Wrong type in JSON at 'store.'{}''", s), - } - } - }, - _ => panic!("Wrong type in JSON at 'store'"), - } - }, - _ => panic!("Wrong type in JSON at top level"), - } - - } - #[test] fn test_store_get_create_get_delete_get() { let store = get_store(); @@ -1497,104 +1407,5 @@ mod store_tests { } } - #[test] - fn test_swap_backend_during_runtime_with_io() { - use std::io::Cursor; - use std::rc::Rc; - use std::cell::RefCell; - use serde_json::Value; - use file_abstraction::stdio::out::StdoutFileAbstraction; - use file_abstraction::stdio::mapper::json::JsonMapper; - - // The output we later read from and check whether there is an entry - let output = Rc::new(RefCell::new(vec![])); - - { - let mut store = { - use file_abstraction::stdio::StdIoFileAbstraction; - use file_abstraction::stdio::mapper::json::JsonMapper; - - // Lets have an empty store as input - let mut input = Cursor::new(format!(r#" - {{ "version": "{version}", - "store": {{ - "example": {{ - "header": {{ - "imag": {{ - "version": "{version}" - }} - }}, - "content": "foobar" - }} - }} - }} - "#, version = env!("CARGO_PKG_VERSION"))); - - let output = Rc::new(RefCell::new(::std::io::sink())); - let mapper = JsonMapper::new(); - let backend = StdIoFileAbstraction::new(&mut input, output, mapper).unwrap(); - let backend = Box::new(backend); - - Store::new_with_backend(PathBuf::from("/"), &None, backend).unwrap() - }; - - // Replacing the backend - - { - let mapper = JsonMapper::new(); - let backend = StdoutFileAbstraction::new(output.clone(), mapper); - let _ = assert!(backend.is_ok(), format!("Should be ok: {:?}", backend)); - let backend = backend.unwrap(); - let backend = Box::new(backend); - - assert!(store.reset_backend(backend).is_ok()); - } - } - - let vec = Rc::try_unwrap(output).unwrap().into_inner(); - let errstr = format!("Not UTF8: '{:?}'", vec); - let string = String::from_utf8(vec); - assert!(string.is_ok(), errstr); - let string = string.unwrap(); - - assert!(!string.is_empty(), format!("Expected not to be empty: '{}'", string)); - - let json : ::serde_json::Value = ::serde_json::from_str(&string).unwrap(); - - match json { - Value::Object(ref map) => { - assert!(map.get("version").is_some(), format!("No 'version' in JSON")); - match map.get("version").unwrap() { - &Value::String(ref s) => assert_eq!(env!("CARGO_PKG_VERSION"), s), - _ => panic!("Wrong type in JSON at 'version'"), - } - - assert!(map.get("store").is_some(), format!("No 'store' in JSON")); - match map.get("store").unwrap() { - &Value::Object(ref objs) => { - let s = String::from("example"); - assert!(objs.get(&s).is_some(), format!("No entry: '{}' in \n{:?}", s, objs)); - match objs.get(&s).unwrap() { - &Value::Object(ref entry) => { - match entry.get("header").unwrap() { - &Value::Object(_) => assert!(true), - _ => panic!("Wrong type in JSON at 'store.'{}'.header'", s), - } - - match entry.get("content").unwrap() { - &Value::String(_) => assert!(true), - _ => panic!("Wrong type in JSON at 'store.'{}'.content'", s), - } - }, - _ => panic!("Wrong type in JSON at 'store.'{}''", s), - } - }, - _ => panic!("Wrong type in JSON at 'store'"), - } - }, - _ => panic!("Wrong type in JSON at top level"), - } - - } } From 563c76c375eb704a16e50082d134f8b1bb243a7a Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 24 Apr 2018 22:08:31 +0200 Subject: [PATCH 4/5] Remove "stdio" file abstraction from store implementation --- doc/src/02000-store.md | 77 ------ .../libimagstore/src/file_abstraction/mod.rs | 1 - .../src/file_abstraction/stdio/mapper/json.rs | 250 ------------------ .../src/file_abstraction/stdio/mapper/mod.rs | 32 --- .../src/file_abstraction/stdio/mod.rs | 137 ---------- .../src/file_abstraction/stdio/out.rs | 169 ------------ 6 files changed, 666 deletions(-) delete mode 100644 lib/core/libimagstore/src/file_abstraction/stdio/mapper/json.rs delete mode 100644 lib/core/libimagstore/src/file_abstraction/stdio/mapper/mod.rs delete mode 100644 lib/core/libimagstore/src/file_abstraction/stdio/mod.rs delete mode 100644 lib/core/libimagstore/src/file_abstraction/stdio/out.rs diff --git a/doc/src/02000-store.md b/doc/src/02000-store.md index acb2c6d8..7a0b6ac4 100644 --- a/doc/src/02000-store.md +++ b/doc/src/02000-store.md @@ -178,80 +178,3 @@ The `InMemoryFileAbstractionInstance` implementation is corrosponding to the `InMemoryFileAbstraction` implementation - for the in-memory "filesystem". -## The StdIo backend {#sec:thestore:backends:stdio} - -Sidenote: The name is "StdIo" because its main purpose is Stdin/Stdio, but it -is abstracted over Read/Write actually, so it is also possible to use this -backend in other ways, too. - -### Why? {#sec:thestore:backends:stdio:why} - -This is a backend for the imag store which is created -from stdin, by piping contents into the store (via JSON or TOML) and piping the -store contents (as JSON or TOML) to stdout when the backend is destructed. - -This is one of some components which make command-chaining in imag possible. -With this, the application does not have to know whether the store actually -lives on the filesystem or just "in memory". - -### Mappers {#sec:thestore:backends:stdio:mappers} - -The backend contains a "Mapper" which defines how the contents get mapped into -the in-memory store representation: A JSON implementation or a TOML -implementation are possible. - -The following section assumes a JSON mapper. - -The mapper reads the JSON, parses it and translates it to a `Entry`. -Then, the entry is made available to the store codebase. -To summarize what we do right now, lets have a look at the awesome ascii-art -below: - -``` - libimag* - | - v - IO Mapper Store Mapper IO -+--+---------+----------------+--------+--+ -| | | | | | - JSON -> Entry -> JSON -``` - -This is what gets translated where for one imag call with a stdio store backend. - -### The JSON Mapper {#sec:thestore:backends:stdio:json} - -The JSON mapper maps JSON which is read from a source into a HashMap which -represents the in-memory filesystem. - -The strucure is as follows: - -```json -{ - "version": "0.8.0", - "store": { - "example": { - "header": { - "imag": { - "version": "0.8.0", - }, - }, - "content": "hi there!", - }, - }, -} -``` - -### TODO {#sec:thestore:backends:todo} - -If you look at the version history of this file you will see that this -implementation has grown from something complex and probably slow to what we -have today. - -Still, there's one improvement we could make: abstract all the things away so -the `libimag*` crates handle the header without knowing whether it is JSON or -TOML. -With this, we would not even have to translate JSON to TOML anymore. -We should measure whether this would have actually any performance impact before -implementing it. - diff --git a/lib/core/libimagstore/src/file_abstraction/mod.rs b/lib/core/libimagstore/src/file_abstraction/mod.rs index 6c3807ea..b6ca5e00 100644 --- a/lib/core/libimagstore/src/file_abstraction/mod.rs +++ b/lib/core/libimagstore/src/file_abstraction/mod.rs @@ -28,7 +28,6 @@ use storeid::StoreId; mod fs; mod inmemory; mod iter; -pub mod stdio; pub use self::fs::FSFileAbstraction; pub use self::fs::FSFileAbstractionInstance; diff --git a/lib/core/libimagstore/src/file_abstraction/stdio/mapper/json.rs b/lib/core/libimagstore/src/file_abstraction/stdio/mapper/json.rs deleted file mode 100644 index 8b6052f0..00000000 --- a/lib/core/libimagstore/src/file_abstraction/stdio/mapper/json.rs +++ /dev/null @@ -1,250 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer 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::collections::HashMap; -use std::io::{Read, Write}; -use std::path::PathBuf; - -use serde_json; -use toml; - -use error::StoreErrorKind as SEK; -use error::StoreError as SE; -use error::ResultExt; -use super::Mapper; -use store::Result; -use store::Entry; -use storeid::StoreId; - -#[derive(Debug, Deserialize, Serialize)] -struct BackendEntry { - header: serde_json::Value, - content: String, -} - -impl BackendEntry { - - fn to_string(self) -> Result { - toml::to_string(&self.header) - .chain_err(|| SEK::IoError) - .map(|hdr| { - format!("---\n{header}---\n{content}", - header = hdr, - content = self.content) - }) - } - -} - -#[derive(Debug, Deserialize, Serialize)] -struct Document { - version: String, - store: HashMap, -} - -pub struct JsonMapper; - -impl JsonMapper { - - pub fn new() -> JsonMapper { - JsonMapper - } - -} - -impl Mapper for JsonMapper { - fn read_to_fs(&self, r: &mut R, hm: &mut HashMap) -> Result<()> { - let mut document = { - debug!("Reading Document"); - let mut s = String::new(); - r.read_to_string(&mut s).chain_err(|| SEK::IoError)?; - debug!("Document = {:?}", s); - debug!("Parsing Document"); - let doc : Document = serde_json::from_str(&s).chain_err(|| SEK::IoError)?; - debug!("Document = {:?}", doc); - doc - }; - - let _ = ::semver::Version::parse(&document.version) - .chain_err(|| SEK::VersionError) - .and_then(|doc_vers| { - // safe because cargo does not compile if crate version is not valid - let crate_version = ::semver::Version::parse(env!("CARGO_PKG_VERSION")).unwrap(); - - debug!("Document version vs. own version: {doc_vers} > {crate_vers}", - doc_vers = doc_vers, - crate_vers = crate_version); - - if doc_vers > crate_version { - Err(SE::from_kind(SEK::VersionError)) - } else { - Ok(()) - } - })?; - - for (key, val) in document.store.drain() { - debug!("(key, value) ({:?}, {:?})", key, val); - let res = val - .to_string() - .and_then(|vals| { - debug!("value string = {:?}", vals); - StoreId::new_baseless(key.clone()) - .and_then(|id| Entry::from_str(id, &vals)) - .map(|entry| hm.insert(key, entry)) - }) - .map(|_| ()); - - let _ = res?; - } - - Ok(()) - } - - fn fs_to_write(&self, hm: &mut HashMap, out: &mut W) -> Result<()> { - #[derive(Serialize)] - struct BackendEntry { - header: ::toml::Value, - content: String, - } - - impl BackendEntry { - fn construct_from(e: Entry) -> BackendEntry { - BackendEntry { - header: e.get_header().clone(), - content: e.get_content().clone(), - } - } - } - - #[derive(Serialize)] - struct OutDocument { - version: String, - store: HashMap, - } - - let mut store = HashMap::new(); - for (key, value) in hm.drain() { - store.insert(key, BackendEntry::construct_from(value)); - } - - let doc = OutDocument { - version: String::from(env!("CARGO_PKG_VERSION")), - store: store, - }; - - serde_json::to_string(&doc) - .chain_err(|| SEK::IoError) - .and_then(|json| out.write(&json.into_bytes()).chain_err(|| SEK::IoError)) - .and_then(|_| out.flush().chain_err(|| SEK::IoError)) - .map(|_| ()) - } -} - -#[cfg(test)] -mod test { - use std::io::Cursor; - - use super::*; - - #[test] - fn test_empty_json_to_fs() { - let json = format!(r#"{{"version":"{version}","store":{{}}}}"#, - version = env!("CARGO_PKG_VERSION")); - 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(&mut json, &mut hm); - assert!(io_res.is_ok()); - assert!(hm.is_empty()); - } - - #[test] - fn test_json_to_fs() { - let json = format!(r#" - {{ "version": "{version}", - "store": {{ - "example": {{ - "header": {{ - "imag": {{ - "version": "{version}" - }} - }}, - "content": "test" - }} - }} - }} - "#, version = env!("CARGO_PKG_VERSION")); - 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(&mut json, &mut hm); - assert!(io_res.is_ok()); - - assert_eq!(1, hm.len()); // we should have exactly one entry - } - - #[test] - fn test_fs_to_json() { - let mapper = JsonMapper::new(); - let mut out : Cursor> = Cursor::new(vec![]); - - let mut hm = { - let mut hm = HashMap::new(); - let content = format!(r#"--- -[imag] -version = "{}" ---- -hi there!"#, env!("CARGO_PKG_VERSION")); - - let id = PathBuf::from("example"); - let entry = Entry::from_str(id.clone(), &content).unwrap(); - hm.insert(id, entry); - hm - }; - - let io_res = mapper.fs_to_write(&mut hm, &mut out); - assert!(io_res.is_ok()); - - let example = format!(r#" - {{ - "version": "{version}", - "store": {{ - "example": {{ - "header": {{ - "imag": {{ - "version": "{version}" - }} - }}, - "content": "hi there!" - }} - }} - }} - "#, version = env!("CARGO_PKG_VERSION")); - - let example_json : ::serde_json::Value = ::serde_json::from_str(&example).unwrap(); - - let output_json = String::from_utf8(out.into_inner()).unwrap(); - let output_json : ::serde_json::Value = ::serde_json::from_str(&output_json).unwrap(); - - assert_eq!(example_json, output_json); - } -} - diff --git a/lib/core/libimagstore/src/file_abstraction/stdio/mapper/mod.rs b/lib/core/libimagstore/src/file_abstraction/stdio/mapper/mod.rs deleted file mode 100644 index 0543feb1..00000000 --- a/lib/core/libimagstore/src/file_abstraction/stdio/mapper/mod.rs +++ /dev/null @@ -1,32 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer 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::collections::HashMap; -use std::io::{Read, Write}; -use std::path::PathBuf; -use store::Result; -use store::Entry; - -pub trait Mapper { - fn read_to_fs(&self, &mut R, &mut HashMap) -> Result<()>; - fn fs_to_write(&self, &mut HashMap, &mut W) -> Result<()>; -} - -pub mod json; - diff --git a/lib/core/libimagstore/src/file_abstraction/stdio/mod.rs b/lib/core/libimagstore/src/file_abstraction/stdio/mod.rs deleted file mode 100644 index a9ea379c..00000000 --- a/lib/core/libimagstore/src/file_abstraction/stdio/mod.rs +++ /dev/null @@ -1,137 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer 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 error::StoreErrorKind as SEK; -use error::StoreError as SE; -use super::FileAbstraction; -use super::FileAbstractionInstance; -use super::Drain; -use super::InMemoryFileAbstraction; -use store::Entry; -use file_abstraction::iter::PathIterator; - -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>>>; - -pub struct StdIoFileAbstraction(StdoutFileAbstraction); - -impl StdIoFileAbstraction - where M: Mapper, - W: Write -{ - - pub fn new(in_stream: &mut R, out_stream: Rc>, mapper: M) -> Result, SE> { - StdoutFileAbstraction::new(out_stream, mapper) - .and_then(|out| { - let _ = out.backend() - .lock() - .map_err(|_| SE::from_kind(SEK::LockError)) - .map(|mut mtx| out.mapper().read_to_fs(in_stream, mtx.get_mut()))?; - - Ok(StdIoFileAbstraction(out)) - }) - } - - pub fn backend(&self) -> &Backend { - self.0.backend() - } - -} - -impl Debug for StdIoFileAbstraction - where M: Mapper, - W: Write -{ - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { - write!(f, "StdIoFileAbstraction({:?}", self.0) - } -} - -impl Deref for StdIoFileAbstraction - where M: Mapper, - W: Write -{ - type Target = StdoutFileAbstraction; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -// basically #[derive(FileAbstraction)] -impl FileAbstraction for StdIoFileAbstraction { - - 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 { - self.0.new_instance(p) - } - - fn exists(&self, p: &PathBuf) -> Result { - self.0.exists(p) - } - - fn is_file(&self, p: &PathBuf) -> Result { - self.0.is_file(p) - } - - fn drain(&self) -> Result { - self.0.drain() - } - - fn fill(&mut self, d: Drain) -> Result<(), SE> { - self.0.fill(d) - } - - fn pathes_recursively(&self, basepath: PathBuf) -> Result { - self.0.pathes_recursively(basepath) - } -} - diff --git a/lib/core/libimagstore/src/file_abstraction/stdio/out.rs b/lib/core/libimagstore/src/file_abstraction/stdio/out.rs deleted file mode 100644 index e534fa9c..00000000 --- a/lib/core/libimagstore/src/file_abstraction/stdio/out.rs +++ /dev/null @@ -1,169 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer 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 -// - -//! A StdIoFileAbstraction which does not read from stdin. - -use std::rc::Rc; -use std::cell::RefCell; -use std::collections::HashMap; -use std::fmt::Debug; -use std::fmt::Error as FmtError; -use std::fmt::Formatter; -use std::io::Write; -use std::path::PathBuf; -use std::sync::Arc; -use std::sync::Mutex; -use std::ops::Deref; - -use libimagerror::trace::*; - -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; -use file_abstraction::iter::PathIterator; - -use super::mapper::Mapper; - -// Because this is not exported in super::inmemory; -type Backend = Arc>>>; - -pub struct StdoutFileAbstraction { - mapper: M, - mem: InMemoryFileAbstraction, - out: Rc>, -} - -impl StdoutFileAbstraction - where M: Mapper, - W: Write -{ - - pub fn new(out_stream: Rc>, mapper: M) -> Result, SE> { - Ok(StdoutFileAbstraction { - mapper: mapper, - mem: InMemoryFileAbstraction::new(), - out: out_stream, - }) - } - - pub fn backend(&self) -> &Backend { - self.mem.backend() - } - - fn backend_cloned(&self) -> Result, SE> { - self.mem - .backend() - .lock() - .map_err(|_| SE::from_kind(SEK::LockError)) - .map(|mtx| mtx.deref().borrow().clone()) - } - - pub fn mapper(&self) -> &M { - &self.mapper - } - -} - -impl Debug for StdoutFileAbstraction - where M: Mapper, - W: Write -{ - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { - write!(f, "StdoutFileAbstraction({:?}", self.mem) - } -} - -impl Drop for StdoutFileAbstraction - where M: Mapper, - W: Write -{ - fn drop(&mut self) { - use std::ops::DerefMut; - - let fill_res = match self.mem.backend().lock() { - Err(_) => Err(SE::from_kind(SEK::LockError)), - 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. - // 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 StdoutFileAbstraction { - - fn remove_file(&self, path: &PathBuf) -> Result<(), SE> { - self.mem.remove_file(path) - } - - fn copy(&self, from: &PathBuf, to: &PathBuf) -> Result<(), SE> { - self.mem.copy(from, to) - } - - fn rename(&self, from: &PathBuf, to: &PathBuf) -> Result<(), SE> { - self.mem.rename(from, to) - } - - fn create_dir_all(&self, pb: &PathBuf) -> Result<(), SE> { - self.mem.create_dir_all(pb) - } - - fn new_instance(&self, p: PathBuf) -> Box { - self.mem.new_instance(p) - } - - fn exists(&self, p: &PathBuf) -> Result { - self.mem.exists(p) - } - - fn is_file(&self, p: &PathBuf) -> Result { - self.mem.is_file(p) - } - - fn drain(&self) -> Result { - self.backend_cloned().map(Drain::new) - } - - fn fill(&mut self, mut d: Drain) -> Result<(), SE> { - debug!("Draining into : {:?}", self); - let mut mtx = self.backend().lock().map_err(|_| SE::from_kind(SEK::IoError))?; - let backend = mtx.get_mut(); - - for (path, element) in d.iter() { - debug!("Drain into {:?}: {:?}", self, path); - backend.insert(path, element); - } - Ok(()) - } - - fn pathes_recursively(&self, basepath: PathBuf) -> Result { - self.mem.pathes_recursively(basepath) - } - -} - - From 524c391ee0313e3ff32d258b9f2845d6f127e781 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 24 Apr 2018 22:11:28 +0200 Subject: [PATCH 5/5] Remove unused dependency --- lib/core/libimagstore/Cargo.toml | 1 - lib/core/libimagstore/src/lib.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/core/libimagstore/Cargo.toml b/lib/core/libimagstore/Cargo.toml index e0d64727..296bcb6d 100644 --- a/lib/core/libimagstore/Cargo.toml +++ b/lib/core/libimagstore/Cargo.toml @@ -29,7 +29,6 @@ walkdir = "1" is-match = "0.1" serde = "1" serde_json = "1" -serde_derive = "1" error-chain = "0.11" toml-query = "0.6" diff --git a/lib/core/libimagstore/src/lib.rs b/lib/core/libimagstore/src/lib.rs index 833dd4d0..0d6f0ccb 100644 --- a/lib/core/libimagstore/src/lib.rs +++ b/lib/core/libimagstore/src/lib.rs @@ -44,7 +44,6 @@ extern crate semver; extern crate walkdir; #[macro_use] extern crate is_match; extern crate serde_json; -#[macro_use] extern crate serde_derive; #[macro_use] extern crate error_chain; extern crate toml_query;