commit
2d94be5831
83 changed files with 523 additions and 291 deletions
|
@ -21,7 +21,7 @@ Our (long-term) goal is to
|
||||||
> management, consists of reusable parts and integrates well with known
|
> management, consists of reusable parts and integrates well with known
|
||||||
> commandline tools.
|
> commandline tools.
|
||||||
|
|
||||||
Yes, imag is a rather ambitous project as it tries to reimplement functionality
|
Yes, imag is a rather ambitious project as it tries to reimplement functionality
|
||||||
for several "personal information management aspects". It is a hobby project,
|
for several "personal information management aspects". It is a hobby project,
|
||||||
keep that in mind. We try to use standards like vcard and icalendar wherever
|
keep that in mind. We try to use standards like vcard and icalendar wherever
|
||||||
possible.
|
possible.
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
version = "2.0"
|
version = "2.0"
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub fn retrieve(rt: &Runtime) {
|
||||||
let id = scmd.value_of("id").unwrap();
|
let id = scmd.value_of("id").unwrap();
|
||||||
let path = PathBuf::from(id);
|
let path = PathBuf::from(id);
|
||||||
let store = Some(rt.store().path().clone());
|
let store = Some(rt.store().path().clone());
|
||||||
let path = try!(StoreId::new(store, path).map_err_trace_exit(1));
|
let path = StoreId::new(store, path).map_err_trace_exit(1)?;
|
||||||
debug!("path = {:?}", path);
|
debug!("path = {:?}", path);
|
||||||
|
|
||||||
rt.store()
|
rt.store()
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
version = "2.0"
|
version = "2.0"
|
||||||
walkdir = "1"
|
walkdir = "1"
|
||||||
|
|
|
@ -254,12 +254,12 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_aliases(rt: &Runtime) -> Result<BTreeMap<String, String>, String> {
|
fn fetch_aliases(rt: &Runtime) -> Result<BTreeMap<String, String>, String> {
|
||||||
let cfg = try!(rt.config().ok_or_else(|| String::from("No configuration found")));
|
let cfg = rt.config().ok_or_else(|| String::from("No configuration found"))?;
|
||||||
let value = cfg
|
let value = cfg
|
||||||
.read("imag.aliases")
|
.read("imag.aliases")
|
||||||
.map_err(|_| String::from("Reading from config failed"));
|
.map_err(|_| String::from("Reading from config failed"));
|
||||||
|
|
||||||
match try!(value) {
|
match value? {
|
||||||
None => Ok(BTreeMap::new()),
|
None => Ok(BTreeMap::new()),
|
||||||
Some(&Value::Table(ref tbl)) => {
|
Some(&Value::Table(ref tbl)) => {
|
||||||
let mut alias_mappings = BTreeMap::new();
|
let mut alias_mappings = BTreeMap::new();
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -88,7 +88,7 @@ fn add(rt: &Runtime) {
|
||||||
BookmarkCollection::get(rt.store(), &coll)
|
BookmarkCollection::get(rt.store(), &coll)
|
||||||
.and_then(|mut collection| {
|
.and_then(|mut collection| {
|
||||||
for url in scmd.values_of("urls").unwrap() { // unwrap saved by clap
|
for url in scmd.values_of("urls").unwrap() { // unwrap saved by clap
|
||||||
let _ = try!(collection.add_link(BookmarkLink::from(url)));
|
let _ = collection.add_link(BookmarkLink::from(url))?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
version = "2.0"
|
version = "2.0"
|
||||||
|
|
|
@ -9,6 +9,12 @@ keywords = ["imag", "PIM", "personal", "information", "management"]
|
||||||
readme = "../../../README.md"
|
readme = "../../../README.md"
|
||||||
license = "LGPL-2.1"
|
license = "LGPL-2.1"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -88,13 +88,13 @@ pub fn day(rt: &Runtime) -> i32 {
|
||||||
acc.and_then(|_| {
|
acc.and_then(|_| {
|
||||||
debug!("Processing {:?}", e.get_location());
|
debug!("Processing {:?}", e.get_location());
|
||||||
|
|
||||||
let tag = try!(e.get_timetrack_tag());
|
let tag = e.get_timetrack_tag()?;
|
||||||
debug!(" -> tag = {:?}", tag);
|
debug!(" -> tag = {:?}", tag);
|
||||||
|
|
||||||
let start = try!(e.get_start_datetime());
|
let start = e.get_start_datetime()?;
|
||||||
debug!(" -> start = {:?}", start);
|
debug!(" -> start = {:?}", start);
|
||||||
|
|
||||||
let end = try!(e.get_end_datetime());
|
let end = e.get_end_datetime()?;
|
||||||
debug!(" -> end = {:?}", end);
|
debug!(" -> end = {:?}", end);
|
||||||
|
|
||||||
match (start, end) {
|
match (start, end) {
|
||||||
|
|
|
@ -91,13 +91,13 @@ pub fn list(rt: &Runtime) -> i32 {
|
||||||
acc.and_then(|_| {
|
acc.and_then(|_| {
|
||||||
debug!("Processing {:?}", e.get_location());
|
debug!("Processing {:?}", e.get_location());
|
||||||
|
|
||||||
let tag = try!(e.get_timetrack_tag());
|
let tag = e.get_timetrack_tag()?;
|
||||||
debug!(" -> tag = {:?}", tag);
|
debug!(" -> tag = {:?}", tag);
|
||||||
|
|
||||||
let start = try!(e.get_start_datetime());
|
let start = e.get_start_datetime()?;
|
||||||
debug!(" -> start = {:?}", start);
|
debug!(" -> start = {:?}", start);
|
||||||
|
|
||||||
let end = try!(e.get_end_datetime());
|
let end = e.get_end_datetime()?;
|
||||||
debug!(" -> end = {:?}", end);
|
debug!(" -> end = {:?}", end);
|
||||||
|
|
||||||
match (start, end) {
|
match (start, end) {
|
||||||
|
|
|
@ -103,13 +103,13 @@ pub fn month(rt: &Runtime) -> i32 {
|
||||||
acc.and_then(|_| {
|
acc.and_then(|_| {
|
||||||
debug!("Processing {:?}", e.get_location());
|
debug!("Processing {:?}", e.get_location());
|
||||||
|
|
||||||
let tag = try!(e.get_timetrack_tag());
|
let tag = e.get_timetrack_tag()?;
|
||||||
debug!(" -> tag = {:?}", tag);
|
debug!(" -> tag = {:?}", tag);
|
||||||
|
|
||||||
let start = try!(e.get_start_datetime());
|
let start = e.get_start_datetime()?;
|
||||||
debug!(" -> start = {:?}", start);
|
debug!(" -> start = {:?}", start);
|
||||||
|
|
||||||
let end = try!(e.get_end_datetime());
|
let end = e.get_end_datetime()?;
|
||||||
debug!(" -> end = {:?}", end);
|
debug!(" -> end = {:?}", end);
|
||||||
|
|
||||||
match (start, end) {
|
match (start, end) {
|
||||||
|
|
|
@ -95,13 +95,13 @@ pub fn week(rt: &Runtime) -> i32 {
|
||||||
acc.and_then(|_| {
|
acc.and_then(|_| {
|
||||||
debug!("Processing {:?}", e.get_location());
|
debug!("Processing {:?}", e.get_location());
|
||||||
|
|
||||||
let tag = try!(e.get_timetrack_tag());
|
let tag = e.get_timetrack_tag()?;
|
||||||
debug!(" -> tag = {:?}", tag);
|
debug!(" -> tag = {:?}", tag);
|
||||||
|
|
||||||
let start = try!(e.get_start_datetime());
|
let start = e.get_start_datetime()?;
|
||||||
debug!(" -> start = {:?}", start);
|
debug!(" -> start = {:?}", start);
|
||||||
|
|
||||||
let end = try!(e.get_end_datetime());
|
let end = e.get_end_datetime()?;
|
||||||
debug!(" -> end = {:?}", end);
|
debug!(" -> end = {:?}", end);
|
||||||
|
|
||||||
match (start, end) {
|
match (start, end) {
|
||||||
|
|
|
@ -94,13 +94,13 @@ pub fn year(rt: &Runtime) -> i32 {
|
||||||
acc.and_then(|_| {
|
acc.and_then(|_| {
|
||||||
debug!("Processing {:?}", e.get_location());
|
debug!("Processing {:?}", e.get_location());
|
||||||
|
|
||||||
let tag = try!(e.get_timetrack_tag());
|
let tag = e.get_timetrack_tag()?;
|
||||||
debug!(" -> tag = {:?}", tag);
|
debug!(" -> tag = {:?}", tag);
|
||||||
|
|
||||||
let start = try!(e.get_start_datetime());
|
let start = e.get_start_datetime()?;
|
||||||
debug!(" -> start = {:?}", start);
|
debug!(" -> start = {:?}", start);
|
||||||
|
|
||||||
let end = try!(e.get_end_datetime());
|
let end = e.get_end_datetime()?;
|
||||||
debug!(" -> end = {:?}", end);
|
debug!(" -> end = {:?}", end);
|
||||||
|
|
||||||
match (start, end) {
|
match (start, end) {
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
ansi_term = "0.10"
|
ansi_term = "0.10"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
env_logger = "0.4"
|
env_logger = "0.4"
|
||||||
|
|
|
@ -85,30 +85,30 @@ impl ImagLogger {
|
||||||
::libimaginteraction::format::register_all_format_helpers(&mut handlebars);
|
::libimaginteraction::format::register_all_format_helpers(&mut handlebars);
|
||||||
|
|
||||||
{
|
{
|
||||||
let fmt = try!(aggregate_global_format_trace(config));
|
let fmt = aggregate_global_format_trace(config)?;
|
||||||
try!(handlebars.register_template_string("TRACE", fmt)); // name must be uppercase
|
handlebars.register_template_string("TRACE", fmt)?; // name must be uppercase
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let fmt = try!(aggregate_global_format_debug(config));
|
let fmt = aggregate_global_format_debug(config)?;
|
||||||
try!(handlebars.register_template_string("DEBUG", fmt)); // name must be uppercase
|
handlebars.register_template_string("DEBUG", fmt)?; // name must be uppercase
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let fmt = try!(aggregate_global_format_info(config));
|
let fmt = aggregate_global_format_info(config)?;
|
||||||
try!(handlebars.register_template_string("INFO", fmt)); // name must be uppercase
|
handlebars.register_template_string("INFO", fmt)?; // name must be uppercase
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let fmt = try!(aggregate_global_format_warn(config));
|
let fmt = aggregate_global_format_warn(config)?;
|
||||||
try!(handlebars.register_template_string("WARN", fmt)); // name must be uppercase
|
handlebars.register_template_string("WARN", fmt)?; // name must be uppercase
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let fmt = try!(aggregate_global_format_error(config));
|
let fmt = aggregate_global_format_error(config)?;
|
||||||
try!(handlebars.register_template_string("ERROR", fmt)); // name must be uppercase
|
handlebars.register_template_string("ERROR", fmt)?; // name must be uppercase
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ImagLogger {
|
Ok(ImagLogger {
|
||||||
global_loglevel : try!(aggregate_global_loglevel(matches, config)),
|
global_loglevel : aggregate_global_loglevel(matches, config)?,
|
||||||
global_destinations : try!(aggregate_global_destinations(matches, config)),
|
global_destinations : aggregate_global_destinations(matches, config)?,
|
||||||
module_settings : try!(aggregate_module_settings(matches, config)),
|
module_settings : aggregate_module_settings(matches, config)?,
|
||||||
handlebars : handlebars,
|
handlebars : handlebars,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,7 @@ fn translate_destinations(raw: &Vec<Value>) -> Result<Vec<LogDestination>> {
|
||||||
.fold(Ok(vec![]), |acc, val| {
|
.fold(Ok(vec![]), |acc, val| {
|
||||||
acc.and_then(|mut v| {
|
acc.and_then(|mut v| {
|
||||||
let dest = match *val {
|
let dest = match *val {
|
||||||
Value::String(ref s) => try!(translate_destination(s)),
|
Value::String(ref s) => translate_destination(s)?,
|
||||||
_ => {
|
_ => {
|
||||||
let path = "imag.logging.modules.<mod>.destinations".to_owned();
|
let path = "imag.logging.modules.<mod>.destinations".to_owned();
|
||||||
let ty = "Array<String>";
|
let ty = "Array<String>";
|
||||||
|
@ -321,7 +321,7 @@ fn aggregate_global_destinations(matches: &ArgMatches, config: Option<&Value>)
|
||||||
values.split(",")
|
values.split(",")
|
||||||
.fold(Ok(vec![]), move |acc, dest| {
|
.fold(Ok(vec![]), move |acc, dest| {
|
||||||
acc.and_then(|mut v| {
|
acc.and_then(|mut v| {
|
||||||
v.push(try!(translate_destination(dest)));
|
v.push(translate_destination(dest)?);
|
||||||
Ok(v)
|
Ok(v)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -393,38 +393,35 @@ fn aggregate_module_settings(_matches: &ArgMatches, config: Option<&Value>)
|
||||||
let mut settings = BTreeMap::new();
|
let mut settings = BTreeMap::new();
|
||||||
|
|
||||||
for (module_name, v) in t {
|
for (module_name, v) in t {
|
||||||
let destinations = try!(match v.read("destinations") {
|
let destinations = match v.read("destinations")? {
|
||||||
Ok(Some(&Value::Array(ref a))) => translate_destinations(a).map(Some),
|
Some(&Value::Array(ref a)) => Some(translate_destinations(a)?),
|
||||||
Ok(None) => Ok(None),
|
None => None,
|
||||||
Ok(Some(_)) => {
|
Some(_) => {
|
||||||
let path = "imag.logging.modules.<mod>.destinations".to_owned();
|
let path = "imag.logging.modules.<mod>.destinations".to_owned();
|
||||||
let ty = "Array";
|
let ty = "Array";
|
||||||
Err(RE::from_kind(EK::ConfigTypeError(path, ty)))
|
return Err(RE::from_kind(EK::ConfigTypeError(path, ty)))
|
||||||
},
|
},
|
||||||
Err(e) => Err(e).map_err(From::from),
|
};
|
||||||
});
|
|
||||||
|
|
||||||
let level = try!(match v.read("level") {
|
let level = match v.read("level")? {
|
||||||
Ok(Some(&Value::String(ref s))) => match_log_level_str(s).map(Some),
|
Some(&Value::String(ref s)) => Some(match_log_level_str(s)?),
|
||||||
Ok(None) => Ok(None),
|
None => None,
|
||||||
Ok(Some(_)) => {
|
Some(_) => {
|
||||||
let path = "imag.logging.modules.<mod>.level".to_owned();
|
let path = "imag.logging.modules.<mod>.level".to_owned();
|
||||||
let ty = "String";
|
let ty = "String";
|
||||||
Err(RE::from_kind(EK::ConfigTypeError(path, ty)))
|
return Err(RE::from_kind(EK::ConfigTypeError(path, ty)))
|
||||||
},
|
},
|
||||||
Err(e) => Err(e).map_err(From::from),
|
};
|
||||||
});
|
|
||||||
|
|
||||||
let enabled = try!(match v.read("enabled") {
|
let enabled = match v.read("enabled")? {
|
||||||
Ok(Some(&Value::Boolean(b))) => Ok(b),
|
Some(&Value::Boolean(b)) => b,
|
||||||
Ok(None) => Ok(false),
|
None => false,
|
||||||
Ok(Some(_)) => {
|
Some(_) => {
|
||||||
let path = "imag.logging.modules.<mod>.enabled".to_owned();
|
let path = "imag.logging.modules.<mod>.enabled".to_owned();
|
||||||
let ty = "Boolean";
|
let ty = "Boolean";
|
||||||
Err(RE::from_kind(EK::ConfigTypeError(path, ty)))
|
return Err(RE::from_kind(EK::ConfigTypeError(path, ty)))
|
||||||
},
|
},
|
||||||
Err(e) => Err(e).map_err(From::from),
|
};
|
||||||
});
|
|
||||||
|
|
||||||
let module_settings = ModuleSettings {
|
let module_settings = ModuleSettings {
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
glob = "0.2.11"
|
glob = "0.2.11"
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
|
|
|
@ -48,8 +48,8 @@ impl FileAbstractionInstance for FSFileAbstractionInstance {
|
||||||
FSFileAbstractionInstance::File(ref mut f, _) => return {
|
FSFileAbstractionInstance::File(ref mut f, _) => return {
|
||||||
// We seek to the beginning of the file since we expect each
|
// We seek to the beginning of the file since we expect each
|
||||||
// access to the file to be in a different context
|
// access to the file to be in a different context
|
||||||
try!(f.seek(SeekFrom::Start(0))
|
f.seek(SeekFrom::Start(0))
|
||||||
.chain_err(|| SEK::FileNotSeeked));
|
.chain_err(|| SEK::FileNotSeeked)?;
|
||||||
|
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
f.read_to_string(&mut s)
|
f.read_to_string(&mut s)
|
||||||
|
@ -58,7 +58,7 @@ impl FileAbstractionInstance for FSFileAbstractionInstance {
|
||||||
.and_then(|s| Entry::from_str(id, &s))
|
.and_then(|s| Entry::from_str(id, &s))
|
||||||
},
|
},
|
||||||
FSFileAbstractionInstance::Absent(ref p) =>
|
FSFileAbstractionInstance::Absent(ref p) =>
|
||||||
(try!(open_file(p).chain_err(|| SEK::FileNotFound)), p.clone()),
|
(open_file(p).chain_err(|| SEK::FileNotFound)?, p.clone()),
|
||||||
};
|
};
|
||||||
*self = FSFileAbstractionInstance::File(file, path);
|
*self = FSFileAbstractionInstance::File(file, path);
|
||||||
if let FSFileAbstractionInstance::File(ref mut f, _) = *self {
|
if let FSFileAbstractionInstance::File(ref mut f, _) = *self {
|
||||||
|
@ -84,15 +84,15 @@ impl FileAbstractionInstance for FSFileAbstractionInstance {
|
||||||
FSFileAbstractionInstance::File(ref mut f, _) => return {
|
FSFileAbstractionInstance::File(ref mut f, _) => return {
|
||||||
// We seek to the beginning of the file since we expect each
|
// We seek to the beginning of the file since we expect each
|
||||||
// access to the file to be in a different context
|
// access to the file to be in a different context
|
||||||
try!(f.seek(SeekFrom::Start(0))
|
f.seek(SeekFrom::Start(0))
|
||||||
.chain_err(|| SEK::FileNotCreated));
|
.chain_err(|| SEK::FileNotCreated)?;
|
||||||
|
|
||||||
try!(f.set_len(buf.len() as u64).chain_err(|| SEK::FileNotWritten));
|
f.set_len(buf.len() as u64).chain_err(|| SEK::FileNotWritten)?;
|
||||||
|
|
||||||
f.write_all(&buf).chain_err(|| SEK::FileNotWritten)
|
f.write_all(&buf).chain_err(|| SEK::FileNotWritten)
|
||||||
},
|
},
|
||||||
FSFileAbstractionInstance::Absent(ref p) =>
|
FSFileAbstractionInstance::Absent(ref p) =>
|
||||||
(try!(create_file(p).chain_err(|| SEK::FileNotCreated)), p.clone()),
|
(create_file(p).chain_err(|| SEK::FileNotCreated)?, p.clone()),
|
||||||
};
|
};
|
||||||
*self = FSFileAbstractionInstance::File(file, path);
|
*self = FSFileAbstractionInstance::File(file, path);
|
||||||
if let FSFileAbstractionInstance::File(ref mut f, _) = *self {
|
if let FSFileAbstractionInstance::File(ref mut f, _) = *self {
|
||||||
|
@ -129,7 +129,7 @@ impl FileAbstraction for FSFileAbstraction {
|
||||||
match to.parent() {
|
match to.parent() {
|
||||||
Some(p) => if !p.exists() {
|
Some(p) => if !p.exists() {
|
||||||
debug!("Creating: {:?}", p);
|
debug!("Creating: {:?}", p);
|
||||||
let _ = try!(create_dir_all(&PathBuf::from(p)));
|
let _ = create_dir_all(&PathBuf::from(p))?;
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
debug!("Failed to find parent. This looks like it will fail now");
|
debug!("Failed to find parent. This looks like it will fail now");
|
||||||
|
@ -184,11 +184,11 @@ impl FileAbstraction for FSFileAbstraction {
|
||||||
})
|
})
|
||||||
.fold(Ok(vec![]), |acc, e| {
|
.fold(Ok(vec![]), |acc, e| {
|
||||||
acc.and_then(move |mut a| {
|
acc.and_then(move |mut a| {
|
||||||
a.push(try!(e));
|
a.push(e?);
|
||||||
Ok(a)
|
Ok(a)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
Ok(PathIterator::new(Box::new(try!(i).into_iter())))
|
Ok(PathIterator::new(Box::new(i?.into_iter())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl FileAbstraction for InMemoryFileAbstraction {
|
||||||
let mut mtx = self.backend().lock().expect("Locking Mutex failed");
|
let mut mtx = self.backend().lock().expect("Locking Mutex failed");
|
||||||
let backend = mtx.get_mut();
|
let backend = mtx.get_mut();
|
||||||
|
|
||||||
let a = try!(backend.get(from).cloned().ok_or(SE::from_kind(SEK::FileNotFound)));
|
let a = backend.get(from).cloned().ok_or(SE::from_kind(SEK::FileNotFound))?;
|
||||||
backend.insert(to.clone(), a);
|
backend.insert(to.clone(), a);
|
||||||
debug!("Copying: {:?} -> {:?} worked", from, to);
|
debug!("Copying: {:?} -> {:?} worked", from, to);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -142,7 +142,7 @@ impl FileAbstraction for InMemoryFileAbstraction {
|
||||||
let mut mtx = self.backend().lock().expect("Locking Mutex failed");
|
let mut mtx = self.backend().lock().expect("Locking Mutex failed");
|
||||||
let backend = mtx.get_mut();
|
let backend = mtx.get_mut();
|
||||||
|
|
||||||
let a = try!(backend.get(from).cloned().ok_or(SE::from_kind(SEK::FileNotFound)));
|
let a = backend.get(from).cloned().ok_or(SE::from_kind(SEK::FileNotFound))?;
|
||||||
backend.insert(to.clone(), a);
|
backend.insert(to.clone(), a);
|
||||||
debug!("Renaming: {:?} -> {:?} worked", from, to);
|
debug!("Renaming: {:?} -> {:?} worked", from, to);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -176,7 +176,7 @@ impl FileAbstraction for InMemoryFileAbstraction {
|
||||||
|
|
||||||
fn fill<'a>(&'a mut self, mut d: Drain) -> Result<(), SE> {
|
fn fill<'a>(&'a mut self, mut d: Drain) -> Result<(), SE> {
|
||||||
debug!("Draining into : {:?}", self);
|
debug!("Draining into : {:?}", self);
|
||||||
let mut mtx = try!(self.backend().lock().map_err(|_| SEK::LockError));
|
let mut mtx = self.backend().lock().map_err(|_| SEK::LockError)?;
|
||||||
let backend = mtx.get_mut();
|
let backend = mtx.get_mut();
|
||||||
|
|
||||||
for (path, element) in d.iter() {
|
for (path, element) in d.iter() {
|
||||||
|
|
|
@ -73,15 +73,15 @@ impl Mapper for JsonMapper {
|
||||||
let mut document = {
|
let mut document = {
|
||||||
debug!("Reading Document");
|
debug!("Reading Document");
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
try!(r.read_to_string(&mut s).chain_err(|| SEK::IoError));
|
r.read_to_string(&mut s).chain_err(|| SEK::IoError)?;
|
||||||
debug!("Document = {:?}", s);
|
debug!("Document = {:?}", s);
|
||||||
debug!("Parsing Document");
|
debug!("Parsing Document");
|
||||||
let doc : Document = try!(serde_json::from_str(&s).chain_err(|| SEK::IoError));
|
let doc : Document = serde_json::from_str(&s).chain_err(|| SEK::IoError)?;
|
||||||
debug!("Document = {:?}", doc);
|
debug!("Document = {:?}", doc);
|
||||||
doc
|
doc
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = try!(::semver::Version::parse(&document.version)
|
let _ = ::semver::Version::parse(&document.version)
|
||||||
.chain_err(|| SEK::VersionError)
|
.chain_err(|| SEK::VersionError)
|
||||||
.and_then(|doc_vers| {
|
.and_then(|doc_vers| {
|
||||||
// safe because cargo does not compile if crate version is not valid
|
// safe because cargo does not compile if crate version is not valid
|
||||||
|
@ -96,7 +96,7 @@ impl Mapper for JsonMapper {
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}));
|
})?;
|
||||||
|
|
||||||
for (key, val) in document.store.drain() {
|
for (key, val) in document.store.drain() {
|
||||||
debug!("(key, value) ({:?}, {:?})", key, val);
|
debug!("(key, value) ({:?}, {:?})", key, val);
|
||||||
|
@ -110,7 +110,7 @@ impl Mapper for JsonMapper {
|
||||||
})
|
})
|
||||||
.map(|_| ());
|
.map(|_| ());
|
||||||
|
|
||||||
let _ = try!(res);
|
let _ = res?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -56,11 +56,10 @@ impl<W, M> StdIoFileAbstraction<W, M>
|
||||||
pub fn new<R: Read>(in_stream: &mut R, out_stream: Rc<RefCell<W>>, mapper: M) -> Result<StdIoFileAbstraction<W, M>, SE> {
|
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)
|
StdoutFileAbstraction::new(out_stream, mapper)
|
||||||
.and_then(|out| {
|
.and_then(|out| {
|
||||||
let _ = try!(out
|
let _ = out.backend()
|
||||||
.backend()
|
.lock()
|
||||||
.lock()
|
.map_err(|_| SE::from_kind(SEK::LockError))
|
||||||
.map_err(|_| SE::from_kind(SEK::LockError))
|
.map(|mut mtx| out.mapper().read_to_fs(in_stream, mtx.get_mut()))?;
|
||||||
.map(|mut mtx| out.mapper().read_to_fs(in_stream, mtx.get_mut())));
|
|
||||||
|
|
||||||
Ok(StdIoFileAbstraction(out))
|
Ok(StdIoFileAbstraction(out))
|
||||||
})
|
})
|
||||||
|
|
|
@ -150,7 +150,7 @@ impl<W: Write, M: Mapper> FileAbstraction for StdoutFileAbstraction<W, M> {
|
||||||
|
|
||||||
fn fill(&mut self, mut d: Drain) -> Result<(), SE> {
|
fn fill(&mut self, mut d: Drain) -> Result<(), SE> {
|
||||||
debug!("Draining into : {:?}", self);
|
debug!("Draining into : {:?}", self);
|
||||||
let mut mtx = try!(self.backend().lock().map_err(|_| SE::from_kind(SEK::IoError)));
|
let mut mtx = self.backend().lock().map_err(|_| SE::from_kind(SEK::IoError))?;
|
||||||
let backend = mtx.get_mut();
|
let backend = mtx.get_mut();
|
||||||
|
|
||||||
for (path, element) in d.iter() {
|
for (path, element) in d.iter() {
|
||||||
|
|
|
@ -140,13 +140,13 @@ impl Iterator for Walk {
|
||||||
impl StoreEntry {
|
impl StoreEntry {
|
||||||
|
|
||||||
fn new(id: StoreId, backend: &Box<FileAbstraction>) -> Result<StoreEntry> {
|
fn new(id: StoreId, backend: &Box<FileAbstraction>) -> Result<StoreEntry> {
|
||||||
let pb = try!(id.clone().into_pathbuf());
|
let pb = id.clone().into_pathbuf()?;
|
||||||
|
|
||||||
#[cfg(feature = "fs-lock")]
|
#[cfg(feature = "fs-lock")]
|
||||||
{
|
{
|
||||||
try!(open_file(pb.clone())
|
open_file(pb.clone())
|
||||||
.and_then(|f| f.lock_exclusive())
|
.and_then(|f| f.lock_exclusive())
|
||||||
.chain_err(|| SEK::IoError));
|
.chain_err(|| SEK::IoError)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(StoreEntry {
|
Ok(StoreEntry {
|
||||||
|
@ -258,7 +258,7 @@ impl Store {
|
||||||
use configuration::*;
|
use configuration::*;
|
||||||
|
|
||||||
debug!("Validating Store configuration");
|
debug!("Validating Store configuration");
|
||||||
let _ = try!(config_is_valid(&store_config).chain_err(|| SEK::ConfigurationError));
|
let _ = config_is_valid(&store_config).chain_err(|| SEK::ConfigurationError)?;
|
||||||
|
|
||||||
debug!("Building new Store object");
|
debug!("Building new Store object");
|
||||||
if !location.exists() {
|
if !location.exists() {
|
||||||
|
@ -268,9 +268,10 @@ impl Store {
|
||||||
.chain_err(|| SEK::IoError);
|
.chain_err(|| SEK::IoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(backend.create_dir_all(&location)
|
backend
|
||||||
.chain_err(|| SEK::StorePathCreate(location.clone()))
|
.create_dir_all(&location)
|
||||||
.map_dbg_err_str("Failed"));
|
.chain_err(|| SEK::StorePathCreate(location.clone()))
|
||||||
|
.map_dbg_err_str("Failed")?;
|
||||||
} else if location.is_file() {
|
} else if location.is_file() {
|
||||||
debug!("Store path exists as file");
|
debug!("Store path exists as file");
|
||||||
return Err(SE::from_kind(SEK::StorePathExists(location)));
|
return Err(SE::from_kind(SEK::StorePathExists(location)));
|
||||||
|
@ -391,7 +392,7 @@ impl Store {
|
||||||
/// - CreateCallError(EntryAlreadyExists()) if the entry exists already.
|
/// - CreateCallError(EntryAlreadyExists()) if the entry exists already.
|
||||||
///
|
///
|
||||||
pub fn create<'a, S: IntoStoreId>(&'a self, id: S) -> Result<FileLockEntry<'a>> {
|
pub fn create<'a, S: IntoStoreId>(&'a self, id: S) -> Result<FileLockEntry<'a>> {
|
||||||
let id = try!(id.into_storeid()).with_base(self.path().clone());
|
let id = id.into_storeid()?.with_base(self.path().clone());
|
||||||
|
|
||||||
debug!("Creating id: '{}'", id);
|
debug!("Creating id: '{}'", id);
|
||||||
|
|
||||||
|
@ -408,7 +409,7 @@ impl Store {
|
||||||
}
|
}
|
||||||
hsmap.insert(id.clone(), {
|
hsmap.insert(id.clone(), {
|
||||||
debug!("Creating: '{}'", id);
|
debug!("Creating: '{}'", id);
|
||||||
let mut se = try!(StoreEntry::new(id.clone(), &self.backend));
|
let mut se = StoreEntry::new(id.clone(), &self.backend)?;
|
||||||
se.status = StoreEntryStatus::Borrowed;
|
se.status = StoreEntryStatus::Borrowed;
|
||||||
se
|
se
|
||||||
});
|
});
|
||||||
|
@ -434,21 +435,20 @@ impl Store {
|
||||||
/// - RetrieveCallError(LockPoisoned()) if the internal lock is poisened.
|
/// - RetrieveCallError(LockPoisoned()) if the internal lock is poisened.
|
||||||
///
|
///
|
||||||
pub fn retrieve<'a, S: IntoStoreId>(&'a self, id: S) -> Result<FileLockEntry<'a>> {
|
pub fn retrieve<'a, S: IntoStoreId>(&'a self, id: S) -> Result<FileLockEntry<'a>> {
|
||||||
let id = try!(id.into_storeid()).with_base(self.path().clone());
|
let id = id.into_storeid()?.with_base(self.path().clone());
|
||||||
debug!("Retrieving id: '{}'", id);
|
debug!("Retrieving id: '{}'", id);
|
||||||
let entry = try!({
|
let entry = self
|
||||||
self.entries
|
.entries
|
||||||
.write()
|
.write()
|
||||||
.map_err(|_| SE::from_kind(SEK::LockPoisoned))
|
.map_err(|_| SE::from_kind(SEK::LockPoisoned))
|
||||||
.and_then(|mut es| {
|
.and_then(|mut es| {
|
||||||
let new_se = try!(StoreEntry::new(id.clone(), &self.backend));
|
let new_se = StoreEntry::new(id.clone(), &self.backend)?;
|
||||||
let se = es.entry(id.clone()).or_insert(new_se);
|
let se = es.entry(id.clone()).or_insert(new_se);
|
||||||
let entry = se.get_entry();
|
let entry = se.get_entry();
|
||||||
se.status = StoreEntryStatus::Borrowed;
|
se.status = StoreEntryStatus::Borrowed;
|
||||||
entry
|
entry
|
||||||
})
|
})
|
||||||
.chain_err(|| SEK::RetrieveCallError)
|
.chain_err(|| SEK::RetrieveCallError)?;
|
||||||
});
|
|
||||||
|
|
||||||
debug!("Constructing FileLockEntry: '{}'", id);
|
debug!("Constructing FileLockEntry: '{}'", id);
|
||||||
Ok(FileLockEntry::new(self, entry))
|
Ok(FileLockEntry::new(self, entry))
|
||||||
|
@ -465,16 +465,15 @@ impl Store {
|
||||||
/// - Errors Store::retrieve() might return
|
/// - Errors Store::retrieve() might return
|
||||||
///
|
///
|
||||||
pub fn get<'a, S: IntoStoreId + Clone>(&'a self, id: S) -> Result<Option<FileLockEntry<'a>>> {
|
pub fn get<'a, S: IntoStoreId + Clone>(&'a self, id: S) -> Result<Option<FileLockEntry<'a>>> {
|
||||||
let id = try!(id.into_storeid()).with_base(self.path().clone());
|
let id = id.into_storeid()?.with_base(self.path().clone());
|
||||||
|
|
||||||
debug!("Getting id: '{}'", id);
|
debug!("Getting id: '{}'", id);
|
||||||
|
|
||||||
let exists = try!(id.exists()) || try!(self.entries
|
let exists = id.exists()? || self.entries
|
||||||
.read()
|
.read()
|
||||||
.map(|map| map.contains_key(&id))
|
.map(|map| map.contains_key(&id))
|
||||||
.map_err(|_| SE::from_kind(SEK::LockPoisoned))
|
.map_err(|_| SE::from_kind(SEK::LockPoisoned))
|
||||||
.chain_err(|| SEK::GetCallError)
|
.chain_err(|| SEK::GetCallError)?;
|
||||||
);
|
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
debug!("Does not exist in internal cache or filesystem: {:?}", id);
|
debug!("Does not exist in internal cache or filesystem: {:?}", id);
|
||||||
|
@ -558,17 +557,17 @@ impl Store {
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
};
|
};
|
||||||
|
|
||||||
let se = try!(hsmap.get_mut(&entry.location).ok_or_else(|| {
|
let se = hsmap.get_mut(&entry.location).ok_or_else(|| {
|
||||||
SE::from_kind(SEK::IdNotFound(entry.location.clone()))
|
SE::from_kind(SEK::IdNotFound(entry.location.clone()))
|
||||||
}));
|
})?;
|
||||||
|
|
||||||
assert!(se.is_borrowed(), "Tried to update a non borrowed entry.");
|
assert!(se.is_borrowed(), "Tried to update a non borrowed entry.");
|
||||||
|
|
||||||
debug!("Verifying Entry");
|
debug!("Verifying Entry");
|
||||||
try!(entry.entry.verify());
|
entry.entry.verify()?;
|
||||||
|
|
||||||
debug!("Writing Entry");
|
debug!("Writing Entry");
|
||||||
try!(se.write_entry(&entry.entry));
|
se.write_entry(&entry.entry)?;
|
||||||
if modify_presence {
|
if modify_presence {
|
||||||
debug!("Modifying ppresence of {} -> Present", entry.get_location());
|
debug!("Modifying ppresence of {} -> Present", entry.get_location());
|
||||||
se.status = StoreEntryStatus::Present;
|
se.status = StoreEntryStatus::Present;
|
||||||
|
@ -590,7 +589,7 @@ impl Store {
|
||||||
/// - Errors StoreEntry::new() might return
|
/// - Errors StoreEntry::new() might return
|
||||||
///
|
///
|
||||||
pub fn retrieve_copy<S: IntoStoreId>(&self, id: S) -> Result<Entry> {
|
pub fn retrieve_copy<S: IntoStoreId>(&self, id: S) -> Result<Entry> {
|
||||||
let id = try!(id.into_storeid()).with_base(self.path().clone());
|
let id = id.into_storeid()?.with_base(self.path().clone());
|
||||||
debug!("Retrieving copy of '{}'", id);
|
debug!("Retrieving copy of '{}'", id);
|
||||||
let entries = match self.entries.write() {
|
let entries = match self.entries.write() {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -605,7 +604,7 @@ impl Store {
|
||||||
return Err(SE::from_kind(SEK::IdLocked)).chain_err(|| SEK::RetrieveCopyCallError);
|
return Err(SE::from_kind(SEK::IdLocked)).chain_err(|| SEK::RetrieveCopyCallError);
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(StoreEntry::new(id, &self.backend)).get_entry()
|
StoreEntry::new(id, &self.backend)?.get_entry()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete an entry
|
/// Delete an entry
|
||||||
|
@ -620,7 +619,7 @@ impl Store {
|
||||||
/// - DeleteCallError(FileError()) if the internals failed to remove the file.
|
/// - DeleteCallError(FileError()) if the internals failed to remove the file.
|
||||||
///
|
///
|
||||||
pub fn delete<S: IntoStoreId>(&self, id: S) -> Result<()> {
|
pub fn delete<S: IntoStoreId>(&self, id: S) -> Result<()> {
|
||||||
let id = try!(id.into_storeid()).with_base(self.path().clone());
|
let id = id.into_storeid()?.with_base(self.path().clone());
|
||||||
|
|
||||||
debug!("Deleting id: '{}'", id);
|
debug!("Deleting id: '{}'", id);
|
||||||
|
|
||||||
|
@ -641,7 +640,7 @@ impl Store {
|
||||||
// StoreId::exists(), a PathBuf object gets allocated. So we simply get a
|
// StoreId::exists(), a PathBuf object gets allocated. So we simply get a
|
||||||
// PathBuf here, check whether it is there and if it is, we can re-use it to
|
// PathBuf here, check whether it is there and if it is, we can re-use it to
|
||||||
// delete the filesystem file.
|
// delete the filesystem file.
|
||||||
let pb = try!(id.into_pathbuf());
|
let pb = id.into_pathbuf()?;
|
||||||
|
|
||||||
if pb.exists() {
|
if pb.exists() {
|
||||||
// looks like we're deleting a not-loaded file from the store.
|
// looks like we're deleting a not-loaded file from the store.
|
||||||
|
@ -660,7 +659,7 @@ impl Store {
|
||||||
|
|
||||||
// remove the entry first, then the file
|
// remove the entry first, then the file
|
||||||
entries.remove(&id);
|
entries.remove(&id);
|
||||||
let pb = try!(id.clone().with_base(self.path().clone()).into_pathbuf());
|
let pb = id.clone().with_base(self.path().clone()).into_pathbuf()?;
|
||||||
if let Err(e) = self.backend.remove_file(&pb) {
|
if let Err(e) = self.backend.remove_file(&pb) {
|
||||||
return Err(e)
|
return Err(e)
|
||||||
.chain_err(|| SEK::FileError)
|
.chain_err(|| SEK::FileError)
|
||||||
|
@ -689,12 +688,11 @@ impl Store {
|
||||||
-> Result<()>
|
-> Result<()>
|
||||||
{
|
{
|
||||||
let new_id = new_id.with_base(self.path().clone());
|
let new_id = new_id.with_base(self.path().clone());
|
||||||
let hsmap = try!(
|
let hsmap = self
|
||||||
self.entries
|
.entries
|
||||||
.write()
|
.write()
|
||||||
.map_err(|_| SE::from_kind(SEK::LockPoisoned))
|
.map_err(|_| SE::from_kind(SEK::LockPoisoned))
|
||||||
.chain_err(|| SEK::MoveCallError)
|
.chain_err(|| SEK::MoveCallError)?;
|
||||||
);
|
|
||||||
|
|
||||||
if hsmap.contains_key(&new_id) {
|
if hsmap.contains_key(&new_id) {
|
||||||
return Err(SE::from_kind(SEK::EntryAlreadyExists(new_id.clone())))
|
return Err(SE::from_kind(SEK::EntryAlreadyExists(new_id.clone())))
|
||||||
|
@ -703,8 +701,8 @@ impl Store {
|
||||||
|
|
||||||
let old_id = entry.get_location().clone();
|
let old_id = entry.get_location().clone();
|
||||||
|
|
||||||
let old_id_as_path = try!(old_id.clone().with_base(self.path().clone()).into_pathbuf());
|
let old_id_as_path = old_id.clone().with_base(self.path().clone()).into_pathbuf()?;
|
||||||
let new_id_as_path = try!(new_id.clone().with_base(self.path().clone()).into_pathbuf());
|
let new_id_as_path = new_id.clone().with_base(self.path().clone()).into_pathbuf()?;
|
||||||
self.backend.copy(&old_id_as_path, &new_id_as_path)
|
self.backend.copy(&old_id_as_path, &new_id_as_path)
|
||||||
.and_then(|_| {
|
.and_then(|_| {
|
||||||
if remove_old {
|
if remove_old {
|
||||||
|
@ -777,10 +775,10 @@ impl Store {
|
||||||
|
|
||||||
debug!("Old id is not yet borrowed");
|
debug!("Old id is not yet borrowed");
|
||||||
|
|
||||||
let old_id_pb = try!(old_id.clone().with_base(self.path().clone()).into_pathbuf());
|
let old_id_pb = old_id.clone().with_base(self.path().clone()).into_pathbuf()?;
|
||||||
let new_id_pb = try!(new_id.clone().with_base(self.path().clone()).into_pathbuf());
|
let new_id_pb = new_id.clone().with_base(self.path().clone()).into_pathbuf()?;
|
||||||
|
|
||||||
if try!(self.backend.exists(&new_id_pb)) {
|
if self.backend.exists(&new_id_pb)? {
|
||||||
return Err(SE::from_kind(SEK::EntryAlreadyExists(new_id.clone())));
|
return Err(SE::from_kind(SEK::EntryAlreadyExists(new_id.clone())));
|
||||||
}
|
}
|
||||||
debug!("New entry does not yet exist on filesystem. Good.");
|
debug!("New entry does not yet exist on filesystem. Good.");
|
||||||
|
@ -817,11 +815,12 @@ impl Store {
|
||||||
let is_file = {
|
let is_file = {
|
||||||
let mut base = self.path().clone();
|
let mut base = self.path().clone();
|
||||||
base.push(element.clone());
|
base.push(element.clone());
|
||||||
try!(self.backend.is_file(&base))
|
println!("Checking: {:?}", base);
|
||||||
|
self.backend.is_file(&base)?
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_file {
|
if is_file {
|
||||||
let sid = try!(StoreId::from_full_path(self.path(), element));
|
let sid = StoreId::from_full_path(self.path(), element)?;
|
||||||
elems.push(sid);
|
elems.push(sid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -841,14 +840,14 @@ impl Debug for Store {
|
||||||
|
|
||||||
/// TODO: Make pretty.
|
/// TODO: Make pretty.
|
||||||
fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FMTError> {
|
fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FMTError> {
|
||||||
try!(write!(fmt, " --- Store ---\n"));
|
write!(fmt, " --- Store ---\n")?;
|
||||||
try!(write!(fmt, "\n"));
|
write!(fmt, "\n")?;
|
||||||
try!(write!(fmt, " - location : {:?}\n", self.location));
|
write!(fmt, " - location : {:?}\n", self.location)?;
|
||||||
try!(write!(fmt, " - configuration : {:?}\n", self.configuration));
|
write!(fmt, " - configuration : {:?}\n", self.configuration)?;
|
||||||
try!(write!(fmt, "\n"));
|
write!(fmt, "\n")?;
|
||||||
try!(write!(fmt, "Entries:\n"));
|
write!(fmt, "Entries:\n")?;
|
||||||
try!(write!(fmt, "{:?}", self.entries));
|
write!(fmt, "{:?}", self.entries)?;
|
||||||
try!(write!(fmt, "\n"));
|
write!(fmt, "\n")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,7 +978,7 @@ impl Entry {
|
||||||
pub fn from_reader<S: IntoStoreId>(loc: S, file: &mut Read) -> Result<Entry> {
|
pub fn from_reader<S: IntoStoreId>(loc: S, file: &mut Read) -> Result<Entry> {
|
||||||
let text = {
|
let text = {
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
try!(file.read_to_string(&mut s));
|
file.read_to_string(&mut s)?;
|
||||||
s
|
s
|
||||||
};
|
};
|
||||||
Self::from_str(loc, &text[..])
|
Self::from_str(loc, &text[..])
|
||||||
|
@ -1000,10 +999,10 @@ impl Entry {
|
||||||
pub fn from_str<S: IntoStoreId>(loc: S, s: &str) -> Result<Entry> {
|
pub fn from_str<S: IntoStoreId>(loc: S, s: &str) -> Result<Entry> {
|
||||||
use util::entry_buffer_to_header_content;
|
use util::entry_buffer_to_header_content;
|
||||||
|
|
||||||
let (header, content) = try!(entry_buffer_to_header_content(s));
|
let (header, content) = entry_buffer_to_header_content(s)?;
|
||||||
|
|
||||||
Ok(Entry {
|
Ok(Entry {
|
||||||
location: try!(loc.into_storeid()),
|
location: loc.into_storeid()?,
|
||||||
header: header,
|
header: header,
|
||||||
content: content,
|
content: content,
|
||||||
})
|
})
|
||||||
|
|
|
@ -59,9 +59,9 @@ impl StoreId {
|
||||||
pub fn from_full_path<D>(store_part: &PathBuf, full_path: D) -> Result<StoreId>
|
pub fn from_full_path<D>(store_part: &PathBuf, full_path: D) -> Result<StoreId>
|
||||||
where D: Deref<Target = Path>
|
where D: Deref<Target = Path>
|
||||||
{
|
{
|
||||||
let p = try!(
|
let p = full_path
|
||||||
full_path.strip_prefix(store_part).chain_err(|| SEK::StoreIdBuildFromFullPathError)
|
.strip_prefix(store_part)
|
||||||
);
|
.chain_err(|| SEK::StoreIdBuildFromFullPathError)?;
|
||||||
StoreId::new(Some(store_part.clone()), PathBuf::from(p))
|
StoreId::new(Some(store_part.clone()), PathBuf::from(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ impl StoreId {
|
||||||
/// specified.
|
/// specified.
|
||||||
pub fn into_pathbuf(mut self) -> Result<PathBuf> {
|
pub fn into_pathbuf(mut self) -> Result<PathBuf> {
|
||||||
let base = self.base.take();
|
let base = self.base.take();
|
||||||
let mut base = try!(base.ok_or_else(|| SEK::StoreIdHasNoBaseError(self.id.clone())));
|
let mut base = base.ok_or_else(|| SEK::StoreIdHasNoBaseError(self.id.clone()))?;
|
||||||
base.push(self.id);
|
base.push(self.id);
|
||||||
Ok(base)
|
Ok(base)
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,6 @@ pub fn entry_buffer_to_header_content(buf: &str) -> Result<(Value, String)> {
|
||||||
|
|
||||||
let content = matches.name("content").map(|r| r.as_str()).unwrap_or("");
|
let content = matches.name("content").map(|r| r.as_str()).unwrap_or("");
|
||||||
|
|
||||||
Ok((try!(Value::parse(header.as_str())), String::from(content)))
|
Ok((Value::parse(header.as_str())?, String::from(content)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
url = "1.5"
|
url = "1.5"
|
||||||
regex = "0.2"
|
regex = "0.2"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -209,7 +209,7 @@ impl FromStoreId for DiaryId {
|
||||||
|
|
||||||
let mut cmps = s.components().rev();
|
let mut cmps = s.components().rev();
|
||||||
|
|
||||||
let (hour, minute) = try!(next_component(&mut cmps).and_then(|time| {
|
let (hour, minute) = next_component(&mut cmps).and_then(|time| {
|
||||||
let mut time = time.split(":");
|
let mut time = time.split(":");
|
||||||
let hour = time.next().and_then(|s| FromStr::from_str(s).ok());
|
let hour = time.next().and_then(|s| FromStr::from_str(s).ok());
|
||||||
let minute = time.next()
|
let minute = time.next()
|
||||||
|
@ -223,7 +223,7 @@ impl FromStoreId for DiaryId {
|
||||||
(Some(h), Some(m)) => Ok((h, m)),
|
(Some(h), Some(m)) => Ok((h, m)),
|
||||||
_ => return Err(DE::from_kind(DEK::IdParseError)),
|
_ => return Err(DE::from_kind(DEK::IdParseError)),
|
||||||
}
|
}
|
||||||
}));
|
})?;
|
||||||
|
|
||||||
let day: Result<u32,_> = next_component(&mut cmps)
|
let day: Result<u32,_> = next_component(&mut cmps)
|
||||||
.and_then(|s| s.parse::<u32>()
|
.and_then(|s| s.parse::<u32>()
|
||||||
|
@ -244,10 +244,10 @@ impl FromStoreId for DiaryId {
|
||||||
debug!("Year = {:?}", year);
|
debug!("Year = {:?}", year);
|
||||||
debug!("Name = {:?}", name);
|
debug!("Name = {:?}", name);
|
||||||
|
|
||||||
let day = try!(day);
|
let day = day?;
|
||||||
let month = try!(month);
|
let month = month?;
|
||||||
let year = try!(year);
|
let year = year?;
|
||||||
let name = try!(name);
|
let name = name?;
|
||||||
|
|
||||||
Ok(DiaryId::new(name, year, month, day, hour, minute))
|
Ok(DiaryId::new(name, year, month, day, hour, minute))
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,10 +54,10 @@ impl DiaryViewer {
|
||||||
Ok(id) => println!("{} :\n", id),
|
Ok(id) => println!("{} :\n", id),
|
||||||
Err(e) => trace_error(&e),
|
Err(e) => trace_error(&e),
|
||||||
}
|
}
|
||||||
let _ = try!(self.0
|
let _ = self.0
|
||||||
.view_entry(&entry)
|
.view_entry(&entry)
|
||||||
.chain_err(|| DEK::ViewError)
|
.chain_err(|| DEK::ViewError)
|
||||||
.chain_err(|| DEK::IOError));
|
.chain_err(|| DEK::IOError)?;
|
||||||
println!("\n---\n");
|
println!("\n---\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
email = "0.0.17"
|
email = "0.0.17"
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl Hasher for MailHasher {
|
||||||
use email::Header;
|
use email::Header;
|
||||||
|
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
try!(c.read_to_string(&mut s));
|
c.read_to_string(&mut s)?;
|
||||||
|
|
||||||
MimeMessage::parse(&s)
|
MimeMessage::parse(&s)
|
||||||
.chain_err(|| REK::RefHashingError)
|
.chain_err(|| REK::RefHashingError)
|
||||||
|
@ -66,9 +66,9 @@ impl Hasher for MailHasher {
|
||||||
|
|
||||||
let mut v : Vec<String> = vec![];
|
let mut v : Vec<String> = vec![];
|
||||||
for hdr in mail.headers.iter().filter(|item| filter.filter(item)) {
|
for hdr in mail.headers.iter().filter(|item| filter.filter(item)) {
|
||||||
let s = try!(hdr
|
let s = hdr
|
||||||
.get_value()
|
.get_value()
|
||||||
.chain_err(|| REK::RefHashingError));
|
.chain_err(|| REK::RefHashingError)?;
|
||||||
|
|
||||||
v.push(s);
|
v.push(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
toml = "0.4"
|
toml = "0.4"
|
||||||
|
|
|
@ -49,10 +49,10 @@ impl<'a> NoteStore<'a> for Store {
|
||||||
|
|
||||||
debug!("Creating new Note: '{}'", name);
|
debug!("Creating new Note: '{}'", name);
|
||||||
let fle = {
|
let fle = {
|
||||||
let mut lockentry = try!(ModuleEntryPath::new(name.clone())
|
let mut lockentry = ModuleEntryPath::new(name.clone())
|
||||||
.into_storeid()
|
.into_storeid()
|
||||||
.and_then(|id| self.create(id))
|
.and_then(|id| self.create(id))
|
||||||
.chain_err(|| NEK::StoreWriteError));
|
.chain_err(|| NEK::StoreWriteError)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let entry = lockentry.deref_mut();
|
let entry = lockentry.deref_mut();
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
filters = "0.2"
|
filters = "0.2"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
task-hookrs = "0.4"
|
task-hookrs = "0.4"
|
||||||
uuid = "0.5"
|
uuid = "0.5"
|
||||||
|
|
|
@ -54,7 +54,7 @@ impl<'a> TaskStore<'a> for Store {
|
||||||
|
|
||||||
fn import_task_from_reader<R: BufRead>(&'a self, mut r: R) -> Result<(FileLockEntry<'a>, String, Uuid)> {
|
fn import_task_from_reader<R: BufRead>(&'a self, mut r: R) -> Result<(FileLockEntry<'a>, String, Uuid)> {
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
try!(r.read_line(&mut line).map_err(|_| TE::from_kind(TEK::UTF8Error)));
|
r.read_line(&mut line).map_err(|_| TE::from_kind(TEK::UTF8Error))?;
|
||||||
import_task(&line.as_str())
|
import_task(&line.as_str())
|
||||||
.map_err(|_| TE::from_kind(TEK::ImportError))
|
.map_err(|_| TE::from_kind(TEK::ImportError))
|
||||||
.and_then(|t| {
|
.and_then(|t| {
|
||||||
|
@ -74,7 +74,7 @@ impl<'a> TaskStore<'a> for Store {
|
||||||
///
|
///
|
||||||
fn get_task_from_import<R: BufRead>(&'a self, mut r: R) -> Result<RResult<FileLockEntry<'a>, String>> {
|
fn get_task_from_import<R: BufRead>(&'a self, mut r: R) -> Result<RResult<FileLockEntry<'a>, String>> {
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
try!(r.read_line(&mut line).chain_err(|| TEK::UTF8Error));
|
r.read_line(&mut line).chain_err(|| TEK::UTF8Error)?;
|
||||||
self.get_task_from_string(line)
|
self.get_task_from_string(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ impl<'a> TaskStore<'a> for Store {
|
||||||
/// implicitely create the task if it does not exist.
|
/// implicitely create the task if it does not exist.
|
||||||
fn retrieve_task_from_import<R: BufRead>(&'a self, mut r: R) -> Result<FileLockEntry<'a>> {
|
fn retrieve_task_from_import<R: BufRead>(&'a self, mut r: R) -> Result<FileLockEntry<'a>> {
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
try!(r.read_line(&mut line).chain_err(|| TEK::UTF8Error));
|
r.read_line(&mut line).chain_err(|| TEK::UTF8Error)?;
|
||||||
self.retrieve_task_from_string(line)
|
self.retrieve_task_from_string(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ impl<'a> TaskStore<'a> for Store {
|
||||||
}
|
}
|
||||||
} // end if c % 2
|
} // end if c % 2
|
||||||
},
|
},
|
||||||
Err(e) => return Err(TE::from_kind(TEK::ImportError)),
|
Err(_) => return Err(TE::from_kind(TEK::ImportError)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -186,14 +186,14 @@ impl<'a> TaskStore<'a> for Store {
|
||||||
.and_then(|mut fle| {
|
.and_then(|mut fle| {
|
||||||
{
|
{
|
||||||
let hdr = fle.get_header_mut();
|
let hdr = fle.get_header_mut();
|
||||||
if try!(hdr.read("todo").chain_err(|| TEK::StoreError)).is_none() {
|
if hdr.read("todo").chain_err(|| TEK::StoreError)?.is_none() {
|
||||||
try!(hdr
|
hdr
|
||||||
.set("todo", Value::Table(BTreeMap::new()))
|
.set("todo", Value::Table(BTreeMap::new()))
|
||||||
.chain_err(|| TEK::StoreError));
|
.chain_err(|| TEK::StoreError)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(hdr.set("todo.uuid", Value::String(format!("{}",uuid)))
|
hdr.set("todo.uuid", Value::String(format!("{}",uuid)))
|
||||||
.chain_err(|| TEK::StoreError));
|
.chain_err(|| TEK::StoreError)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If none of the errors above have returned the function, everything is fine
|
// If none of the errors above have returned the function, everything is fine
|
||||||
|
|
|
@ -9,6 +9,12 @@ keywords = ["imag", "PIM", "personal", "information", "management"]
|
||||||
readme = "../../../README.md"
|
readme = "../../../README.md"
|
||||||
license = "LGPL-2.1"
|
license = "LGPL-2.1"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
toml = "0.4"
|
toml = "0.4"
|
||||||
|
|
|
@ -48,13 +48,13 @@ impl Annotateable for Entry {
|
||||||
/// Annotate an entry, returns the new entry which is used to annotate
|
/// Annotate an entry, returns the new entry which is used to annotate
|
||||||
fn annotate<'a>(&mut self, store: &'a Store, ann_name: &str) -> Result<FileLockEntry<'a>> {
|
fn annotate<'a>(&mut self, store: &'a Store, ann_name: &str) -> Result<FileLockEntry<'a>> {
|
||||||
use module_path::ModuleEntryPath;
|
use module_path::ModuleEntryPath;
|
||||||
store.retrieve(try!(ModuleEntryPath::new(ann_name).into_storeid()))
|
store.retrieve(ModuleEntryPath::new(ann_name).into_storeid()?)
|
||||||
.map_err(From::from)
|
.map_err(From::from)
|
||||||
.and_then(|mut anno| {
|
.and_then(|mut anno| {
|
||||||
{
|
{
|
||||||
let header = anno.get_header_mut();
|
let header = anno.get_header_mut();
|
||||||
try!(header.insert("annotation.is_annotation", Value::Boolean(true)));
|
header.insert("annotation.is_annotation", Value::Boolean(true))?;
|
||||||
try!(header.insert("annotation.name", Value::String(String::from(ann_name))));
|
header.insert("annotation.name", Value::String(String::from(ann_name)))?;
|
||||||
}
|
}
|
||||||
Ok(anno)
|
Ok(anno)
|
||||||
})
|
})
|
||||||
|
@ -69,7 +69,7 @@ impl Annotateable for Entry {
|
||||||
/// `ann_name`, which is then returned
|
/// `ann_name`, which is then returned
|
||||||
fn denotate<'a>(&mut self, store: &'a Store, ann_name: &str) -> Result<Option<FileLockEntry<'a>>> {
|
fn denotate<'a>(&mut self, store: &'a Store, ann_name: &str) -> Result<Option<FileLockEntry<'a>>> {
|
||||||
for annotation in self.annotations(store)? {
|
for annotation in self.annotations(store)? {
|
||||||
let mut anno = try!(annotation);
|
let mut anno = annotation?;
|
||||||
let name = match anno.get_header().read("annotation.name")? {
|
let name = match anno.get_header().read("annotation.name")? {
|
||||||
None => continue,
|
None => continue,
|
||||||
Some(val) => match *val {
|
Some(val) => match *val {
|
||||||
|
@ -79,7 +79,7 @@ impl Annotateable for Entry {
|
||||||
};
|
};
|
||||||
|
|
||||||
if name == ann_name {
|
if name == ann_name {
|
||||||
let _ = try!(self.remove_internal_link(&mut anno));
|
let _ = self.remove_internal_link(&mut anno)?;
|
||||||
return Ok(Some(anno));
|
return Ok(Some(anno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
toml = "0.4"
|
toml = "0.4"
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl CategoryRegister for Store {
|
||||||
|
|
||||||
/// Check whether a category exists
|
/// Check whether a category exists
|
||||||
fn category_exists(&self, name: &str) -> Result<bool> {
|
fn category_exists(&self, name: &str) -> Result<bool> {
|
||||||
let sid = try!(mk_category_storeid(self.path().clone(), name));
|
let sid = mk_category_storeid(self.path().clone(), name)?;
|
||||||
represents_category(self, sid, name)
|
represents_category(self, sid, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ impl CategoryRegister for Store {
|
||||||
fn create_category(&self, name: &str) -> Result<bool> {
|
fn create_category(&self, name: &str) -> Result<bool> {
|
||||||
use libimagstore::error::StoreErrorKind as SEK;
|
use libimagstore::error::StoreErrorKind as SEK;
|
||||||
|
|
||||||
let sid = try!(mk_category_storeid(self.path().clone(), name));
|
let sid = mk_category_storeid(self.path().clone(), name)?;
|
||||||
|
|
||||||
|
|
||||||
match self.create(sid) {
|
match self.create(sid) {
|
||||||
|
@ -94,7 +94,7 @@ impl CategoryRegister for Store {
|
||||||
|
|
||||||
/// Delete a category
|
/// Delete a category
|
||||||
fn delete_category(&self, name: &str) -> Result<()> {
|
fn delete_category(&self, name: &str) -> Result<()> {
|
||||||
let sid = try!(mk_category_storeid(self.path().clone(), name));
|
let sid = mk_category_storeid(self.path().clone(), name)?;
|
||||||
|
|
||||||
self.delete(sid).chain_err(|| CEK::StoreWriteError)
|
self.delete(sid).chain_err(|| CEK::StoreWriteError)
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ impl CategoryRegister for Store {
|
||||||
/// Returns the FileLockEntry which represents the category, so one can link to it and use it
|
/// Returns the FileLockEntry which represents the category, so one can link to it and use it
|
||||||
/// like a normal file in the store (which is exactly what it is).
|
/// like a normal file in the store (which is exactly what it is).
|
||||||
fn get_category_by_name(&self, name: &str) -> Result<Option<FileLockEntry>> {
|
fn get_category_by_name(&self, name: &str) -> Result<Option<FileLockEntry>> {
|
||||||
let sid = try!(mk_category_storeid(self.path().clone(), name));
|
let sid = mk_category_storeid(self.path().clone(), name)?;
|
||||||
|
|
||||||
self.get(sid)
|
self.get(sid)
|
||||||
.chain_err(|| CEK::StoreWriteError)
|
.chain_err(|| CEK::StoreWriteError)
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
toml-query = "^0.4"
|
toml-query = "^0.4"
|
||||||
|
|
|
@ -112,11 +112,11 @@ impl EntryDate for Entry {
|
||||||
/// header in an inconsistent state.
|
/// header in an inconsistent state.
|
||||||
///
|
///
|
||||||
fn delete_date_range(&mut self) -> Result<()> {
|
fn delete_date_range(&mut self) -> Result<()> {
|
||||||
let _ = try!(self
|
let _ = self
|
||||||
.get_header_mut()
|
.get_header_mut()
|
||||||
.delete(&DATE_RANGE_START_HEADER_LOCATION)
|
.delete(&DATE_RANGE_START_HEADER_LOCATION)
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.chain_err(|| DEK::DeleteDateTimeRangeError));
|
.chain_err(|| DEK::DeleteDateTimeRangeError)?;
|
||||||
|
|
||||||
self.get_header_mut()
|
self.get_header_mut()
|
||||||
.delete(&DATE_RANGE_END_HEADER_LOCATION)
|
.delete(&DATE_RANGE_END_HEADER_LOCATION)
|
||||||
|
@ -125,7 +125,7 @@ impl EntryDate for Entry {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_date_range(&self) -> Result<DateTimeRange> {
|
fn read_date_range(&self) -> Result<DateTimeRange> {
|
||||||
let start = try!(self
|
let start = self
|
||||||
.get_header()
|
.get_header()
|
||||||
.read(&DATE_RANGE_START_HEADER_LOCATION)
|
.read(&DATE_RANGE_START_HEADER_LOCATION)
|
||||||
.chain_err(|| DEK::ReadDateTimeRangeError)
|
.chain_err(|| DEK::ReadDateTimeRangeError)
|
||||||
|
@ -136,9 +136,9 @@ impl EntryDate for Entry {
|
||||||
Some(_) => Err(DE::from_kind(DEK::DateHeaderFieldTypeError)),
|
Some(_) => Err(DE::from_kind(DEK::DateHeaderFieldTypeError)),
|
||||||
_ => Err(DE::from_kind(DEK::ReadDateError)),
|
_ => Err(DE::from_kind(DEK::ReadDateError)),
|
||||||
}
|
}
|
||||||
}));
|
})?;
|
||||||
|
|
||||||
let end = try!(self
|
let end = self
|
||||||
.get_header()
|
.get_header()
|
||||||
.read(&DATE_RANGE_START_HEADER_LOCATION)
|
.read(&DATE_RANGE_START_HEADER_LOCATION)
|
||||||
.chain_err(|| DEK::ReadDateTimeRangeError)
|
.chain_err(|| DEK::ReadDateTimeRangeError)
|
||||||
|
@ -149,7 +149,7 @@ impl EntryDate for Entry {
|
||||||
Some(_) => Err(DE::from_kind(DEK::DateHeaderFieldTypeError)),
|
Some(_) => Err(DE::from_kind(DEK::DateHeaderFieldTypeError)),
|
||||||
_ => Err(DE::from_kind(DEK::ReadDateError)),
|
_ => Err(DE::from_kind(DEK::ReadDateError)),
|
||||||
}
|
}
|
||||||
}));
|
})?;
|
||||||
|
|
||||||
DateTimeRange::new(start, end)
|
DateTimeRange::new(start, end)
|
||||||
.chain_err(|| DEK::DateTimeRangeError)
|
.chain_err(|| DEK::DateTimeRangeError)
|
||||||
|
@ -168,7 +168,7 @@ impl EntryDate for Entry {
|
||||||
let start = start.format(&DATE_FMT).to_string();
|
let start = start.format(&DATE_FMT).to_string();
|
||||||
let end = end.format(&DATE_FMT).to_string();
|
let end = end.format(&DATE_FMT).to_string();
|
||||||
|
|
||||||
let opt_old_start = try!(self
|
let opt_old_start = self
|
||||||
.get_header_mut()
|
.get_header_mut()
|
||||||
.insert(&DATE_RANGE_START_HEADER_LOCATION, Value::String(start))
|
.insert(&DATE_RANGE_START_HEADER_LOCATION, Value::String(start))
|
||||||
.map(|opt| opt.map(|stri| {
|
.map(|opt| opt.map(|stri| {
|
||||||
|
@ -178,9 +178,9 @@ impl EntryDate for Entry {
|
||||||
_ => Err(DE::from_kind(DEK::DateHeaderFieldTypeError)),
|
_ => Err(DE::from_kind(DEK::DateHeaderFieldTypeError)),
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.chain_err(|| DEK::SetDateTimeRangeError));
|
.chain_err(|| DEK::SetDateTimeRangeError)?;
|
||||||
|
|
||||||
let opt_old_end = try!(self
|
let opt_old_end = self
|
||||||
.get_header_mut()
|
.get_header_mut()
|
||||||
.insert(&DATE_RANGE_END_HEADER_LOCATION, Value::String(end))
|
.insert(&DATE_RANGE_END_HEADER_LOCATION, Value::String(end))
|
||||||
.map(|opt| opt.map(|stri| {
|
.map(|opt| opt.map(|stri| {
|
||||||
|
@ -190,7 +190,7 @@ impl EntryDate for Entry {
|
||||||
_ => Err(DE::from_kind(DEK::DateHeaderFieldTypeError)),
|
_ => Err(DE::from_kind(DEK::DateHeaderFieldTypeError)),
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.chain_err(|| DEK::SetDateTimeRangeError));
|
.chain_err(|| DEK::SetDateTimeRangeError)?;
|
||||||
|
|
||||||
match (opt_old_start, opt_old_end) {
|
match (opt_old_start, opt_old_end) {
|
||||||
(Some(Ok(old_start)), Some(Ok(old_end))) => {
|
(Some(Ok(old_start)), Some(Ok(old_end))) => {
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
error-chain = "0.11"
|
error-chain = "0.11"
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
filters = "0.2"
|
filters = "0.2"
|
||||||
|
|
|
@ -9,6 +9,12 @@ keywords = ["imag", "PIM", "personal", "information", "management"]
|
||||||
readme = "../../../README.md"
|
readme = "../../../README.md"
|
||||||
license = "LGPL-2.1"
|
license = "LGPL-2.1"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
toml = "0.4"
|
toml = "0.4"
|
||||||
toml-query = "^0.4"
|
toml-query = "^0.4"
|
||||||
|
|
|
@ -89,7 +89,7 @@ impl GPSEntry for Entry {
|
||||||
|
|
||||||
let mut hdr = self.get_header_mut();
|
let mut hdr = self.get_header_mut();
|
||||||
for pattern in patterns.iter() {
|
for pattern in patterns.iter() {
|
||||||
let _ = try!(hdr.delete(pattern).chain_err(|| GPSEK::HeaderWriteError));
|
let _ = hdr.delete(pattern).chain_err(|| GPSEK::HeaderWriteError)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
match coordinates {
|
match coordinates {
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
itertools = "0.7"
|
itertools = "0.7"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -325,12 +325,12 @@ impl ExternalLinker for Entry {
|
||||||
s.input_str(&link.as_str()[..]);
|
s.input_str(&link.as_str()[..]);
|
||||||
s.result_str()
|
s.result_str()
|
||||||
};
|
};
|
||||||
let file_id = try!(
|
let file_id =
|
||||||
ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
|
ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
|
||||||
.map_dbg_err(|_| {
|
.map_dbg_err(|_| {
|
||||||
format!("Failed to build StoreId for this hash '{:?}'", hash)
|
format!("Failed to build StoreId for this hash '{:?}'", hash)
|
||||||
})
|
})
|
||||||
);
|
?;
|
||||||
|
|
||||||
debug!("Link = '{:?}'", link);
|
debug!("Link = '{:?}'", link);
|
||||||
debug!("Hash = '{:?}'", hash);
|
debug!("Hash = '{:?}'", hash);
|
||||||
|
@ -338,17 +338,17 @@ impl ExternalLinker for Entry {
|
||||||
|
|
||||||
// retrieve the file from the store, which implicitely creates the entry if it does not
|
// retrieve the file from the store, which implicitely creates the entry if it does not
|
||||||
// exist
|
// exist
|
||||||
let mut file = try!(store
|
let mut file = store
|
||||||
.retrieve(file_id.clone())
|
.retrieve(file_id.clone())
|
||||||
.map_dbg_err(|_| {
|
.map_dbg_err(|_| {
|
||||||
format!("Failed to create or retrieve an file for this link '{:?}'", link)
|
format!("Failed to create or retrieve an file for this link '{:?}'", link)
|
||||||
}));
|
})?;
|
||||||
|
|
||||||
debug!("Generating header content!");
|
debug!("Generating header content!");
|
||||||
{
|
{
|
||||||
let hdr = file.deref_mut().get_header_mut();
|
let hdr = file.deref_mut().get_header_mut();
|
||||||
|
|
||||||
let mut table = match try!(hdr.read("links.external.content")) {
|
let mut table = match hdr.read("links.external.content")? {
|
||||||
Some(&Value::Table(ref table)) => table.clone(),
|
Some(&Value::Table(ref table)) => table.clone(),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
warn!("There is a value at 'links.external.content' which is not a table.");
|
warn!("There is a value at 'links.external.content' which is not a table.");
|
||||||
|
@ -363,12 +363,12 @@ impl ExternalLinker for Entry {
|
||||||
debug!("setting URL = '{:?}", v);
|
debug!("setting URL = '{:?}", v);
|
||||||
table.insert(String::from("url"), v);
|
table.insert(String::from("url"), v);
|
||||||
|
|
||||||
let _ = try!(hdr.insert("links.external.content", Value::Table(table)));
|
let _ = hdr.insert("links.external.content", Value::Table(table))?;
|
||||||
debug!("Setting URL worked");
|
debug!("Setting URL worked");
|
||||||
}
|
}
|
||||||
|
|
||||||
// then add an internal link to the new file or return an error if this fails
|
// then add an internal link to the new file or return an error if this fails
|
||||||
let _ = try!(self.add_internal_link(file.deref_mut()));
|
let _ = self.add_internal_link(file.deref_mut())?;
|
||||||
debug!("Error adding internal link");
|
debug!("Error adding internal link");
|
||||||
}
|
}
|
||||||
debug!("Ready iterating");
|
debug!("Ready iterating");
|
||||||
|
|
|
@ -406,7 +406,7 @@ impl InternalLinker for Entry {
|
||||||
new_links.push(link.get_location().clone().into());
|
new_links.push(link.get_location().clone().into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_links = try!(LinkIter::new(new_links)
|
let new_links = LinkIter::new(new_links)
|
||||||
.into_values()
|
.into_values()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.fold(Ok(vec![]), |acc, elem| {
|
.fold(Ok(vec![]), |acc, elem| {
|
||||||
|
@ -417,7 +417,7 @@ impl InternalLinker for Entry {
|
||||||
v
|
v
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}));
|
})?;
|
||||||
let res = self
|
let res = self
|
||||||
.get_header_mut()
|
.get_header_mut()
|
||||||
.insert("links.internal", Value::Array(new_links))
|
.insert("links.internal", Value::Array(new_links))
|
||||||
|
@ -477,7 +477,7 @@ fn add_internal_link_with_instance(this: &mut Entry, link: &mut Entry, instance:
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rewrite_links<I: Iterator<Item = Link>>(header: &mut Value, links: I) -> Result<()> {
|
fn rewrite_links<I: Iterator<Item = Link>>(header: &mut Value, links: I) -> Result<()> {
|
||||||
let links = try!(links.into_values()
|
let links = links.into_values()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.fold(Ok(vec![]), |acc, elem| {
|
.fold(Ok(vec![]), |acc, elem| {
|
||||||
acc.and_then(move |mut v| {
|
acc.and_then(move |mut v| {
|
||||||
|
@ -487,7 +487,7 @@ fn rewrite_links<I: Iterator<Item = Link>>(header: &mut Value, links: I) -> Resu
|
||||||
v
|
v
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}));
|
})?;
|
||||||
|
|
||||||
debug!("Setting new link array: {:?}", links);
|
debug!("Setting new link array: {:?}", links);
|
||||||
let process = header
|
let process = header
|
||||||
|
@ -502,7 +502,7 @@ fn add_foreign_link(target: &mut Entry, from: StoreId) -> Result<()> {
|
||||||
debug!("Linking back from {:?} to {:?}", target.get_location(), from);
|
debug!("Linking back from {:?} to {:?}", target.get_location(), from);
|
||||||
target.get_internal_links()
|
target.get_internal_links()
|
||||||
.and_then(|links| {
|
.and_then(|links| {
|
||||||
let links = try!(links
|
let links = links
|
||||||
.chain(LinkIter::new(vec![from.into()]))
|
.chain(LinkIter::new(vec![from.into()]))
|
||||||
.into_values()
|
.into_values()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -514,7 +514,7 @@ fn add_foreign_link(target: &mut Entry, from: StoreId) -> Result<()> {
|
||||||
v
|
v
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}));
|
})?;
|
||||||
debug!("Setting links in {:?}: {:?}", target.get_location(), links);
|
debug!("Setting links in {:?}: {:?}", target.get_location(), links);
|
||||||
|
|
||||||
let res = target
|
let res = target
|
||||||
|
@ -551,7 +551,7 @@ fn process_rw_result(links: Result<Option<Value>>) -> Result<LinkIter> {
|
||||||
return Err(LEK::ExistingLinkTypeWrong.into());
|
return Err(LEK::ExistingLinkTypeWrong.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let links : Vec<Link> = try!(links.into_iter()
|
let links : Vec<Link> = links.into_iter()
|
||||||
.map(|link| {
|
.map(|link| {
|
||||||
debug!("Matching the link: {:?}", link);
|
debug!("Matching the link: {:?}", link);
|
||||||
match link {
|
match link {
|
||||||
|
@ -566,11 +566,11 @@ fn process_rw_result(links: Result<Option<Value>>) -> Result<LinkIter> {
|
||||||
debug!("Things missing... returning Error instance");
|
debug!("Things missing... returning Error instance");
|
||||||
Err(LE::from_kind(LEK::LinkParserError))
|
Err(LE::from_kind(LEK::LinkParserError))
|
||||||
} else {
|
} else {
|
||||||
let link = try!(tab.remove("link")
|
let link = tab.remove("link")
|
||||||
.ok_or(LE::from_kind(LEK::LinkParserFieldMissingError)));
|
.ok_or(LE::from_kind(LEK::LinkParserFieldMissingError))?;
|
||||||
|
|
||||||
let anno = try!(tab.remove("annotation")
|
let anno = tab.remove("annotation")
|
||||||
.ok_or(LE::from_kind(LEK::LinkParserFieldMissingError)));
|
.ok_or(LE::from_kind(LEK::LinkParserFieldMissingError))?;
|
||||||
|
|
||||||
debug!("Ok, here we go with building a Link::Annotated");
|
debug!("Ok, here we go with building a Link::Annotated");
|
||||||
match (link, anno) {
|
match (link, anno) {
|
||||||
|
@ -591,7 +591,7 @@ fn process_rw_result(links: Result<Option<Value>>) -> Result<LinkIter> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect());
|
.collect::<Result<Vec<Link>>>()?;
|
||||||
|
|
||||||
debug!("Ok, the RW action was successful, returning link vector now!");
|
debug!("Ok, the RW action was successful, returning link vector now!");
|
||||||
Ok(LinkIter::new(links))
|
Ok(LinkIter::new(links))
|
||||||
|
@ -641,7 +641,7 @@ pub mod store_check {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
for element in iter {
|
for element in iter {
|
||||||
debug!("Checking element = {:?}", element);
|
debug!("Checking element = {:?}", element);
|
||||||
let entry = match try!(element) {
|
let entry = match element? {
|
||||||
Some(e) => e,
|
Some(e) => e,
|
||||||
None => {
|
None => {
|
||||||
let e = String::from("TODO: Not yet handled");
|
let e = String::from("TODO: Not yet handled");
|
||||||
|
@ -659,7 +659,7 @@ pub mod store_check {
|
||||||
for internal_link in internal_links {
|
for internal_link in internal_links {
|
||||||
debug!("internal link = {:?}", internal_link);
|
debug!("internal link = {:?}", internal_link);
|
||||||
|
|
||||||
linking.outgoing.push(try!(internal_link).get_location().clone());
|
linking.outgoing.push(internal_link?.get_location().clone());
|
||||||
linking.incoming.push(entry.get_location().clone());
|
linking.incoming.push(entry.get_location().clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,7 +677,7 @@ pub mod store_check {
|
||||||
if is_match!(self.get(id.clone()), Ok(Some(_))) {
|
if is_match!(self.get(id.clone()), Ok(Some(_))) {
|
||||||
debug!("Exists in store: {:?}", id);
|
debug!("Exists in store: {:?}", id);
|
||||||
|
|
||||||
if !try!(id.exists()) {
|
if !id.exists()? {
|
||||||
warn!("Does exist in store but not on FS: {:?}", id);
|
warn!("Does exist in store but not on FS: {:?}", id);
|
||||||
return Err(LE::from_kind(LEK::LinkTargetDoesNotExist))
|
return Err(LE::from_kind(LEK::LinkTargetDoesNotExist))
|
||||||
}
|
}
|
||||||
|
@ -750,8 +750,8 @@ pub mod store_check {
|
||||||
})
|
})
|
||||||
.and_then(|nw| {
|
.and_then(|nw| {
|
||||||
for (id, linking) in nw.iter() {
|
for (id, linking) in nw.iter() {
|
||||||
try!(incoming_links_exists_as_outgoing_links(id, linking, &nw));
|
incoming_links_exists_as_outgoing_links(id, linking, &nw)?;
|
||||||
try!(outgoing_links_exist_as_incoming_links(id, linking, &nw));
|
outgoing_links_exist_as_incoming_links(id, linking, &nw)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl<'a> Lister for LineLister<'a> {
|
||||||
|
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
let s = entry.get_location().to_str().unwrap_or(String::from(self.unknown_output));
|
let s = entry.get_location().to_str().unwrap_or(String::from(self.unknown_output));
|
||||||
try!(write!(stdout(), "{:?}\n", s).chain_err(|| LEK::FormatError))
|
write!(stdout(), "{:?}\n", s).chain_err(|| LEK::FormatError)?
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -47,14 +47,14 @@ impl Lister for PathLister {
|
||||||
|
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
let pb = entry.get_location().clone();
|
let pb = entry.get_location().clone();
|
||||||
let pb = try!(pb.into_pathbuf().chain_err(|| LEK::FormatError));
|
let pb = pb.into_pathbuf().chain_err(|| LEK::FormatError)?;
|
||||||
let pb = if self.absolute {
|
let pb = if self.absolute {
|
||||||
try!(pb.canonicalize().chain_err(|| LEK::FormatError))
|
pb.canonicalize().chain_err(|| LEK::FormatError)?
|
||||||
} else {
|
} else {
|
||||||
pb.into()
|
pb.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
try!(write!(stdout(), "{:?}\n", pb).chain_err(|| LEK::FormatError))
|
write!(stdout(), "{:?}\n", pb).chain_err(|| LEK::FormatError)?
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
hoedown = "6.0.0"
|
hoedown = "6.0.0"
|
||||||
|
|
|
@ -116,7 +116,7 @@ impl LinkProcessor {
|
||||||
let spath = Some(store.path().clone());
|
let spath = Some(store.path().clone());
|
||||||
let id = StoreId::new(spath, PathBuf::from(&link.link))?;
|
let id = StoreId::new(spath, PathBuf::from(&link.link))?;
|
||||||
let mut target = if self.create_internal_targets {
|
let mut target = if self.create_internal_targets {
|
||||||
try!(store.retrieve(id))
|
store.retrieve(id)?
|
||||||
} else {
|
} else {
|
||||||
store.get(id.clone())?
|
store.get(id.clone())?
|
||||||
.ok_or(ME::from_kind(MEK::StoreGetError(id)))?
|
.ok_or(ME::from_kind(MEK::StoreGetError(id)))?
|
||||||
|
@ -144,7 +144,7 @@ impl LinkProcessor {
|
||||||
trace!("URL.host_str() = {:?}", url.host_str());
|
trace!("URL.host_str() = {:?}", url.host_str());
|
||||||
let path = url.host_str().unwrap_or_else(|| url.path());
|
let path = url.host_str().unwrap_or_else(|| url.path());
|
||||||
let path = PathBuf::from(path);
|
let path = PathBuf::from(path);
|
||||||
let mut target = try!(RefStore::create(store, path, flags));
|
let mut target = RefStore::create(store, path, flags)?;
|
||||||
|
|
||||||
entry.add_internal_link(&mut target)?;
|
entry.add_internal_link(&mut target)?;
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
itertools = "0.7"
|
itertools = "0.7"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -49,8 +49,8 @@ impl RefFlags {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(RefFlags {
|
Ok(RefFlags {
|
||||||
content_hashing: try!(get_field(v, "ref.flags.content_hashing")),
|
content_hashing: get_field(v, "ref.flags.content_hashing")?,
|
||||||
permission_tracking: try!(get_field(v, "ref.flags.permission_tracking")),
|
permission_tracking: get_field(v, "ref.flags.permission_tracking")?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ impl Hasher for DefaultHasher {
|
||||||
|
|
||||||
fn create_hash<R: Read>(&mut self, _: &PathBuf, c: &mut R) -> Result<String> {
|
fn create_hash<R: Read>(&mut self, _: &PathBuf, c: &mut R) -> Result<String> {
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
try!(c.read_to_string(&mut s));
|
c.read_to_string(&mut s)?;
|
||||||
self.hasher.input_str(&s[..]);
|
self.hasher.input_str(&s[..]);
|
||||||
Ok(self.hasher.result_str())
|
Ok(self.hasher.result_str())
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,12 +51,12 @@ impl Hasher for NBytesHasher {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_hash<R: Read>(&mut self, _: &PathBuf, contents: &mut R) -> Result<String> {
|
fn create_hash<R: Read>(&mut self, _: &PathBuf, contents: &mut R) -> Result<String> {
|
||||||
let s : String = try!(contents
|
let s : String = contents
|
||||||
.bytes()
|
.bytes()
|
||||||
.take(self.n)
|
.take(self.n)
|
||||||
.collect::<RResult<Vec<u8>, _>>()
|
.collect::<RResult<Vec<u8>, _>>()
|
||||||
.map_err(From::from)
|
.map_err(From::from)
|
||||||
.and_then(|v| String::from_utf8(v).map_err(RE::from)));
|
.and_then(|v| String::from_utf8(v).map_err(RE::from))?;
|
||||||
|
|
||||||
self.hasher.input_str(&s[..]);
|
self.hasher.input_str(&s[..]);
|
||||||
Ok(self.hasher.result_str())
|
Ok(self.hasher.result_str())
|
||||||
|
|
|
@ -89,7 +89,7 @@ impl Lister for RefLister {
|
||||||
debug!("Listing Entry: {:?}", entry);
|
debug!("Listing Entry: {:?}", entry);
|
||||||
{
|
{
|
||||||
let is_dead = if self.check_dead {
|
let is_dead = if self.check_dead {
|
||||||
if try!(lerror::ResultExt::chain_err(entry.fs_link_exists(), || LEK::FormatError)) {
|
if lerror::ResultExt::chain_err(entry.fs_link_exists(), || LEK::FormatError)? {
|
||||||
"dead"
|
"dead"
|
||||||
} else {
|
} else {
|
||||||
"alive"
|
"alive"
|
||||||
|
|
|
@ -219,8 +219,8 @@ impl Ref for Entry {
|
||||||
|
|
||||||
/// Check whether the Hashsum of the referenced file is equal to the stored hashsum
|
/// Check whether the Hashsum of the referenced file is equal to the stored hashsum
|
||||||
fn fs_link_valid_hash(&self) -> Result<bool> {
|
fn fs_link_valid_hash(&self) -> Result<bool> {
|
||||||
let stored_hash = try!(self.get_stored_hash());
|
let stored_hash = self.get_stored_hash()?;
|
||||||
let current_hash = try!(self.get_current_hash());
|
let current_hash = self.get_current_hash()?;
|
||||||
Ok(stored_hash == current_hash)
|
Ok(stored_hash == current_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,18 +233,18 @@ impl Ref for Entry {
|
||||||
/// Update the Ref by re-checking the file from FS using the passed Hasher instance
|
/// Update the Ref by re-checking the file from FS using the passed Hasher instance
|
||||||
/// This errors if the file is not present or cannot be read()
|
/// This errors if the file is not present or cannot be read()
|
||||||
fn update_ref_with_hasher<H: Hasher>(&mut self, h: &H) -> Result<()> {
|
fn update_ref_with_hasher<H: Hasher>(&mut self, h: &H) -> Result<()> {
|
||||||
let current_hash = try!(self.get_current_hash()); // uses the default hasher
|
let current_hash = self.get_current_hash()?; // uses the default hasher
|
||||||
let current_perm = try!(self.get_current_permissions());
|
let current_perm = self.get_current_permissions()?;
|
||||||
|
|
||||||
try!(self
|
self
|
||||||
.get_header_mut()
|
.get_header_mut()
|
||||||
.set("ref.permissions.ro", Value::Boolean(current_perm.readonly()))
|
.set("ref.permissions.ro", Value::Boolean(current_perm.readonly()))
|
||||||
);
|
?;
|
||||||
|
|
||||||
try!(self
|
self
|
||||||
.get_header_mut()
|
.get_header_mut()
|
||||||
.set(&format!("ref.content_hash.{}", h.hash_name())[..], Value::String(current_hash))
|
.set(&format!("ref.content_hash.{}", h.hash_name())[..], Value::String(current_hash))
|
||||||
);
|
?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,10 +91,10 @@ impl RefStore for Store {
|
||||||
// manually here. If you can come up with a better version of this, feel free to
|
// manually here. If you can come up with a better version of this, feel free to
|
||||||
// take this note as a todo.
|
// take this note as a todo.
|
||||||
for r in possible_refs {
|
for r in possible_refs {
|
||||||
let contains_hash = try!(r.to_str()
|
let contains_hash = r.to_str()
|
||||||
.chain_err(|| REK::TypeConversionError)
|
.chain_err(|| REK::TypeConversionError)
|
||||||
.map(|s| s.contains(&hash[..]))
|
.map(|s| s.contains(&hash[..]))
|
||||||
);
|
?;
|
||||||
|
|
||||||
if !contains_hash {
|
if !contains_hash {
|
||||||
continue;
|
continue;
|
||||||
|
@ -182,14 +182,14 @@ impl RefStore for Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
let (mut fle, content_hash, permissions, canonical_path) = { // scope to be able to fold
|
let (mut fle, content_hash, permissions, canonical_path) = { // scope to be able to fold
|
||||||
try!(File::open(pb.clone())
|
File::open(pb.clone())
|
||||||
.chain_err(|| REK::RefTargetFileCannotBeOpened)
|
.chain_err(|| REK::RefTargetFileCannotBeOpened)
|
||||||
|
|
||||||
// If we were able to open this file,
|
// If we were able to open this file,
|
||||||
// we hash the contents of the file and return (file, hash)
|
// we hash the contents of the file and return (file, hash)
|
||||||
.and_then(|mut file| {
|
.and_then(|mut file| {
|
||||||
let opt_contenthash = if flags.get_content_hashing() {
|
let opt_contenthash = if flags.get_content_hashing() {
|
||||||
Some(try!(h.create_hash(&pb, &mut file)))
|
Some(h.create_hash(&pb, &mut file)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -201,11 +201,9 @@ impl RefStore for Store {
|
||||||
// and return (file, content hash, permissions)
|
// and return (file, content hash, permissions)
|
||||||
.and_then(|(file, opt_contenthash)| {
|
.and_then(|(file, opt_contenthash)| {
|
||||||
let opt_permissions = if flags.get_permission_tracking() {
|
let opt_permissions = if flags.get_permission_tracking() {
|
||||||
Some(try!(file
|
Some(file.metadata()
|
||||||
.metadata()
|
.map(|md| md.permissions())
|
||||||
.map(|md| md.permissions())
|
.chain_err(|| REK::RefTargetCannotReadPermissions)?)
|
||||||
.chain_err(|| REK::RefTargetCannotReadPermissions)
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -226,7 +224,7 @@ impl RefStore for Store {
|
||||||
// and then we hash the canonicalized path
|
// and then we hash the canonicalized path
|
||||||
// and return (file, content hash, permissions, canonicalized path, path hash)
|
// and return (file, content hash, permissions, canonicalized path, path hash)
|
||||||
.and_then(|(opt_contenthash, opt_permissions, can)| {
|
.and_then(|(opt_contenthash, opt_permissions, can)| {
|
||||||
let path_hash = try!(hash_path(&can).chain_err(|| REK::PathHashingError));
|
let path_hash = hash_path(&can).chain_err(|| REK::PathHashingError)?;
|
||||||
|
|
||||||
Ok((opt_contenthash, opt_permissions, can, path_hash))
|
Ok((opt_contenthash, opt_permissions, can, path_hash))
|
||||||
})
|
})
|
||||||
|
@ -246,10 +244,9 @@ impl RefStore for Store {
|
||||||
// and then we create the FileLockEntry in the Store
|
// and then we create the FileLockEntry in the Store
|
||||||
// and return (filelockentry, content hash, permissions, canonicalized path)
|
// and return (filelockentry, content hash, permissions, canonicalized path)
|
||||||
.and_then(|(opt_conhash, opt_perm, can, path_hash)| {
|
.and_then(|(opt_conhash, opt_perm, can, path_hash)| {
|
||||||
let fle = try!(self.create(ModuleEntryPath::new(path_hash)));
|
let fle = self.create(ModuleEntryPath::new(path_hash))?;
|
||||||
Ok((fle, opt_conhash, opt_perm, can))
|
Ok((fle, opt_conhash, opt_perm, can))
|
||||||
})
|
})?
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for tpl in [
|
for tpl in [
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub trait Tagable {
|
||||||
impl Tagable for Value {
|
impl Tagable for Value {
|
||||||
|
|
||||||
fn get_tags(&self) -> Result<Vec<Tag>> {
|
fn get_tags(&self) -> Result<Vec<Tag>> {
|
||||||
let tags = try!(self.read("tag.values").chain_err(|| TagErrorKind::HeaderReadError));
|
let tags = self.read("tag.values").chain_err(|| TagErrorKind::HeaderReadError)?;
|
||||||
|
|
||||||
match tags {
|
match tags {
|
||||||
Some(&Value::Array(ref tags)) => {
|
Some(&Value::Array(ref tags)) => {
|
||||||
|
@ -92,7 +92,7 @@ impl Tagable for Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_tag(&mut self, t: Tag) -> Result<()> {
|
fn add_tag(&mut self, t: Tag) -> Result<()> {
|
||||||
if !try!(is_tag_str(&t).map(|_| true).map_err(|_| TE::from_kind(TagErrorKind::NotATag))) {
|
if !is_tag_str(&t).map(|_| true).map_err(|_| TE::from_kind(TagErrorKind::NotATag))? {
|
||||||
debug!("Not a tag: '{}'", t);
|
debug!("Not a tag: '{}'", t);
|
||||||
return Err(TagErrorKind::NotATag.into());
|
return Err(TagErrorKind::NotATag.into());
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ impl Tagable for Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_tag(&mut self, t: Tag) -> Result<()> {
|
fn remove_tag(&mut self, t: Tag) -> Result<()> {
|
||||||
if !try!(is_tag_str(&t).map(|_| true).map_err(|_| TE::from_kind(TagErrorKind::NotATag))) {
|
if !is_tag_str(&t).map(|_| true).map_err(|_| TE::from_kind(TagErrorKind::NotATag))? {
|
||||||
debug!("Not a tag: '{}'", t);
|
debug!("Not a tag: '{}'", t);
|
||||||
return Err(TagErrorKind::NotATag.into());
|
return Err(TagErrorKind::NotATag.into());
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ impl Tagable for Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_tag(&self, t: TagSlice) -> Result<bool> {
|
fn has_tag(&self, t: TagSlice) -> Result<bool> {
|
||||||
let tags = try!(self.read("tag.values").chain_err(|| TagErrorKind::HeaderReadError));
|
let tags = self.read("tag.values").chain_err(|| TagErrorKind::HeaderReadError)?;
|
||||||
|
|
||||||
if !tags.iter().all(|t| is_match!(*t, &Value::String(_))) {
|
if !tags.iter().all(|t| is_match!(*t, &Value::String(_))) {
|
||||||
return Err(TagErrorKind::TagTypeError.into());
|
return Err(TagErrorKind::TagTypeError.into());
|
||||||
|
@ -140,7 +140,7 @@ impl Tagable for Value {
|
||||||
fn has_tags(&self, tags: &[Tag]) -> Result<bool> {
|
fn has_tags(&self, tags: &[Tag]) -> Result<bool> {
|
||||||
let mut result = true;
|
let mut result = true;
|
||||||
for tag in tags {
|
for tag in tags {
|
||||||
result = result && try!(self.has_tag(tag));
|
result = result && self.has_tag(tag)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
toml = "0.4"
|
toml = "0.4"
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ansi_term = "0.10"
|
ansi_term = "0.10"
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
|
|
|
@ -95,9 +95,9 @@ impl HelperDef for ColorizeYellowHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn colorize(color: Colour, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
fn colorize(color: Colour, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
||||||
let p = try!(h.param(0).ok_or(RenderError::new("Too few arguments")));
|
let p = h.param(0).ok_or(RenderError::new("Too few arguments"))?;
|
||||||
|
|
||||||
try!(write!(rc.writer(), "{}", color.paint(p.value().render())));
|
write!(rc.writer(), "{}", color.paint(p.value().render()))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,9 +107,9 @@ pub struct UnderlineHelper;
|
||||||
impl HelperDef for UnderlineHelper {
|
impl HelperDef for UnderlineHelper {
|
||||||
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(),
|
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(),
|
||||||
RenderError> {
|
RenderError> {
|
||||||
let p = try!(h.param(0).ok_or(RenderError::new("Too few arguments")));
|
let p = h.param(0).ok_or(RenderError::new("Too few arguments"))?;
|
||||||
let s = Style::new().underline();
|
let s = Style::new().underline();
|
||||||
try!(write!(rc.writer(), "{}", s.paint(p.value().render())));
|
write!(rc.writer(), "{}", s.paint(p.value().render()))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,9 +120,9 @@ pub struct BoldHelper;
|
||||||
impl HelperDef for BoldHelper {
|
impl HelperDef for BoldHelper {
|
||||||
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(),
|
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(),
|
||||||
RenderError> {
|
RenderError> {
|
||||||
let p = try!(h.param(0).ok_or(RenderError::new("Too few arguments")));
|
let p = h.param(0).ok_or(RenderError::new("Too few arguments"))?;
|
||||||
let s = Style::new().bold();
|
let s = Style::new().bold();
|
||||||
try!(write!(rc.writer(), "{}", s.paint(p.value().render())));
|
write!(rc.writer(), "{}", s.paint(p.value().render()))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,9 +133,9 @@ pub struct BlinkHelper;
|
||||||
impl HelperDef for BlinkHelper {
|
impl HelperDef for BlinkHelper {
|
||||||
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(),
|
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(),
|
||||||
RenderError> {
|
RenderError> {
|
||||||
let p = try!(h.param(0).ok_or(RenderError::new("Too few arguments")));
|
let p = h.param(0).ok_or(RenderError::new("Too few arguments"))?;
|
||||||
let s = Style::new().blink();
|
let s = Style::new().blink();
|
||||||
try!(write!(rc.writer(), "{}", s.paint(p.value().render())));
|
write!(rc.writer(), "{}", s.paint(p.value().render()))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,15 +146,15 @@ pub struct StrikethroughHelper;
|
||||||
impl HelperDef for StrikethroughHelper {
|
impl HelperDef for StrikethroughHelper {
|
||||||
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(),
|
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(),
|
||||||
RenderError> {
|
RenderError> {
|
||||||
let p = try!(h.param(0).ok_or(RenderError::new("Too few arguments")));
|
let p = h.param(0).ok_or(RenderError::new("Too few arguments"))?;
|
||||||
let s = Style::new().strikethrough();
|
let s = Style::new().strikethrough();
|
||||||
try!(write!(rc.writer(), "{}", s.paint(p.value().render())));
|
write!(rc.writer(), "{}", s.paint(p.value().render()))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn param_to_number(idx: usize, h: &Helper) -> Result<u64, RenderError> {
|
fn param_to_number(idx: usize, h: &Helper) -> Result<u64, RenderError> {
|
||||||
match try!(h.param(idx).ok_or(RenderError::new("Too few arguments"))).value() {
|
match h.param(idx).ok_or(RenderError::new("Too few arguments"))?.value() {
|
||||||
&Value::Number(ref num) => num.as_u64().ok_or_else(|| RenderError::new("Number cannot be parsed")),
|
&Value::Number(ref num) => num.as_u64().ok_or_else(|| RenderError::new("Number cannot be parsed")),
|
||||||
_ => Err(RenderError::new("Type error: First argument should be a number")),
|
_ => Err(RenderError::new("Type error: First argument should be a number")),
|
||||||
}
|
}
|
||||||
|
@ -166,9 +166,9 @@ pub struct LeftPadHelper;
|
||||||
impl HelperDef for LeftPadHelper {
|
impl HelperDef for LeftPadHelper {
|
||||||
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
||||||
let count = param_to_number(0, h)? as usize;
|
let count = param_to_number(0, h)? as usize;
|
||||||
let text = try!(h.param(1).ok_or(RenderError::new("Too few arguments")));
|
let text = h.param(1).ok_or(RenderError::new("Too few arguments"))?;
|
||||||
let text = format!("{:>width$}", text.value().render(), width = count);
|
let text = format!("{:>width$}", text.value().render(), width = count);
|
||||||
try!(write!(rc.writer(), "{}", text));
|
write!(rc.writer(), "{}", text)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,9 +179,9 @@ pub struct RightPadHelper;
|
||||||
impl HelperDef for RightPadHelper {
|
impl HelperDef for RightPadHelper {
|
||||||
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
||||||
let count = param_to_number(0, h)? as usize;
|
let count = param_to_number(0, h)? as usize;
|
||||||
let text = try!(h.param(1).ok_or(RenderError::new("Too few arguments")));
|
let text = h.param(1).ok_or(RenderError::new("Too few arguments"))?;
|
||||||
let text = format!("{:width$}", text.value().render(), width = count);
|
let text = format!("{:width$}", text.value().render(), width = count);
|
||||||
try!(write!(rc.writer(), "{}", text));
|
write!(rc.writer(), "{}", text)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,8 +192,8 @@ pub struct AbbrevHelper;
|
||||||
impl HelperDef for AbbrevHelper {
|
impl HelperDef for AbbrevHelper {
|
||||||
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
||||||
let count = param_to_number(0, h)? as usize;
|
let count = param_to_number(0, h)? as usize;
|
||||||
let text = try!(h.param(1).ok_or(RenderError::new("Too few arguments"))).value().render();
|
let text = h.param(1).ok_or(RenderError::new("Too few arguments"))?.value().render();
|
||||||
try!(write!(rc.writer(), "{}", text.chars().take(count).collect::<String>()));
|
write!(rc.writer(), "{}", text.chars().take(count).collect::<String>())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,48 +34,48 @@ pub struct Readline {
|
||||||
impl Readline {
|
impl Readline {
|
||||||
|
|
||||||
pub fn new(rt: &Runtime) -> Result<Readline> {
|
pub fn new(rt: &Runtime) -> Result<Readline> {
|
||||||
let c = try!(rt.config().ok_or(IEK::NoConfigError));
|
let c = rt.config().ok_or(IEK::NoConfigError)?;
|
||||||
|
|
||||||
let histfile = try!(c.lookup("ui.cli.readline_history_file").ok_or(IEK::ConfigError));
|
let histfile = c.lookup("ui.cli.readline_history_file").ok_or(IEK::ConfigError)?;
|
||||||
let histsize = try!(c.lookup("ui.cli.readline_history_size").ok_or(IEK::ConfigError));
|
let histsize = c.lookup("ui.cli.readline_history_size").ok_or(IEK::ConfigError)?;
|
||||||
let histigndups = try!(c.lookup("ui.cli.readline_history_ignore_dups").ok_or(IEK::ConfigError));
|
let histigndups = c.lookup("ui.cli.readline_history_ignore_dups").ok_or(IEK::ConfigError)?;
|
||||||
let histignspace = try!(c.lookup("ui.cli.readline_history_ignore_space").ok_or(IEK::ConfigError));
|
let histignspace = c.lookup("ui.cli.readline_history_ignore_space").ok_or(IEK::ConfigError)?;
|
||||||
let prompt = try!(c.lookup("ui.cli.readline_prompt").ok_or(IEK::ConfigError));
|
let prompt = c.lookup("ui.cli.readline_prompt").ok_or(IEK::ConfigError)?;
|
||||||
|
|
||||||
let histfile = try!(match histfile {
|
let histfile = match histfile {
|
||||||
Value::String(s) => PathBuf::from(s),
|
Value::String(s) => PathBuf::from(s),
|
||||||
_ => Err(IE::from_kind(IEK::ConfigTypeError))
|
_ => Err(IE::from_kind(IEK::ConfigTypeError))
|
||||||
.chain_err(|| IEK::ConfigError)
|
.chain_err(|| IEK::ConfigError)
|
||||||
.chain_err(|| IEK::ReadlineError)
|
.chain_err(|| IEK::ReadlineError)
|
||||||
});
|
}?;
|
||||||
|
|
||||||
let histsize = try!(match histsize {
|
let histsize = match histsize {
|
||||||
Value::Integer(i) => i,
|
Value::Integer(i) => i,
|
||||||
_ => Err(IE::from_kind(IEK::ConfigTypeError))
|
_ => Err(IE::from_kind(IEK::ConfigTypeError))
|
||||||
.chain_err(|| IEK::ConfigError)
|
.chain_err(|| IEK::ConfigError)
|
||||||
.chain_err(|| IEK::ReadlineError)
|
.chain_err(|| IEK::ReadlineError)
|
||||||
});
|
}?;
|
||||||
|
|
||||||
let histigndups = try!(match histigndups {
|
let histigndups = match histigndups {
|
||||||
Value::Boolean(b) => b,
|
Value::Boolean(b) => b,
|
||||||
_ => Err(IE::from_kind(IEK::ConfigTypeError))
|
_ => Err(IE::from_kind(IEK::ConfigTypeError))
|
||||||
.chain_err(|| IEK::ConfigError)
|
.chain_err(|| IEK::ConfigError)
|
||||||
.chain_err(|| IEK::ReadlineError)
|
.chain_err(|| IEK::ReadlineError)
|
||||||
});
|
}?;
|
||||||
|
|
||||||
let histignspace = try!(match histignspace {
|
let histignspace = match histignspace {
|
||||||
Value::Boolean(b) => b,
|
Value::Boolean(b) => b,
|
||||||
_ => Err(IE::from_kind(IEK::ConfigTypeError))
|
_ => Err(IE::from_kind(IEK::ConfigTypeError))
|
||||||
.chain_err(|| IEK::ConfigError)
|
.chain_err(|| IEK::ConfigError)
|
||||||
.chain_err(|| IEK::ReadlineError)
|
.chain_err(|| IEK::ReadlineError)
|
||||||
});
|
}?;
|
||||||
|
|
||||||
let prompt = try!(match prompt {
|
let prompt = match prompt {
|
||||||
Value::String(s) => s,
|
Value::String(s) => s,
|
||||||
_ => Err(IE::from_kind(IEK::ConfigTypeError))
|
_ => Err(IE::from_kind(IEK::ConfigTypeError))
|
||||||
.chain_err(|| IEK::ConfigError)
|
.chain_err(|| IEK::ConfigError)
|
||||||
.chain_err(|| IEK::ReadlineError)
|
.chain_err(|| IEK::ReadlineError)
|
||||||
});
|
}?;
|
||||||
|
|
||||||
let config = Config::builder().
|
let config = Config::builder().
|
||||||
.max_history_size(histsize)
|
.max_history_size(histsize)
|
||||||
|
@ -86,11 +86,11 @@ impl Readline {
|
||||||
let mut editor = Editor::new(config);
|
let mut editor = Editor::new(config);
|
||||||
|
|
||||||
if !histfile.exists() {
|
if !histfile.exists() {
|
||||||
let _ = try!(File::create(histfile.clone())
|
let _ = File::create(histfile.clone())
|
||||||
.chain_err(|| IEK::ReadlineHistoryFileCreationError));
|
.chain_err(|| IEK::ReadlineHistoryFileCreationError)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = try!(editor.load_history(&histfile).chain_err(|| ReadlineError));
|
let _ = editor.load_history(&histfile).chain_err(|| ReadlineError)?;
|
||||||
|
|
||||||
Ok(Readline {
|
Ok(Readline {
|
||||||
editor: editor,
|
editor: editor,
|
||||||
|
|
|
@ -59,7 +59,7 @@ pub fn get_id(matches: &ArgMatches) -> Result<Vec<StoreId>> {
|
||||||
.fold(Ok(vec![]), |acc, elem| {
|
.fold(Ok(vec![]), |acc, elem| {
|
||||||
acc.and_then(|mut v| {
|
acc.and_then(|mut v| {
|
||||||
let elem = StoreId::new_baseless(PathBuf::from(String::from(elem)));
|
let elem = StoreId::new_baseless(PathBuf::from(String::from(elem)));
|
||||||
let elem = try!(elem.chain_err(|| IEK::StoreIdParsingError));
|
let elem = elem.chain_err(|| IEK::StoreIdParsingError)?;
|
||||||
v.push(elem);
|
v.push(elem);
|
||||||
Ok(v)
|
Ok(v)
|
||||||
})
|
})
|
||||||
|
@ -74,8 +74,8 @@ pub fn get_or_select_id(matches: &ArgMatches, store_path: &PathBuf) -> Result<Ve
|
||||||
Ok(v) => Ok(v),
|
Ok(v) => Ok(v),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let path = store_path.clone();
|
let path = store_path.clone();
|
||||||
let p = try!(pick_file(default_menu_cmd, path).chain_err(|| IEK::IdSelectingError));
|
let p = pick_file(default_menu_cmd, path).chain_err(|| IEK::IdSelectingError)?;
|
||||||
let id = try!(StoreId::new_baseless(p).chain_err(|| IEK::StoreIdParsingError));
|
let id = StoreId::new_baseless(p).chain_err(|| IEK::StoreIdParsingError)?;
|
||||||
Ok(vec![id])
|
Ok(vec![id])
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,12 @@ documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.h
|
||||||
repository = "https://github.com/matthiasbeyer/imag"
|
repository = "https://github.com/matthiasbeyer/imag"
|
||||||
homepage = "http://imag-pim.org"
|
homepage = "http://imag-pim.org"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = ">=2.17"
|
clap = ">=2.17"
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
|
|
|
@ -19,6 +19,12 @@ default = []
|
||||||
# Testing feature to compile testing utilities into the library.
|
# Testing feature to compile testing utilities into the library.
|
||||||
testing = []
|
testing = []
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
|
||||||
|
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
|
||||||
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
url = "1.5"
|
url = "1.5"
|
||||||
boolinator = "2.4.0"
|
boolinator = "2.4.0"
|
||||||
|
|
|
@ -27,11 +27,11 @@ use std::io::Error as IOError;
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
pub fn edit_in_tmpfile_with_command(mut cmd: Command, s: &mut String) -> Result<bool, IOError> {
|
pub fn edit_in_tmpfile_with_command(mut cmd: Command, s: &mut String) -> Result<bool, IOError> {
|
||||||
let mut file = &try!(NamedTempFile::new());
|
let mut file = &NamedTempFile::new()?;
|
||||||
let file_path = file.path();
|
let file_path = file.path();
|
||||||
|
|
||||||
try!(file.write_all(&s.clone().into_bytes()[..]));
|
file.write_all(&s.clone().into_bytes()[..])?;
|
||||||
try!(file.sync_data());
|
file.sync_data()?;
|
||||||
|
|
||||||
cmd.arg(file_path)
|
cmd.arg(file_path)
|
||||||
.status()
|
.status()
|
||||||
|
|
Loading…
Reference in a new issue