From 53aaf451be3bf39c4a38d0c8178934dd5f79288e Mon Sep 17 00:00:00 2001 From: mario Date: Wed, 20 Apr 2016 19:23:35 +0200 Subject: [PATCH 01/98] Initial: create imag-task/libimagtask directory --- imag-task/Cargo.toml | 6 ++++++ imag-task/src/main.rs | 3 +++ libimagtask/Cargo.toml | 6 ++++++ libimagtask/src/lib.rs | 6 ++++++ 4 files changed, 21 insertions(+) create mode 100644 imag-task/Cargo.toml create mode 100644 imag-task/src/main.rs create mode 100644 libimagtask/Cargo.toml create mode 100644 libimagtask/src/lib.rs diff --git a/imag-task/Cargo.toml b/imag-task/Cargo.toml new file mode 100644 index 00000000..22ef8bcf --- /dev/null +++ b/imag-task/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "imag-task" +version = "0.1.0" +authors = ["mario "] + +[dependencies] diff --git a/imag-task/src/main.rs b/imag-task/src/main.rs new file mode 100644 index 00000000..e7a11a96 --- /dev/null +++ b/imag-task/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/libimagtask/Cargo.toml b/libimagtask/Cargo.toml new file mode 100644 index 00000000..27c2bb15 --- /dev/null +++ b/libimagtask/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "libimagtask" +version = "0.1.0" +authors = ["mario "] + +[dependencies] diff --git a/libimagtask/src/lib.rs b/libimagtask/src/lib.rs new file mode 100644 index 00000000..cdfbe1aa --- /dev/null +++ b/libimagtask/src/lib.rs @@ -0,0 +1,6 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + } +} From 89ec7df348449ffc420c934c51044f592298b292 Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 3 May 2016 17:37:53 +0200 Subject: [PATCH 02/98] Renamed imag-task to imag-todo, libimagtask to libimagtodo --- {imag-task => imag-todo}/Cargo.toml | 2 +- {imag-task => imag-todo}/src/main.rs | 0 {libimagtask => libimagtodo}/Cargo.toml | 2 +- {libimagtask => libimagtodo}/src/lib.rs | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename {imag-task => imag-todo}/Cargo.toml (81%) rename {imag-task => imag-todo}/src/main.rs (100%) rename {libimagtask => libimagtodo}/Cargo.toml (80%) rename {libimagtask => libimagtodo}/src/lib.rs (100%) diff --git a/imag-task/Cargo.toml b/imag-todo/Cargo.toml similarity index 81% rename from imag-task/Cargo.toml rename to imag-todo/Cargo.toml index 22ef8bcf..fb21e2e6 100644 --- a/imag-task/Cargo.toml +++ b/imag-todo/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "imag-task" +name = "imag-todo" version = "0.1.0" authors = ["mario "] diff --git a/imag-task/src/main.rs b/imag-todo/src/main.rs similarity index 100% rename from imag-task/src/main.rs rename to imag-todo/src/main.rs diff --git a/libimagtask/Cargo.toml b/libimagtodo/Cargo.toml similarity index 80% rename from libimagtask/Cargo.toml rename to libimagtodo/Cargo.toml index 27c2bb15..f5394127 100644 --- a/libimagtask/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "libimagtask" +name = "libimagtodo" version = "0.1.0" authors = ["mario "] diff --git a/libimagtask/src/lib.rs b/libimagtodo/src/lib.rs similarity index 100% rename from libimagtask/src/lib.rs rename to libimagtodo/src/lib.rs From 07b7936c0294b9c9966a597a8accc1c241063cde Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 3 May 2016 18:03:34 +0200 Subject: [PATCH 03/98] added dependency task-hookrs --- libimagtodo/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index f5394127..e1621658 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" authors = ["mario "] [dependencies] +task-hookrs = { git = "https://github.com/matthiasbeyer/task-hookrs.git" } From 02c26132448a08b46d1675f398b92247b69169b9 Mon Sep 17 00:00:00 2001 From: mario Date: Wed, 4 May 2016 13:47:39 +0200 Subject: [PATCH 04/98] created files --- libimagtodo/src/add.rs | 0 libimagtodo/src/delete.rs | 0 libimagtodo/src/lib.rs | 2 ++ libimagtodo/src/read.rs | 0 libimagtodo/src/set.rs | 0 libimagtodo/src/task.rs | 7 +++++++ 6 files changed, 9 insertions(+) create mode 100644 libimagtodo/src/add.rs create mode 100644 libimagtodo/src/delete.rs create mode 100644 libimagtodo/src/read.rs create mode 100644 libimagtodo/src/set.rs create mode 100644 libimagtodo/src/task.rs diff --git a/libimagtodo/src/add.rs b/libimagtodo/src/add.rs new file mode 100644 index 00000000..e69de29b diff --git a/libimagtodo/src/delete.rs b/libimagtodo/src/delete.rs new file mode 100644 index 00000000..e69de29b diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index cdfbe1aa..24f3f92b 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -1,3 +1,5 @@ +pub mod task; + #[cfg(test)] mod tests { #[test] diff --git a/libimagtodo/src/read.rs b/libimagtodo/src/read.rs new file mode 100644 index 00000000..e69de29b diff --git a/libimagtodo/src/set.rs b/libimagtodo/src/set.rs new file mode 100644 index 00000000..e69de29b diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs new file mode 100644 index 00000000..a195520a --- /dev/null +++ b/libimagtodo/src/task.rs @@ -0,0 +1,7 @@ +extern crate task-hookrs + +use task-hookrs::task::Task as TTask + +pub struct Task { + uuid : str, +}; From ff500d7d44794249da66dedabc23dae41c842b88 Mon Sep 17 00:00:00 2001 From: mario Date: Wed, 4 May 2016 13:54:34 +0200 Subject: [PATCH 05/98] struct skeleton --- libimagtodo/src/task.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index a195520a..a6eec643 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -1,7 +1,8 @@ -extern crate task-hookrs +extern crate task_hookrs; -use task-hookrs::task::Task as TTask +use self::task_hookrs::task::Task as TTask; pub struct Task { uuid : str, -}; +} + From 2129ab2a49835d98ca4a2b8579e12c81e474c37e Mon Sep 17 00:00:00 2001 From: mario Date: Wed, 4 May 2016 14:12:14 +0200 Subject: [PATCH 06/98] added modules to lib.rs --- libimagtodo/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index 24f3f92b..59b0070f 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -1,4 +1,8 @@ pub mod task; +pub mod delete; +pub mod read; +pub mod set; +pub mod add; #[cfg(test)] mod tests { From efd72d65a11112bbe8182a27ad8ba7d1ee0bbc84 Mon Sep 17 00:00:00 2001 From: mario Date: Wed, 4 May 2016 14:37:25 +0200 Subject: [PATCH 07/98] added dependency to libimagstore --- libimagtodo/Cargo.toml | 4 ++++ libimagtodo/src/lib.rs | 6 ++++++ libimagtodo/src/task.rs | 9 +++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index e1621658..afc6c4f9 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -5,3 +5,7 @@ authors = ["mario "] [dependencies] task-hookrs = { git = "https://github.com/matthiasbeyer/task-hookrs.git" } + +[dependencies.libimagstore] +path = "../libimagstore" + diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index 59b0070f..4149a420 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -1,3 +1,9 @@ + +extern crate task_hookrs; +#[macro_use] extern crate libimagstore; + +module_entry_path_mod!("todo", "0.1.0"); + pub mod task; pub mod delete; pub mod read; diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index a6eec643..0dfa9c6f 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -1,8 +1,13 @@ -extern crate task_hookrs; +use std::ops::Deref; -use self::task_hookrs::task::Task as TTask; +use task_hookrs::task::Task as TTask; + +use libimagstore::store::FileLockEntry; pub struct Task { uuid : str, } +impl Deref for Task { + +} From 0f77c9d3d88724dbe5949bfc3c9d8e37c0009bd6 Mon Sep 17 00:00:00 2001 From: mario Date: Wed, 4 May 2016 15:00:48 +0200 Subject: [PATCH 08/98] experiment with Store/FileLockEntry --- libimagtodo/Cargo.toml | 1 + libimagtodo/src/lib.rs | 1 + libimagtodo/src/task.rs | 15 +++++++++++---- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index afc6c4f9..07059ac9 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" authors = ["mario "] [dependencies] +semver = "0.2" task-hookrs = { git = "https://github.com/matthiasbeyer/task-hookrs.git" } [dependencies.libimagstore] diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index 4149a420..fdd29389 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -1,3 +1,4 @@ +extern crate semver; extern crate task_hookrs; #[macro_use] extern crate libimagstore; diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 0dfa9c6f..5ff6bc5b 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -4,10 +4,17 @@ use task_hookrs::task::Task as TTask; use libimagstore::store::FileLockEntry; -pub struct Task { - uuid : str, +#[derive(Debug)] +pub struct Task<'a> { + flentry : FileLockEntry<'a>, } -impl Deref for Task { - +impl<'a> From for Task<'a> { + fn from(ttask : TTask) -> Task<'a> { + Task { + flentry : { + } + } + } } + From df6f41942be3e525c1578bad1a90fc8fbf17a802 Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Sun, 8 May 2016 10:59:21 +0200 Subject: [PATCH 09/98] added uuid crate and type --- libimagtodo/Cargo.toml | 1 + libimagtodo/src/lib.rs | 1 + libimagtodo/src/task.rs | 2 ++ 3 files changed, 4 insertions(+) diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index 07059ac9..9cdc711c 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -6,6 +6,7 @@ authors = ["mario "] [dependencies] semver = "0.2" task-hookrs = { git = "https://github.com/matthiasbeyer/task-hookrs.git" } +uuid = "0.2.0" [dependencies.libimagstore] path = "../libimagstore" diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index fdd29389..9913f7b4 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -1,4 +1,5 @@ extern crate semver; +extern crate uuid; extern crate task_hookrs; #[macro_use] extern crate libimagstore; diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 5ff6bc5b..41f71cee 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -1,5 +1,6 @@ use std::ops::Deref; +use uuid::Uuid; use task_hookrs::task::Task as TTask; use libimagstore::store::FileLockEntry; @@ -7,6 +8,7 @@ use libimagstore::store::FileLockEntry; #[derive(Debug)] pub struct Task<'a> { flentry : FileLockEntry<'a>, + uuid : Uuid, } impl<'a> From for Task<'a> { From 26ec9710ccd27fd5f29c2ff8917b881ea32ed655 Mon Sep 17 00:00:00 2001 From: mario Date: Mon, 9 May 2016 12:11:13 +0200 Subject: [PATCH 10/98] introduce ConversionError in error.rs and add trait for task_hookrs::task::Task to convert it to a libimagtodo::task::Task --- libimagtodo/src/error.rs | 60 ++++++++++++++++++++++++++++++++++++++++ libimagtodo/src/lib.rs | 1 + libimagtodo/src/task.rs | 17 ++++++++++-- 3 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 libimagtodo/src/error.rs diff --git a/libimagtodo/src/error.rs b/libimagtodo/src/error.rs new file mode 100644 index 00000000..4dafc389 --- /dev/null +++ b/libimagtodo/src/error.rs @@ -0,0 +1,60 @@ +use std::error::Error; +use std::clone::Clone; +use std::fmt::Error as FmtError; +use std::fmt::{Debug, Display, Formatter}; +use std::fmt; + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum TodoErrorKind { + ConversionError, +} + +fn todo_error_type_as_str(e: &TodoErrorKind) -> &'static str { + match e { + &TodoErrorKind::ConversionError => "Conversion Error", + } +} + +impl Display for TodoErrorKind { + fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> { + try!(write!(fmt, "{}", todo_error_type_as_str(self))); + Ok(()) + } +} + +#[derive(Debug)] +pub struct TodoError { + err_type : TodoErrorKind, + cause : Option>, +} + +impl TodoError { + pub fn new(errtype : TodoErrorKind, cause : Option>) -> TodoError { + TodoError { + err_type : errtype, + cause : cause, + } + } + pub fn err_type(&self) -> TodoErrorKind { + self.err_type.clone() + } +} + +impl Display for TodoError { + fn fmt(&self, fmt : &mut Formatter) -> Result<(), FmtError> { + try!(write!(fmt, "[{}]", todo_error_type_as_str(&self.err_type.clone()))); + Ok(()) + } +} + +impl Error for TodoError { + fn description(&self) -> &str { + todo_error_type_as_str(&self.err_type.clone()) + } + fn cause(&self) -> Option<&Error> { + self.cause.as_ref().map(|e| &**e) + } +} + + + diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index 9913f7b4..f1eaf3a3 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -6,6 +6,7 @@ extern crate task_hookrs; module_entry_path_mod!("todo", "0.1.0"); +pub mod error; pub mod task; pub mod delete; pub mod read; diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 41f71cee..66517528 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -5,12 +5,18 @@ use task_hookrs::task::Task as TTask; use libimagstore::store::FileLockEntry; +use error::{TodoError, TodoErrorKind}; + +pub trait IntoTask<'a> { + fn into_filelockentry(self) -> Result, TodoError>; +} + #[derive(Debug)] pub struct Task<'a> { flentry : FileLockEntry<'a>, - uuid : Uuid, + //uuid : Uuid, } - +/* impl<'a> From for Task<'a> { fn from(ttask : TTask) -> Task<'a> { Task { @@ -19,4 +25,9 @@ impl<'a> From for Task<'a> { } } } - +*/ +impl<'a> IntoTask<'a> for TTask { + fn into_filelockentry(self) -> Result, TodoError> { + Err(TodoError::new(TodoErrorKind::ConversionError, None)) + } +} From 2f999caeef95d0aab38645cd986eda15929830f0 Mon Sep 17 00:00:00 2001 From: mario Date: Mon, 9 May 2016 17:22:40 +0200 Subject: [PATCH 11/98] implement the task struct, trait for task_hookrs::task::Task, and some minor error handling --- libimagtodo/Cargo.toml | 2 +- libimagtodo/src/error.rs | 13 ++++++--- libimagtodo/src/lib.rs | 1 + libimagtodo/src/task.rs | 58 +++++++++++++++++++++++++++++----------- 4 files changed, 55 insertions(+), 19 deletions(-) diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index 9cdc711c..dc1f6d8b 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -7,7 +7,7 @@ authors = ["mario "] semver = "0.2" task-hookrs = { git = "https://github.com/matthiasbeyer/task-hookrs.git" } uuid = "0.2.0" +toml = "0.1.28" [dependencies.libimagstore] path = "../libimagstore" - diff --git a/libimagtodo/src/error.rs b/libimagtodo/src/error.rs index 4dafc389..d4be3a4d 100644 --- a/libimagtodo/src/error.rs +++ b/libimagtodo/src/error.rs @@ -4,14 +4,21 @@ use std::fmt::Error as FmtError; use std::fmt::{Debug, Display, Formatter}; use std::fmt; +/// Enum of Error Types, as of now we have two: +/// * ConversionError: for Errors concerning conversion failures from task_hookrs::task::Task to +/// libimagtodo::task::Task. unused. +/// * StoreError: For Errors thrown by functions of the Store/structs relates to the Store #[derive(Clone, Copy, Debug, PartialEq)] pub enum TodoErrorKind { ConversionError, + StoreError, } +/// Maps a TodoErrorKind to a String fn todo_error_type_as_str(e: &TodoErrorKind) -> &'static str { match e { &TodoErrorKind::ConversionError => "Conversion Error", + &TodoErrorKind::StoreError => "Store Error", } } @@ -22,6 +29,7 @@ impl Display for TodoErrorKind { } } +/// Error struct for the imag-todo module #[derive(Debug)] pub struct TodoError { err_type : TodoErrorKind, @@ -29,12 +37,14 @@ pub struct TodoError { } impl TodoError { + /// Creates a new TodoError, with TodoErrorKind errtype and an optional cause pub fn new(errtype : TodoErrorKind, cause : Option>) -> TodoError { TodoError { err_type : errtype, cause : cause, } } + /// Returns the error type (TodoErrorKind) pub fn err_type(&self) -> TodoErrorKind { self.err_type.clone() } @@ -55,6 +65,3 @@ impl Error for TodoError { self.cause.as_ref().map(|e| &**e) } } - - - diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index f1eaf3a3..2f78a6c4 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -1,5 +1,6 @@ extern crate semver; extern crate uuid; +extern crate toml; extern crate task_hookrs; #[macro_use] extern crate libimagstore; diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 66517528..8c3b0886 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -1,33 +1,61 @@ use std::ops::Deref; +use toml::Value; -use uuid::Uuid; use task_hookrs::task::Task as TTask; -use libimagstore::store::FileLockEntry; +use libimagstore::store::{FileLockEntry, Store}; +use libimagstore::storeid::IntoStoreId; +use module_path::ModuleEntryPath; use error::{TodoError, TodoErrorKind}; -pub trait IntoTask<'a> { - fn into_filelockentry(self) -> Result, TodoError>; -} - +/// Task struct containing a `FileLockEntry` #[derive(Debug)] pub struct Task<'a> { flentry : FileLockEntry<'a>, - //uuid : Uuid, } -/* -impl<'a> From for Task<'a> { - fn from(ttask : TTask) -> Task<'a> { + +impl<'a> Task<'a> { + /// Concstructs a new `Task` with a `FileLockEntry` + pub fn new(fle : FileLockEntry<'a>) -> Task<'a> { Task { - flentry : { - } + flentry : fle } } } -*/ + +/// A trait to get a `libimagtodo::task::Task` out of the implementing object. +/// This Task struct is merely a wrapper for a `FileLockEntry`, therefore the function name +/// `into_filelockentry`. +pub trait IntoTask<'a> { + /// # Usage + /// ```ignore + /// use std::io::stdin; + /// + /// use task_hookrs::task::Task; + /// use task_hookrs::import::import; + /// use libimagstore::store::{Store, FileLockEntry}; + /// + /// if let Ok(task_hookrs_task) = import(stdin()) { + /// // Store is given at runtime + /// let task = task_hookrs_task.into_filelockentry(store); + /// println!("Task with uuid: {}", task.flentry.get_header().get("todo.uuid")); + /// } + /// ``` + fn into_filelockentry(self, store : &'a Store) -> Result, TodoError>; +} impl<'a> IntoTask<'a> for TTask { - fn into_filelockentry(self) -> Result, TodoError> { - Err(TodoError::new(TodoErrorKind::ConversionError, None)) + fn into_filelockentry(self, store : &'a Store) -> Result, TodoError> { + let uuid = self.uuid(); + let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); + match store.retrieve(store_id) { + Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), + Ok(mut fle) => { + match fle.get_header_mut().set("todo.uuid", Value::String(format!("{}", uuid))) { + Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), + Ok(_) => Ok(Task { flentry : fle }) + } + }, + } } } From d68ed91be19393f49950cc05fbc85de122fb3efd Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 10 May 2016 15:54:46 +0200 Subject: [PATCH 12/98] add first implementation of command build --- imag-todo/src/main.rs | 21 +++++++++++++++++++++ imag-todo/src/ui.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 imag-todo/src/ui.rs diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index e7a11a96..850fc301 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -1,3 +1,24 @@ +extern crate clap; +extern crate glob; +#[macro_use] extern crate log; +extern crate semver; +extern crate toml; +#[macro_use] extern crate version; + +extern crate libimagrt; +extern crate libimagstore; +extern crate libimagutil; + +use std::process::exit; + +use libimagrt::runtime::Runtime; +use libimagstore::store::FileLockEntry; +use libimagutil::trace::trace_error; + +mod ui; + +use ui::build_ui; + fn main() { println!("Hello, world!"); } diff --git a/imag-todo/src/ui.rs b/imag-todo/src/ui.rs new file mode 100644 index 00000000..cc675f44 --- /dev/null +++ b/imag-todo/src/ui.rs @@ -0,0 +1,42 @@ +use clap::{Arg, App, ArgGroup, SubCommand}; + +pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { + app + .subcommand(SubCommand::with_name("tw-hook") + .about("For use in a taskwarrior hook") + .version("0.1") + + .arg(Arg::with_name("add") + .long("add") + .short("a") + .takes_value(false) + .required(false) + .help("For use in an on-add hook")) + + .arg(Arg::with_name("delete") + .long("delete") + .short("d") + .takes_value(false) + .required(false) + .help("For use in an on-delete hook")) + + .group(ArgGroup::with_name("taskwarrior hooks") + .args(&[ "add", + "delete", + ]) + .required(true)) + ) + + .subcommand(SubCommand::with_name("exec") + .about("Send a command to taskwarrior") + .version("0.1") + + .arg(Arg::with_name("command") + .long("command") + .short("c") + .takes_value(true) + .required(true) + .help("Args written in the string will be send directly to taskwarrior")) + ) +} + From b9d6d83bb74f7409620fc6485d715ad269c52475 Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 10 May 2016 16:28:35 +0200 Subject: [PATCH 13/98] add command parsing --- imag-todo/src/main.rs | 45 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 850fc301..3737baa3 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -20,5 +20,48 @@ mod ui; use ui::build_ui; fn main() { - println!("Hello, world!"); + let name = "imag-todo"; + let version = &version!()[..]; + let about = "Interface with taskwarrior"; + let ui = build_ui(Runtime::get_default_cli_builder(name, version, about)); + let rt = { + let rt = Runtime::new(ui); + if rt.is_ok() { + rt.unwrap() + } else { + println!("Could not set up Runtime"); + println!("{:?}", rt.unwrap_err()); + exit(1); + } + }; + + let scmd = rt.cli().subcommand_name(); + match scmd { + Some("tw-hook") => { + let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap(); + if subcmd.is_present("add") { + println!("To be implemented"); + // + // TODO @Kevin: import function aus task_hookrs benutzen, um + // stdin auszulesen, und dann auf dem + // task_hookrs::task::Task den Trait für die + // Umwandlung aufrufen. + // + } + else if subcmd.is_present("delete") { + println!("To be implemented"); + // + // Functionality to delete Entry in the store + // + } + else { + // Should not be possible, as one argument is required via + // ArgGroup + panic!("Reached unreachable Code"); + } + }, + Some("exec") => { + }, + _ => println!("Nothing implemented yet"), + } } From a79907920fb977841389d34fbc90d6c20734f9c2 Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 10 May 2016 16:43:59 +0200 Subject: [PATCH 14/98] update Cargo.toml --- imag-todo/Cargo.toml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/imag-todo/Cargo.toml b/imag-todo/Cargo.toml index fb21e2e6..213b2710 100644 --- a/imag-todo/Cargo.toml +++ b/imag-todo/Cargo.toml @@ -1,6 +1,22 @@ [package] +authors = ["mario "] name = "imag-todo" version = "0.1.0" -authors = ["mario "] [dependencies] +clap = "2.4.3" +glob = "0.2.11" +log = "0.3.6" +semver = "0.2.3" +toml = "0.1.28" +version = "2.0.1" + +[dependencies.libimagstore] +path = "../libimagstore" + +[dependencies.libimagrt] +path = "../libimagrt" + +[dependencies.libimagutil] +path = "../libimagutil" + From 03ee6e68384c9faeca4b7086b436cf9524c270cc Mon Sep 17 00:00:00 2001 From: schwente Date: Tue, 31 May 2016 13:34:50 +0200 Subject: [PATCH 15/98] Delete Function --- libimagtodo/src/delete.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/libimagtodo/src/delete.rs b/libimagtodo/src/delete.rs index e69de29b..cdb16501 100644 --- a/libimagtodo/src/delete.rs +++ b/libimagtodo/src/delete.rs @@ -0,0 +1,31 @@ +// Needed for reading a Json File +// extern crate rustc_serialize; +// use rustc_serialize::json::Json; +// use std::fs::File; +// use std::io::Read; + +use std::ops::Deref; +use toml::Value; + +use libimagstore::store::Store; +use libimagstore::storeid::IntoStoreId; +use module_path::ModuleEntryPath; + +/// With the uuid we get the storeid and than we can delete the entry +fn deleteFunc(uuid: i32, store : &Store) { + // With this we can read from a .json File + // let mut file = File::open("text.json").unwrap(); + // let mut data = String::new(); + // file.rad_to_string(&mut data).unwrap(); + // + // let jeson = Json::from_str(&data).unwrap(); + // println!("{}", json.find_path(&["uuid"]).unwrap()); + + // With the uuid we get the storeid + let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); + // It deletes an entry + store.delete(store_id); + + println!("The {} was delete!", uuid); +} + From d5dd55820a7561074029e48d9c9c3e69e1664a88 Mon Sep 17 00:00:00 2001 From: schwente Date: Wed, 1 Jun 2016 12:54:33 +0200 Subject: [PATCH 16/98] Do the changes for the Delete function --- libimagtodo/src/delete.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libimagtodo/src/delete.rs b/libimagtodo/src/delete.rs index cdb16501..79dd8ca5 100644 --- a/libimagtodo/src/delete.rs +++ b/libimagtodo/src/delete.rs @@ -6,13 +6,14 @@ use std::ops::Deref; use toml::Value; +use uuid::Uuid; use libimagstore::store::Store; use libimagstore::storeid::IntoStoreId; use module_path::ModuleEntryPath; /// With the uuid we get the storeid and than we can delete the entry -fn deleteFunc(uuid: i32, store : &Store) { +fn deleteFunc(uuid: Uuid, store : &Store) { // With this we can read from a .json File // let mut file = File::open("text.json").unwrap(); // let mut data = String::new(); @@ -25,7 +26,5 @@ fn deleteFunc(uuid: i32, store : &Store) { let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); // It deletes an entry store.delete(store_id); - - println!("The {} was delete!", uuid); } From 41dfd51f8b5d7c4fd49e0cc8330e14bf0d13f46a Mon Sep 17 00:00:00 2001 From: Roman Schemenau Date: Wed, 1 Jun 2016 13:01:19 +0200 Subject: [PATCH 17/98] Implement Read --- libimagtodo/src/read.rs | 67 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/libimagtodo/src/read.rs b/libimagtodo/src/read.rs index e69de29b..28e78d35 100644 --- a/libimagtodo/src/read.rs +++ b/libimagtodo/src/read.rs @@ -0,0 +1,67 @@ + + +use libimagstore::storeid::StoreIdIterator; +use libimagstore::store::{FileLockEntry, Store}; +use libimagstore::storeid::StoreId; +use module_path::ModuleEntryPath; +use error::{TodoError, TodoErrorKind}; + +use std::result::Result as RResult; + +pub type Result = RResult; + +pub struct Read<'a> { + entry: FileLockEntry<'a>, +} + +pub fn all_uuids(store: &Store) -> Result { + store.retrieve_for_module("uuid") + .map(|iter| ReadIterator::new(store, iter)) + .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) +} + + + + +trait FromStoreId { + fn from_storeid<'a>(&'a Store, StoreId) -> Result>; +} + +impl<'a> FromStoreId for Read<'a> { + + fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result> { + match store.retrieve(id) { + Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), + Ok(c) => Ok(Read { entry: c }), + } + } + +} + + +pub struct ReadIterator<'a> { + store: &'a Store, + iditer: StoreIdIterator, +} + +impl<'a> ReadIterator<'a> { + + pub fn new(store: &'a Store, iditer: StoreIdIterator) -> ReadIterator<'a> { + ReadIterator { + store: store, + iditer: iditer, + } + } + +} + +impl<'a> Iterator for ReadIterator<'a> { + type Item = Result>; + + fn next(&mut self) -> Option>> { + self.iditer + .next() + .map(|id| Read::from_storeid(self.store, id)) + } + +} From 7dbf7e7d3975500ece2cf7091c3dbe0d0ca6720a Mon Sep 17 00:00:00 2001 From: Yase Date: Wed, 1 Jun 2016 16:05:43 +0200 Subject: [PATCH 18/98] cmd query --- imag-todo/src/main.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 3737baa3..bef9f7a9 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -61,7 +61,17 @@ fn main() { } }, Some("exec") => { - }, - _ => println!("Nothing implemented yet"), + let subcmd = rt.cli().subcommand_matches("exec").unwrap(); + let itr = subcmd.values_of_os("add").unwrap(); + if subcmd.is_present("command") { + let string = subcmd.value_of("command").unwrap(); + println!("{:?}", string); + else { + panic!("Reached unreachable Code"); + } + }, + _ => println!("Nothing implemented yet"), + } } } + From 11b0622804a4766d5d173f93862aad751781f579 Mon Sep 17 00:00:00 2001 From: schwente Date: Mon, 6 Jun 2016 14:16:53 +0200 Subject: [PATCH 19/98] Fixed the store.delete(...) Return Problem --- libimagtodo/src/delete.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libimagtodo/src/delete.rs b/libimagtodo/src/delete.rs index 79dd8ca5..13d418bf 100644 --- a/libimagtodo/src/delete.rs +++ b/libimagtodo/src/delete.rs @@ -4,16 +4,16 @@ // use std::fs::File; // use std::io::Read; -use std::ops::Deref; -use toml::Value; use uuid::Uuid; use libimagstore::store::Store; use libimagstore::storeid::IntoStoreId; use module_path::ModuleEntryPath; +use error::{TodoError, TodoErrorKind}; + /// With the uuid we get the storeid and than we can delete the entry -fn deleteFunc(uuid: Uuid, store : &Store) { +pub fn deleteFunc(uuid: Uuid, store : &Store) { // With this we can read from a .json File // let mut file = File::open("text.json").unwrap(); // let mut data = String::new(); @@ -25,6 +25,9 @@ fn deleteFunc(uuid: Uuid, store : &Store) { // With the uuid we get the storeid let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); // It deletes an entry - store.delete(store_id); + if let Err(e) = store.delete(store_id) { + return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))).unwrap(); + } + } From 0545b6d3367034b17c44ed6b7e50e46a62a6938e Mon Sep 17 00:00:00 2001 From: Yase Date: Tue, 7 Jun 2016 23:45:49 +0200 Subject: [PATCH 20/98] ui.rs needed a multiple(true) main.rs - now we get the string argument of exec --command --- imag-todo/src/main.rs | 33 ++++++++++++++++++++++++--------- imag-todo/src/ui.rs | 8 +++++--- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index bef9f7a9..4ee5a240 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -10,10 +10,16 @@ extern crate libimagstore; extern crate libimagutil; use std::process::exit; +use std::process::{Command, Stdio}; +use std::io::prelude::*; +use std::io::BufReader; +use std::fs::File; use libimagrt::runtime::Runtime; use libimagstore::store::FileLockEntry; use libimagutil::trace::trace_error; +use std::error::Error; +use std::env; mod ui; @@ -24,6 +30,7 @@ fn main() { let version = &version!()[..]; let about = "Interface with taskwarrior"; let ui = build_ui(Runtime::get_default_cli_builder(name, version, about)); + let rt = { let rt = Runtime::new(ui); if rt.is_ok() { @@ -35,6 +42,8 @@ fn main() { } }; + + let scmd = rt.cli().subcommand_name(); match scmd { Some("tw-hook") => { @@ -61,17 +70,23 @@ fn main() { } }, Some("exec") => { - let subcmd = rt.cli().subcommand_matches("exec").unwrap(); - let itr = subcmd.values_of_os("add").unwrap(); - if subcmd.is_present("command") { - let string = subcmd.value_of("command").unwrap(); - println!("{:?}", string); - else { - panic!("Reached unreachable Code"); - } + let subcmd = rt.cli().subcommand_matches("exec").unwrap(); + let mut string = String::from(""); + //let args: Vec<_> = env::args().collect(); + //println!("{:?}", args); + if let Some(execString) = subcmd.values_of("command") { + for e in execString { + string.push_str(e); + string.push_str(" "); + } + //NOW SEND "string" to taskwarrior + + } else { + println!("false"); + } }, _ => println!("Nothing implemented yet"), } - } + } diff --git a/imag-todo/src/ui.rs b/imag-todo/src/ui.rs index cc675f44..d1707298 100644 --- a/imag-todo/src/ui.rs +++ b/imag-todo/src/ui.rs @@ -1,7 +1,7 @@ use clap::{Arg, App, ArgGroup, SubCommand}; pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { - app + app .subcommand(SubCommand::with_name("tw-hook") .about("For use in a taskwarrior hook") .version("0.1") @@ -35,8 +35,10 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .long("command") .short("c") .takes_value(true) + .multiple(true) .required(true) .help("Args written in the string will be send directly to taskwarrior")) - ) -} + ) + +} From 21fa21859b93733638c226a91caabfd65c8204f0 Mon Sep 17 00:00:00 2001 From: schwente Date: Wed, 8 Jun 2016 12:54:11 +0200 Subject: [PATCH 21/98] Change the Error handling and remove unsed code --- libimagtodo/src/delete.rs | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/libimagtodo/src/delete.rs b/libimagtodo/src/delete.rs index 13d418bf..317deaa0 100644 --- a/libimagtodo/src/delete.rs +++ b/libimagtodo/src/delete.rs @@ -1,9 +1,3 @@ -// Needed for reading a Json File -// extern crate rustc_serialize; -// use rustc_serialize::json::Json; -// use std::fs::File; -// use std::io::Read; - use uuid::Uuid; use libimagstore::store::Store; @@ -12,22 +6,14 @@ use module_path::ModuleEntryPath; use error::{TodoError, TodoErrorKind}; -/// With the uuid we get the storeid and than we can delete the entry -pub fn deleteFunc(uuid: Uuid, store : &Store) { - // With this we can read from a .json File - // let mut file = File::open("text.json").unwrap(); - // let mut data = String::new(); - // file.rad_to_string(&mut data).unwrap(); - // - // let jeson = Json::from_str(&data).unwrap(); - // println!("{}", json.find_path(&["uuid"]).unwrap()); - +/// With the uuid we get the storeid and then we can delete the entry +pub fn deleteFunc(uuid: Uuid, store : &Store) -> Result<(),TodoError> { // With the uuid we get the storeid let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); // It deletes an entry - if let Err(e) = store.delete(store_id) { - return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))).unwrap(); + match store.delete(store_id) { + Ok(val) => Ok(val), + Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), } - } From 2fec50fc102be8f83dbee96171ce93851587f2c5 Mon Sep 17 00:00:00 2001 From: Yase Date: Wed, 8 Jun 2016 14:25:29 +0200 Subject: [PATCH 22/98] exec command calls taskwarrior --- imag-todo/src/main.rs | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 4ee5a240..84696baa 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -1,5 +1,6 @@ extern crate clap; extern crate glob; +extern crate task_hookrs; #[macro_use] extern crate log; extern crate semver; extern crate toml; @@ -11,15 +12,12 @@ extern crate libimagutil; use std::process::exit; use std::process::{Command, Stdio}; -use std::io::prelude::*; -use std::io::BufReader; -use std::fs::File; +use std::error::Error; use libimagrt::runtime::Runtime; -use libimagstore::store::FileLockEntry; -use libimagutil::trace::trace_error; -use std::error::Error; -use std::env; +use std::process::Output; +use std::io::Write; +use std::io::Read; mod ui; @@ -71,21 +69,30 @@ fn main() { }, Some("exec") => { let subcmd = rt.cli().subcommand_matches("exec").unwrap(); - let mut string = String::from(""); - //let args: Vec<_> = env::args().collect(); - //println!("{:?}", args); - if let Some(execString) = subcmd.values_of("command") { - for e in execString { - string.push_str(e); - string.push_str(" "); + let mut args = Vec::new(); + if let Some(exec_string) = subcmd.values_of("command") { + for e in exec_string { + args.push(e); } - //NOW SEND "string" to taskwarrior - + let mut tw_process = Command::new("/usr/local/bin/task").stdin(Stdio::null()).args(&args).spawn().unwrap(); + //let erg = tw_process.args(&args).spawn().unwrap(); //{ + // Ok(_) => debug!("Executed command:\n"), + // Err(e) => debug!("Failed to execute command: {:#?}", e), + //} + let output = tw_process.wait_with_output().unwrap(); + let outstring = String::from_utf8(output.stdout).unwrap(); + println!("{}", outstring); + //let mut s = String::new(); + //match tw_process.stdout.unwrap().read_to_string(&mut s) { + //Err(err) => panic!("couldn't read taskwarrior stdout: {}", + // err.description()), + //Ok(_) => print!("taskwarrior responded with:\n{}", s), + //} } else { - println!("false"); + println!("You need '--command'"); } }, - _ => println!("Nothing implemented yet"), + _ => panic!("Reached unreachable Code"), } } From 41ae20c0497acf71f87c12d55560b0397debc6ef Mon Sep 17 00:00:00 2001 From: Yase Date: Thu, 9 Jun 2016 17:21:24 +0200 Subject: [PATCH 23/98] error handling for unwrap process stuff on exec taskwarrior --- imag-todo/src/main.rs | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 84696baa..00976a5f 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -12,18 +12,14 @@ extern crate libimagutil; use std::process::exit; use std::process::{Command, Stdio}; -use std::error::Error; use libimagrt::runtime::Runtime; -use std::process::Output; -use std::io::Write; -use std::io::Read; mod ui; use ui::build_ui; - fn main() { + let name = "imag-todo"; let version = &version!()[..]; let about = "Interface with taskwarrior"; @@ -74,22 +70,19 @@ fn main() { for e in exec_string { args.push(e); } - let mut tw_process = Command::new("/usr/local/bin/task").stdin(Stdio::null()).args(&args).spawn().unwrap(); - //let erg = tw_process.args(&args).spawn().unwrap(); //{ - // Ok(_) => debug!("Executed command:\n"), - // Err(e) => debug!("Failed to execute command: {:#?}", e), - //} - let output = tw_process.wait_with_output().unwrap(); - let outstring = String::from_utf8(output.stdout).unwrap(); + let mut tw_process = Command::new("/usr/local/bin/task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| { + panic!("failed to execute taskwarrior: {}", e); + }); + + let output = tw_process.wait_with_output().unwrap_or_else(|e| { + panic!("failed to unwrap output: {}", e); + }); + let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| { + panic!("failed to ececute: {}", e); + }); println!("{}", outstring); - //let mut s = String::new(); - //match tw_process.stdout.unwrap().read_to_string(&mut s) { - //Err(err) => panic!("couldn't read taskwarrior stdout: {}", - // err.description()), - //Ok(_) => print!("taskwarrior responded with:\n{}", s), - //} } else { - println!("You need '--command'"); + panic!("faild to execute: You need to exec --command"); } }, _ => panic!("Reached unreachable Code"), From ba600f1fb216f3ac4495923ecd528a6bd75148ca Mon Sep 17 00:00:00 2001 From: Yase Date: Fri, 10 Jun 2016 22:16:12 +0200 Subject: [PATCH 24/98] cargo --- imag-todo/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/imag-todo/Cargo.toml b/imag-todo/Cargo.toml index 213b2710..beac07e5 100644 --- a/imag-todo/Cargo.toml +++ b/imag-todo/Cargo.toml @@ -10,6 +10,7 @@ log = "0.3.6" semver = "0.2.3" toml = "0.1.28" version = "2.0.1" +task-hookrs = "0.1.0" [dependencies.libimagstore] path = "../libimagstore" From f015223a8edbf768e542709fc7a99845e3dd3eec Mon Sep 17 00:00:00 2001 From: Yase Date: Mon, 13 Jun 2016 11:15:02 +0200 Subject: [PATCH 25/98] changed /usr/bin/local/task to task --- imag-todo/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 00976a5f..96f8eafc 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -70,7 +70,7 @@ fn main() { for e in exec_string { args.push(e); } - let mut tw_process = Command::new("/usr/local/bin/task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| { + let mut tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| { panic!("failed to execute taskwarrior: {}", e); }); From 64adf4a5fbead1ea7b719ad78688e6551524c81b Mon Sep 17 00:00:00 2001 From: mario Date: Mon, 30 May 2016 15:02:30 +0200 Subject: [PATCH 26/98] added exec/add with description,priority,project,due and frequency --- imag-todo/src/ui.rs | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/imag-todo/src/ui.rs b/imag-todo/src/ui.rs index d1707298..3f4f6ab5 100644 --- a/imag-todo/src/ui.rs +++ b/imag-todo/src/ui.rs @@ -41,4 +41,46 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { ) -} + .subcommand(SubCommand::with_name("add") + .about("create a task") + .version("0.1") + + .arg(Arg::with_name("description") + .long("description") + .short("d") + .takes_value(true) + .required(true) + .help("Name/Description of the new task") + ) + + .arg(Arg::with_name("priority") + .long("priority") + .short("p") + .takes_value(true) + .required(false) + .help("One of l, m, h for low, medium and high priority") + ) + + .arg(Arg::with_name("project") + .long("project") + .takes_value(true) + .required(false) + .help("Name of the project the task is related to") + ) + + .arg(Arg::with_name("due") + .long("due") + .takes_value(true) + .required(false) + .help("Due date of the new task") + ) + + .arg(Arg::with_name("frequency") + .long("frequency") + .short("f") + .takes_value(true) + .required(false) + .help("Frequency of the recurrence of a task") + ) + +} From f00af56fd67a15fd08392ac3baabc379744c8555 Mon Sep 17 00:00:00 2001 From: mario Date: Wed, 15 Jun 2016 12:55:05 +0200 Subject: [PATCH 27/98] fix syntax error --- imag-todo/src/ui.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imag-todo/src/ui.rs b/imag-todo/src/ui.rs index 3f4f6ab5..a9ec0048 100644 --- a/imag-todo/src/ui.rs +++ b/imag-todo/src/ui.rs @@ -82,5 +82,5 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .required(false) .help("Frequency of the recurrence of a task") ) - + ) } From 84581c73ca33a750be75a2d8536e30370eb04be9 Mon Sep 17 00:00:00 2001 From: Roman Schemenau Date: Wed, 15 Jun 2016 13:10:45 +0200 Subject: [PATCH 28/98] Renamed function and iterator --- libimagtodo/src/read.rs | 69 +++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 40 deletions(-) diff --git a/libimagtodo/src/read.rs b/libimagtodo/src/read.rs index 28e78d35..9129fb60 100644 --- a/libimagtodo/src/read.rs +++ b/libimagtodo/src/read.rs @@ -1,67 +1,56 @@ - -use libimagstore::storeid::StoreIdIterator; -use libimagstore::store::{FileLockEntry, Store}; -use libimagstore::storeid::StoreId; -use module_path::ModuleEntryPath; +use libimagstore::storeid::{StoreIdIterator, StoreId}; +use libimagstore::store::Store; use error::{TodoError, TodoErrorKind}; +use task::Task; use std::result::Result as RResult; pub type Result = RResult; -pub struct Read<'a> { - entry: FileLockEntry<'a>, + +pub fn all_todos(store: &Store) -> Result { + + store.retrieve_for_module("uuid") + .map(|iter| TaskIterator::new(store, iter)) + .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) } -pub fn all_uuids(store: &Store) -> Result { - store.retrieve_for_module("uuid") - .map(|iter| ReadIterator::new(store, iter)) - .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) -} - - - - trait FromStoreId { - fn from_storeid<'a>(&'a Store, StoreId) -> Result>; + fn from_storeid<'a>(&'a Store, StoreId) -> Result>; } -impl<'a> FromStoreId for Read<'a> { +impl<'a> FromStoreId for Task<'a> { - fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result> { - match store.retrieve(id) { - Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), - Ok(c) => Ok(Read { entry: c }), - } + fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result> { + match store.retrieve(id) { + Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), + Ok(c) => Ok(Task::new( c )), + } } - } - -pub struct ReadIterator<'a> { +pub struct TaskIterator<'a> { store: &'a Store, iditer: StoreIdIterator, } -impl<'a> ReadIterator<'a> { +impl<'a> TaskIterator<'a> { - pub fn new(store: &'a Store, iditer: StoreIdIterator) -> ReadIterator<'a> { - ReadIterator { - store: store, - iditer: iditer, - } + pub fn new(store: &'a Store, iditer: StoreIdIterator) -> TaskIterator<'a> { + TaskIterator { + store: store, + iditer: iditer, + } } - } -impl<'a> Iterator for ReadIterator<'a> { - type Item = Result>; +impl<'a> Iterator for TaskIterator<'a> { + type Item = Result>; - fn next(&mut self) -> Option>> { - self.iditer - .next() - .map(|id| Read::from_storeid(self.store, id)) + fn next(&mut self) -> Option>> { + self.iditer + .next() + .map(|id| Task::from_storeid(self.store, id)) } - } From 7de2577725a27635491dfc7d83787bfc9dccd64f Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 28 Jun 2016 20:13:11 +0200 Subject: [PATCH 29/98] implemented add-hook --- imag-todo/src/main.rs | 46 ++++++++++++++++++++++++++++++----------- libimagtodo/Cargo.toml | 2 +- libimagtodo/src/task.rs | 35 +++++++++++++++++++++++++------ 3 files changed, 64 insertions(+), 19 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 96f8eafc..38e5ef1d 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -1,19 +1,29 @@ extern crate clap; extern crate glob; -extern crate task_hookrs; #[macro_use] extern crate log; +extern crate serde_json; extern crate semver; extern crate toml; #[macro_use] extern crate version; +extern crate task_hookrs; + extern crate libimagrt; extern crate libimagstore; extern crate libimagutil; +extern crate libimagtodo; use std::process::exit; use std::process::{Command, Stdio}; +use std::io::stdin; + +use task_hookrs::import::import; +use task_hookrs::task::Task as TTask; use libimagrt::runtime::Runtime; +use libimagtodo::task::Task; +use libimagtodo::task::IntoTask; +use libimagutil::trace::trace_error; mod ui; @@ -24,7 +34,7 @@ fn main() { let version = &version!()[..]; let about = "Interface with taskwarrior"; let ui = build_ui(Runtime::get_default_cli_builder(name, version, about)); - + let rt = { let rt = Runtime::new(ui); if rt.is_ok() { @@ -36,20 +46,32 @@ fn main() { } }; - + let scmd = rt.cli().subcommand_name(); match scmd { Some("tw-hook") => { let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap(); if subcmd.is_present("add") { - println!("To be implemented"); - // - // TODO @Kevin: import function aus task_hookrs benutzen, um - // stdin auszulesen, und dann auf dem - // task_hookrs::task::Task den Trait für die - // Umwandlung aufrufen. - // + if let Ok(ttasks) = task_hookrs::import::import(stdin()) { + for ttask in ttasks { + println!("{}", match serde_json::ser::to_string(&ttask) { + Ok(val) => val, + Err(e) => { + error!("{}", e); + return; + } + }); + let task = match ttask.into_filelockentry(rt.store()) { + Ok(val) => val, + Err(e) => { + trace_error(&e); + error!("{}", e); + return; + } + }; + } + } } else if subcmd.is_present("delete") { println!("To be implemented"); @@ -73,7 +95,7 @@ fn main() { let mut tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| { panic!("failed to execute taskwarrior: {}", e); }); - + let output = tw_process.wait_with_output().unwrap_or_else(|e| { panic!("failed to unwrap output: {}", e); }); @@ -87,6 +109,6 @@ fn main() { }, _ => panic!("Reached unreachable Code"), } - + } diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index dc1f6d8b..25e6386e 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -5,7 +5,7 @@ authors = ["mario "] [dependencies] semver = "0.2" -task-hookrs = { git = "https://github.com/matthiasbeyer/task-hookrs.git" } +task-hookrs = "0.1.0" uuid = "0.2.0" toml = "0.1.28" diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 8c3b0886..e8384a73 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -1,4 +1,5 @@ use std::ops::Deref; +use std::collections::BTreeMap; use toml::Value; use task_hookrs::task::Task as TTask; @@ -49,13 +50,35 @@ impl<'a> IntoTask<'a> for TTask { let uuid = self.uuid(); let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); match store.retrieve(store_id) { - Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), - Ok(mut fle) => { - match fle.get_header_mut().set("todo.uuid", Value::String(format!("{}", uuid))) { - Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), - Ok(_) => Ok(Task { flentry : fle }) - } + Err(e) => { + return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) }, + Ok(mut fle) => { + { + let mut header = fle.get_header_mut(); + match header.read("todo") { + Ok(None) => { + match header.set("todo", Value::Table(BTreeMap::new())) { + Ok(_) => { }, + Err(e) => { + return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) + } + } + } + Ok(Some(_)) => { } + Err(e) => { + } + } + match header.set("todo.uuid", Value::String(format!("{}",uuid))) { + Ok(_) => { }, + Err(e) => { + return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) + } + } + } + // If none of the errors above have returned the function, everything is fine + Ok(Task { flentry : fle } ) + } } } } From 48de71d926f735b7cb331a5befcac76b85eec12e Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 28 Jun 2016 20:20:35 +0200 Subject: [PATCH 30/98] fixed function name --- libimagtodo/src/delete.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libimagtodo/src/delete.rs b/libimagtodo/src/delete.rs index 317deaa0..78af3c78 100644 --- a/libimagtodo/src/delete.rs +++ b/libimagtodo/src/delete.rs @@ -7,13 +7,13 @@ use module_path::ModuleEntryPath; use error::{TodoError, TodoErrorKind}; /// With the uuid we get the storeid and then we can delete the entry -pub fn deleteFunc(uuid: Uuid, store : &Store) -> Result<(),TodoError> { +pub fn delete(uuid: Uuid, store : &Store) -> Result<(),TodoError> { // With the uuid we get the storeid let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); - // It deletes an entry + // It deletes an entry match store.delete(store_id) { Ok(val) => Ok(val), - Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), + Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), } } From 3a9128ec7bc061c5d35f4a6425df8d7cd236cca0 Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 28 Jun 2016 20:30:54 +0200 Subject: [PATCH 31/98] various fixes like indentation and function names. also moved the Result type definition to an extra file/module. --- libimagtodo/src/add.rs | 0 libimagtodo/src/read.rs | 31 +++++++++++++------------------ libimagtodo/src/result.rs | 5 +++++ libimagtodo/src/set.rs | 0 libimagtodo/src/task.rs | 5 +++-- 5 files changed, 21 insertions(+), 20 deletions(-) delete mode 100644 libimagtodo/src/add.rs create mode 100644 libimagtodo/src/result.rs delete mode 100644 libimagtodo/src/set.rs diff --git a/libimagtodo/src/add.rs b/libimagtodo/src/add.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/libimagtodo/src/read.rs b/libimagtodo/src/read.rs index 9129fb60..4af86d61 100644 --- a/libimagtodo/src/read.rs +++ b/libimagtodo/src/read.rs @@ -1,16 +1,11 @@ - use libimagstore::storeid::{StoreIdIterator, StoreId}; use libimagstore::store::Store; use error::{TodoError, TodoErrorKind}; use task::Task; +use result::Result; -use std::result::Result as RResult; +pub fn get_todo_iterator(store: &Store) -> Result { -pub type Result = RResult; - - -pub fn all_todos(store: &Store) -> Result { - store.retrieve_for_module("uuid") .map(|iter| TaskIterator::new(store, iter)) .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) @@ -23,10 +18,10 @@ trait FromStoreId { impl<'a> FromStoreId for Task<'a> { fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result> { - match store.retrieve(id) { - Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), - Ok(c) => Ok(Task::new( c )), - } + match store.retrieve(id) { + Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), + Ok(c) => Ok(Task::new( c )), + } } } @@ -38,10 +33,10 @@ pub struct TaskIterator<'a> { impl<'a> TaskIterator<'a> { pub fn new(store: &'a Store, iditer: StoreIdIterator) -> TaskIterator<'a> { - TaskIterator { - store: store, - iditer: iditer, - } + TaskIterator { + store: store, + iditer: iditer, + } } } @@ -49,8 +44,8 @@ impl<'a> Iterator for TaskIterator<'a> { type Item = Result>; fn next(&mut self) -> Option>> { - self.iditer - .next() - .map(|id| Task::from_storeid(self.store, id)) + self.iditer + .next() + .map(|id| Task::from_storeid(self.store, id)) } } diff --git a/libimagtodo/src/result.rs b/libimagtodo/src/result.rs new file mode 100644 index 00000000..2c254210 --- /dev/null +++ b/libimagtodo/src/result.rs @@ -0,0 +1,5 @@ +use error::{TodoError, TodoErrorKind}; + +use std::result::Result as RResult; + +pub type Result = RResult; diff --git a/libimagtodo/src/set.rs b/libimagtodo/src/set.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index e8384a73..5fe55990 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -9,6 +9,7 @@ use libimagstore::storeid::IntoStoreId; use module_path::ModuleEntryPath; use error::{TodoError, TodoErrorKind}; +use result::Result; /// Task struct containing a `FileLockEntry` #[derive(Debug)] @@ -43,10 +44,10 @@ pub trait IntoTask<'a> { /// println!("Task with uuid: {}", task.flentry.get_header().get("todo.uuid")); /// } /// ``` - fn into_filelockentry(self, store : &'a Store) -> Result, TodoError>; + fn into_filelockentry(self, store : &'a Store) -> Result>; } impl<'a> IntoTask<'a> for TTask { - fn into_filelockentry(self, store : &'a Store) -> Result, TodoError> { + fn into_filelockentry(self, store : &'a Store) -> Result> { let uuid = self.uuid(); let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); match store.retrieve(store_id) { From b2bc54c4f8b1b3970a1005f09a9dc9d253d9883f Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 28 Jun 2016 20:42:33 +0200 Subject: [PATCH 32/98] clean up of lib.rs --- libimagtodo/src/lib.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index 2f78a6c4..a93b8143 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -7,16 +7,9 @@ extern crate task_hookrs; module_entry_path_mod!("todo", "0.1.0"); -pub mod error; -pub mod task; pub mod delete; +pub mod error; pub mod read; -pub mod set; -pub mod add; +pub mod result; +pub mod task; -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - } -} From aa75b5ad9d41affe773d69caa8e64cc5116c0b77 Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 28 Jun 2016 20:57:53 +0200 Subject: [PATCH 33/98] added "list" option in clap ui --- imag-todo/src/main.rs | 8 ++- imag-todo/src/ui.rs | 115 +++++++++++++++++++++++------------------- 2 files changed, 67 insertions(+), 56 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 38e5ef1d..b756bb31 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -18,10 +18,8 @@ use std::process::{Command, Stdio}; use std::io::stdin; use task_hookrs::import::import; -use task_hookrs::task::Task as TTask; use libimagrt::runtime::Runtime; -use libimagtodo::task::Task; use libimagtodo::task::IntoTask; use libimagutil::trace::trace_error; @@ -53,7 +51,7 @@ fn main() { Some("tw-hook") => { let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap(); if subcmd.is_present("add") { - if let Ok(ttasks) = task_hookrs::import::import(stdin()) { + if let Ok(ttasks) = import(stdin()) { for ttask in ttasks { println!("{}", match serde_json::ser::to_string(&ttask) { Ok(val) => val, @@ -62,7 +60,7 @@ fn main() { return; } }); - let task = match ttask.into_filelockentry(rt.store()) { + match ttask.into_filelockentry(rt.store()) { Ok(val) => val, Err(e) => { trace_error(&e); @@ -92,7 +90,7 @@ fn main() { for e in exec_string { args.push(e); } - let mut tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| { + let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| { panic!("failed to execute taskwarrior: {}", e); }); diff --git a/imag-todo/src/ui.rs b/imag-todo/src/ui.rs index a9ec0048..ae2adc07 100644 --- a/imag-todo/src/ui.rs +++ b/imag-todo/src/ui.rs @@ -1,7 +1,7 @@ use clap::{Arg, App, ArgGroup, SubCommand}; pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { - app + app .subcommand(SubCommand::with_name("tw-hook") .about("For use in a taskwarrior hook") .version("0.1") @@ -22,65 +22,78 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .group(ArgGroup::with_name("taskwarrior hooks") .args(&[ "add", - "delete", - ]) + "delete", + ]) .required(true)) ) - .subcommand(SubCommand::with_name("exec") - .about("Send a command to taskwarrior") - .version("0.1") + .subcommand(SubCommand::with_name("exec") + .about("Send a command to taskwarrior") + .version("0.1") - .arg(Arg::with_name("command") - .long("command") - .short("c") - .takes_value(true) - .multiple(true) - .required(true) - .help("Args written in the string will be send directly to taskwarrior")) + .arg(Arg::with_name("command") + .long("command") + .short("c") + .takes_value(true) + .multiple(true) + .required(true) + .help("Args written in the string will be send directly to taskwarrior") + ) + ) - ) + .subcommand(SubCommand::with_name("add") + .about("create a task") + .version("0.1") - .subcommand(SubCommand::with_name("add") - .about("create a task") - .version("0.1") + .arg(Arg::with_name("description") + .long("description") + .short("d") + .takes_value(true) + .required(true) + .help("Name/Description of the new task") + ) - .arg(Arg::with_name("description") - .long("description") - .short("d") - .takes_value(true) - .required(true) - .help("Name/Description of the new task") - ) + .arg(Arg::with_name("priority") + .long("priority") + .short("p") + .takes_value(true) + .required(false) + .help("One of l, m, h for low, medium and high priority") + ) - .arg(Arg::with_name("priority") - .long("priority") - .short("p") - .takes_value(true) - .required(false) - .help("One of l, m, h for low, medium and high priority") - ) + .arg(Arg::with_name("project") + .long("project") + .takes_value(true) + .required(false) + .help("Name of the project the task is related to") + ) - .arg(Arg::with_name("project") - .long("project") - .takes_value(true) - .required(false) - .help("Name of the project the task is related to") - ) + .arg(Arg::with_name("due") + .long("due") + .takes_value(true) + .required(false) + .help("Due date of the new task") + ) - .arg(Arg::with_name("due") - .long("due") - .takes_value(true) - .required(false) - .help("Due date of the new task") - ) + .arg(Arg::with_name("frequency") + .long("frequency") + .short("f") + .takes_value(true) + .required(false) + .help("Frequency of the recurrence of a task") + ) + ) - .arg(Arg::with_name("frequency") - .long("frequency") - .short("f") - .takes_value(true) - .required(false) - .help("Frequency of the recurrence of a task") - ) - ) + .subcommand(SubCommand::with_name("list") + .about("List all tasks") + .version("0.1") + + .arg(Arg::with_name("verbose") + .long("verbose") + .short("v") + .takes_value(false) + .required(false) + .help("Asks taskwarrior for all the details") + ) + ) } From 72e85399ff4d8243f37cb1c52b907e8e61dc287e Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 28 Jun 2016 23:05:05 +0200 Subject: [PATCH 34/98] implemented list-featureo --- imag-todo/src/main.rs | 108 ++++++++++++++++++++++++++++++---------- libimagtodo/src/read.rs | 2 +- libimagtodo/src/task.rs | 2 +- 3 files changed, 85 insertions(+), 27 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index b756bb31..6b463000 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -72,7 +72,7 @@ fn main() { } } else if subcmd.is_present("delete") { - println!("To be implemented"); + unimplemented!(); // // Functionality to delete Entry in the store // @@ -80,33 +80,91 @@ fn main() { else { // Should not be possible, as one argument is required via // ArgGroup - panic!("Reached unreachable Code"); + unreachable!(); } }, Some("exec") => { - let subcmd = rt.cli().subcommand_matches("exec").unwrap(); - let mut args = Vec::new(); - if let Some(exec_string) = subcmd.values_of("command") { - for e in exec_string { - args.push(e); - } - let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| { - panic!("failed to execute taskwarrior: {}", e); - }); + let subcmd = rt.cli().subcommand_matches("exec").unwrap(); + let mut args = Vec::new(); + if let Some(exec_string) = subcmd.values_of("command") { + for e in exec_string { + args.push(e); + } + let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| { + panic!("failed to execute taskwarrior: {}", e); + }); - let output = tw_process.wait_with_output().unwrap_or_else(|e| { - panic!("failed to unwrap output: {}", e); - }); - let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| { - panic!("failed to ececute: {}", e); - }); - println!("{}", outstring); - } else { - panic!("faild to execute: You need to exec --command"); - } - }, - _ => panic!("Reached unreachable Code"), + let output = tw_process.wait_with_output().unwrap_or_else(|e| { + panic!("failed to unwrap output: {}", e); + }); + let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| { + panic!("failed to ececute: {}", e); + }); + println!("{}", outstring); + } else { + panic!("faild to execute: You need to exec --command"); + } } - -} + Some("list") => { + let subcmd = rt.cli().subcommand_matches("list").unwrap(); + let mut args = Vec::new(); + let verbose = subcmd.is_present("verbose"); + let iter = match libimagtodo::read::get_todo_iterator(rt.store()) { + //let iter = match rt.store().retrieve_for_module("todo/taskwarrior") { + Err(e) => { + error!("{}", e); + return; + } + Ok(val) => val, + }; + for task in iter { + match task { + Ok(val) => { + //let val = libimagtodo::task::Task::new(fle); + //println!("{:#?}", val.flentry); + let uuid = match val.flentry.get_header().read("todo.uuid") { + Ok(Some(u)) => u, + Ok(None) => continue, + Err(e) => { + error!("{}", e); + continue; + } + }; + if verbose { + args.clear(); + args.push(format!("uuid:{}", uuid)); + args.push(format!("{}", "information")); + let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn() + .unwrap_or_else(|e| { + error!("{}", e); + panic!("failed"); + }); + let output = tw_process.wait_with_output().unwrap_or_else(|e| { + panic!("failed to unwrap output: {}", e); + }); + let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| { + panic!("failed to ececute: {}", e); + }); + println!("{}", outstring); + } + else { + println!("{}", match uuid { + toml::Value::String(s) => s, + _ => { + error!("Unexpected type for todo.uuid: {}", uuid); + continue; + }, + }); + } + } + Err(e) => { + error!("{}", e); + continue; + } + } + } + } + _ => unimplemented!(), + } + } diff --git a/libimagtodo/src/read.rs b/libimagtodo/src/read.rs index 4af86d61..57c326c9 100644 --- a/libimagtodo/src/read.rs +++ b/libimagtodo/src/read.rs @@ -6,7 +6,7 @@ use result::Result; pub fn get_todo_iterator(store: &Store) -> Result { - store.retrieve_for_module("uuid") + store.retrieve_for_module("todo/taskwarrior") .map(|iter| TaskIterator::new(store, iter)) .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) } diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 5fe55990..b9174a56 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -14,7 +14,7 @@ use result::Result; /// Task struct containing a `FileLockEntry` #[derive(Debug)] pub struct Task<'a> { - flentry : FileLockEntry<'a>, + pub flentry : FileLockEntry<'a>, } impl<'a> Task<'a> { From 64b07ec35519c6d5e8c6fbfa1d30f3e2c976e6fd Mon Sep 17 00:00:00 2001 From: mario Date: Wed, 29 Jun 2016 21:37:21 +0200 Subject: [PATCH 35/98] impl delete waiting for task-hookrs --- imag-todo/src/main.rs | 59 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 6b463000..29a4925f 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -16,6 +16,7 @@ extern crate libimagtodo; use std::process::exit; use std::process::{Command, Stdio}; use std::io::stdin; +use std::io::BufRead; use task_hookrs::import::import; @@ -70,12 +71,62 @@ fn main() { }; } } + else { + error!("No usable input"); + return; + } } else if subcmd.is_present("delete") { - unimplemented!(); - // - // Functionality to delete Entry in the store - // + // The used hook is "on-modify". This hook gives two json-objects + // per usage und wants one (the second one) back. + let mut counter = 0; + let stdin = stdin(); + for rline in stdin.lock().lines() { + let mut line = match rline { + Ok(l) => l, + Err(e) => { + error!("{}", e); + return; + } + }; + line.insert(0, '['); + line.push(']'); + if counter % 2 == 1 { + if let Ok(ttasks) = import(line.as_bytes()) { + for ttask in ttasks { + // Only every second task is needed, the first one is the + // task before the change, and the second one after + // the change. The (maybe modified) second one is + // expected by taskwarrior. + println!("{}", match serde_json::ser::to_string(&ttask) { + Ok(val) => val, + Err(e) => { + error!("{}", e); + return; + } + }); + match ttask.status() { + &task_hookrs::status::TaskStatus::Deleted => { + match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) { + Ok(_) => { } + Err(e) => { + trace_error(&e); + error!("{}", e); + return; + } + } + } + _ => { + } + } + } + } + else { + error!("No usable input"); + } + } + counter += 1; + } } else { // Should not be possible, as one argument is required via From fbea3bcaf758c141ff780728af601b90474dbd2d Mon Sep 17 00:00:00 2001 From: mario Date: Thu, 30 Jun 2016 15:12:06 +0200 Subject: [PATCH 36/98] changed task-hookrs dependency to github.com/mario-kr/task-hookrs git for additional features --- imag-todo/Cargo.toml | 13 ++++++++----- libimagtodo/Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/imag-todo/Cargo.toml b/imag-todo/Cargo.toml index beac07e5..089c9918 100644 --- a/imag-todo/Cargo.toml +++ b/imag-todo/Cargo.toml @@ -8,16 +8,19 @@ clap = "2.4.3" glob = "0.2.11" log = "0.3.6" semver = "0.2.3" +serde_json = "0.7.3" +task-hookrs = { git = "https://github.com/mario-kr/task-hookrs.git" } toml = "0.1.28" version = "2.0.1" -task-hookrs = "0.1.0" - -[dependencies.libimagstore] -path = "../libimagstore" [dependencies.libimagrt] path = "../libimagrt" +[dependencies.libimagstore] +path = "../libimagstore" + +[dependencies.libimagtodo] +path = "../libimagtodo" + [dependencies.libimagutil] path = "../libimagutil" - diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index 25e6386e..b6582ac4 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -5,7 +5,7 @@ authors = ["mario "] [dependencies] semver = "0.2" -task-hookrs = "0.1.0" +task-hookrs = { git = "https://github.com/mario-kr/task-hookrs.git" } uuid = "0.2.0" toml = "0.1.28" From d0d9eac61cfaf2110ccb5522769fb02fe2b50311 Mon Sep 17 00:00:00 2001 From: mario Date: Thu, 30 Jun 2016 15:14:39 +0200 Subject: [PATCH 37/98] code cleanup --- libimagtodo/src/delete.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libimagtodo/src/delete.rs b/libimagtodo/src/delete.rs index 78af3c78..3aafae59 100644 --- a/libimagtodo/src/delete.rs +++ b/libimagtodo/src/delete.rs @@ -7,7 +7,7 @@ use module_path::ModuleEntryPath; use error::{TodoError, TodoErrorKind}; /// With the uuid we get the storeid and then we can delete the entry -pub fn delete(uuid: Uuid, store : &Store) -> Result<(),TodoError> { +pub fn delete(store : &Store, uuid: Uuid) -> Result<(),TodoError> { // With the uuid we get the storeid let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); // It deletes an entry From 8225f1a93e43ee3a66860ced8676adc85c1df78a Mon Sep 17 00:00:00 2001 From: mario Date: Thu, 30 Jun 2016 18:25:57 +0200 Subject: [PATCH 38/98] add-hook working --- imag-todo/src/main.rs | 58 ++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 29a4925f..6d4cc70e 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -18,7 +18,7 @@ use std::process::{Command, Stdio}; use std::io::stdin; use std::io::BufRead; -use task_hookrs::import::import; +use task_hookrs::import::{import, import_task, import_tasks}; use libimagrt::runtime::Runtime; use libimagtodo::task::IntoTask; @@ -52,24 +52,32 @@ fn main() { Some("tw-hook") => { let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap(); if subcmd.is_present("add") { - if let Ok(ttasks) = import(stdin()) { - for ttask in ttasks { - println!("{}", match serde_json::ser::to_string(&ttask) { - Ok(val) => val, - Err(e) => { - error!("{}", e); - return; - } - }); - match ttask.into_filelockentry(rt.store()) { - Ok(val) => val, - Err(e) => { - trace_error(&e); - error!("{}", e); - return; - } - }; + let stdin = stdin(); + let mut stdin = stdin.lock(); + let mut line = String::new(); + match stdin.read_line(&mut line) { + Ok(_) => { } + Err(e) => { + error!("{}", e); + return; } + }; + if let Ok(ttask) = import_task(&line.as_str()) { + print!("{}", match serde_json::ser::to_string(&ttask) { + Ok(val) => val, + Err(e) => { + error!("{}", e); + return; + } + }); + match ttask.into_filelockentry(rt.store()) { + Ok(val) => val, + Err(e) => { + trace_error(&e); + error!("{}", e); + return; + } + }; } else { error!("No usable input"); @@ -118,8 +126,8 @@ fn main() { } _ => { } - } - } + } // end match ttask.status() + } // end for } else { error!("No usable input"); @@ -212,10 +220,10 @@ fn main() { error!("{}", e); continue; } - } - } - } - _ => unimplemented!(), + } // end match task + } // end for } - } + _ => unimplemented!(), + } // end match scmd +} // end main From 2144c8c4259ecba6b545f05f57f1648f361959df Mon Sep 17 00:00:00 2001 From: mario Date: Thu, 30 Jun 2016 18:38:03 +0200 Subject: [PATCH 39/98] delete-hook working --- imag-todo/src/main.rs | 78 +++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 6d4cc70e..13831583 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -89,51 +89,43 @@ fn main() { // per usage und wants one (the second one) back. let mut counter = 0; let stdin = stdin(); - for rline in stdin.lock().lines() { - let mut line = match rline { - Ok(l) => l, - Err(e) => { - error!("{}", e); - return; - } - }; - line.insert(0, '['); - line.push(']'); - if counter % 2 == 1 { - if let Ok(ttasks) = import(line.as_bytes()) { - for ttask in ttasks { - // Only every second task is needed, the first one is the - // task before the change, and the second one after - // the change. The (maybe modified) second one is - // expected by taskwarrior. - println!("{}", match serde_json::ser::to_string(&ttask) { - Ok(val) => val, - Err(e) => { - error!("{}", e); - return; - } - }); - match ttask.status() { - &task_hookrs::status::TaskStatus::Deleted => { - match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) { - Ok(_) => { } - Err(e) => { - trace_error(&e); - error!("{}", e); - return; - } + let mut stdin = stdin.lock(); + if let Ok(ttasks) = import_tasks(stdin) { + for ttask in ttasks { + if counter % 2 == 1 { + // Only every second task is needed, the first one is the + // task before the change, and the second one after + // the change. The (maybe modified) second one is + // expected by taskwarrior. + println!("{}", match serde_json::ser::to_string(&ttask) { + Ok(val) => val, + Err(e) => { + error!("{}", e); + return; + } + }); + match ttask.status() { + &task_hookrs::status::TaskStatus::Deleted => { + match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) { + Ok(_) => { + println!("Deleted task {}", *ttask.uuid()); + } + Err(e) => { + trace_error(&e); + error!("{}", e); + return; } } - _ => { - } - } // end match ttask.status() - } // end for - } - else { - error!("No usable input"); - } - } - counter += 1; + } + _ => { + } + } // end match ttask.status() + } // end if c % 2 + counter += 1; + } // end for + } // end if let + else { + error!("No usable input"); } } else { From 5f1e9d6b3027591ef5ec375a7f1261a13be208dd Mon Sep 17 00:00:00 2001 From: mario Date: Thu, 30 Jun 2016 18:59:53 +0200 Subject: [PATCH 40/98] fixed parentheses --- imag-todo/src/main.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 13831583..4dedfb1d 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -63,7 +63,8 @@ fn main() { } }; if let Ok(ttask) = import_task(&line.as_str()) { - print!("{}", match serde_json::ser::to_string(&ttask) { + let uuid = *ttask.uuid(); + println!("{}", match serde_json::ser::to_string(&ttask) { Ok(val) => val, Err(e) => { error!("{}", e); @@ -71,7 +72,10 @@ fn main() { } }); match ttask.into_filelockentry(rt.store()) { - Ok(val) => val, + Ok(val) => { + println!("Task {} stored in imag", uuid); + val + }, Err(e) => { trace_error(&e); error!("{}", e); From 8c93e549399b264668c856834a63202c1a44c9d0 Mon Sep 17 00:00:00 2001 From: mario Date: Thu, 30 Jun 2016 19:02:12 +0200 Subject: [PATCH 41/98] reduce warnings --- imag-todo/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 4dedfb1d..9019dcde 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -18,7 +18,7 @@ use std::process::{Command, Stdio}; use std::io::stdin; use std::io::BufRead; -use task_hookrs::import::{import, import_task, import_tasks}; +use task_hookrs::import::{import_task, import_tasks}; use libimagrt::runtime::Runtime; use libimagtodo::task::IntoTask; @@ -93,7 +93,7 @@ fn main() { // per usage und wants one (the second one) back. let mut counter = 0; let stdin = stdin(); - let mut stdin = stdin.lock(); + let stdin = stdin.lock(); if let Ok(ttasks) = import_tasks(stdin) { for ttask in ttasks { if counter % 2 == 1 { From bbb4866fa0ada4084c0ff1131d515f70636ccb2f Mon Sep 17 00:00:00 2001 From: mario Date: Thu, 30 Jun 2016 19:06:26 +0200 Subject: [PATCH 42/98] reduce warnings lib --- libimagtodo/src/error.rs | 3 +-- libimagtodo/src/lib.rs | 2 +- libimagtodo/src/result.rs | 2 +- libimagtodo/src/task.rs | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libimagtodo/src/error.rs b/libimagtodo/src/error.rs index d4be3a4d..58fe7758 100644 --- a/libimagtodo/src/error.rs +++ b/libimagtodo/src/error.rs @@ -1,8 +1,7 @@ use std::error::Error; use std::clone::Clone; use std::fmt::Error as FmtError; -use std::fmt::{Debug, Display, Formatter}; -use std::fmt; +use std::fmt::{Display, Formatter}; /// Enum of Error Types, as of now we have two: /// * ConversionError: for Errors concerning conversion failures from task_hookrs::task::Task to diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index a93b8143..0396704a 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -2,8 +2,8 @@ extern crate semver; extern crate uuid; extern crate toml; -extern crate task_hookrs; #[macro_use] extern crate libimagstore; +extern crate task_hookrs; module_entry_path_mod!("todo", "0.1.0"); diff --git a/libimagtodo/src/result.rs b/libimagtodo/src/result.rs index 2c254210..d14bf499 100644 --- a/libimagtodo/src/result.rs +++ b/libimagtodo/src/result.rs @@ -1,4 +1,4 @@ -use error::{TodoError, TodoErrorKind}; +use error::TodoError; use std::result::Result as RResult; diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index b9174a56..ba9c7e9e 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -1,4 +1,3 @@ -use std::ops::Deref; use std::collections::BTreeMap; use toml::Value; @@ -68,6 +67,7 @@ impl<'a> IntoTask<'a> for TTask { } Ok(Some(_)) => { } Err(e) => { + return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) } } match header.set("todo.uuid", Value::String(format!("{}",uuid))) { From a91ec5c3ab54069da0e7f02453750cf116108f5a Mon Sep 17 00:00:00 2001 From: mario Date: Thu, 30 Jun 2016 19:09:14 +0200 Subject: [PATCH 43/98] do vim ggVG= --- libimagtodo/src/delete.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libimagtodo/src/delete.rs b/libimagtodo/src/delete.rs index 3aafae59..ed56dc0c 100644 --- a/libimagtodo/src/delete.rs +++ b/libimagtodo/src/delete.rs @@ -8,12 +8,12 @@ use error::{TodoError, TodoErrorKind}; /// With the uuid we get the storeid and then we can delete the entry pub fn delete(store : &Store, uuid: Uuid) -> Result<(),TodoError> { - // With the uuid we get the storeid - let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); - // It deletes an entry - match store.delete(store_id) { - Ok(val) => Ok(val), - Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), - } + // With the uuid we get the storeid + let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); + // It deletes an entry + match store.delete(store_id) { + Ok(val) => Ok(val), + Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), + } } From 5f731c8f8fe265dd9a7c293df57ac368911a2996 Mon Sep 17 00:00:00 2001 From: mario Date: Mon, 4 Jul 2016 14:04:11 +0200 Subject: [PATCH 44/98] change from libimagutil::trace to libimagerror::trace --- imag-todo/Cargo.toml | 4 ++-- imag-todo/src/main.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imag-todo/Cargo.toml b/imag-todo/Cargo.toml index 089c9918..845a0901 100644 --- a/imag-todo/Cargo.toml +++ b/imag-todo/Cargo.toml @@ -22,5 +22,5 @@ path = "../libimagstore" [dependencies.libimagtodo] path = "../libimagtodo" -[dependencies.libimagutil] -path = "../libimagutil" +[dependencies.libimagerror] +path = "../libimagerror" diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 9019dcde..945724b7 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -10,7 +10,7 @@ extern crate task_hookrs; extern crate libimagrt; extern crate libimagstore; -extern crate libimagutil; +extern crate libimagerror; extern crate libimagtodo; use std::process::exit; @@ -22,7 +22,7 @@ use task_hookrs::import::{import_task, import_tasks}; use libimagrt::runtime::Runtime; use libimagtodo::task::IntoTask; -use libimagutil::trace::trace_error; +use libimagerror::trace::trace_error; mod ui; From 29c4ed853ccf56a0bc29311d176d55d815412343 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 19:37:49 +0200 Subject: [PATCH 45/98] Remove unnecessary whitespace --- imag-todo/src/main.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 945724b7..1686a36b 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -28,7 +28,6 @@ mod ui; use ui::build_ui; fn main() { - let name = "imag-todo"; let version = &version!()[..]; let about = "Interface with taskwarrior"; @@ -45,8 +44,6 @@ fn main() { } }; - - let scmd = rt.cli().subcommand_name(); match scmd { Some("tw-hook") => { From fadeae52147bcc4c147df274e1987958a736d57c Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 19:38:00 +0200 Subject: [PATCH 46/98] Move functionality to own functions --- imag-todo/src/main.rs | 316 +++++++++++++++++++++--------------------- 1 file changed, 161 insertions(+), 155 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 1686a36b..7f2583ff 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -46,21 +46,65 @@ fn main() { let scmd = rt.cli().subcommand_name(); match scmd { - Some("tw-hook") => { - let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap(); - if subcmd.is_present("add") { - let stdin = stdin(); - let mut stdin = stdin.lock(); - let mut line = String::new(); - match stdin.read_line(&mut line) { - Ok(_) => { } - Err(e) => { - error!("{}", e); - return; - } - }; - if let Ok(ttask) = import_task(&line.as_str()) { - let uuid = *ttask.uuid(); + Some("tw-hook") => tw_hook(&rt), + Some("exec") => exec(&rt), + Some("list") => list(&rt), + _ => unimplemented!(), + } // end match scmd +} // end main + +fn tw_hook(rt: &Runtime) { + let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap(); + if subcmd.is_present("add") { + let stdin = stdin(); + let mut stdin = stdin.lock(); + let mut line = String::new(); + match stdin.read_line(&mut line) { + Ok(_) => { } + Err(e) => { + error!("{}", e); + return; + } + }; + if let Ok(ttask) = import_task(&line.as_str()) { + let uuid = *ttask.uuid(); + println!("{}", match serde_json::ser::to_string(&ttask) { + Ok(val) => val, + Err(e) => { + error!("{}", e); + return; + } + }); + match ttask.into_filelockentry(rt.store()) { + Ok(val) => { + println!("Task {} stored in imag", uuid); + val + }, + Err(e) => { + trace_error(&e); + error!("{}", e); + return; + } + }; + } + else { + error!("No usable input"); + return; + } + } + else if subcmd.is_present("delete") { + // The used hook is "on-modify". This hook gives two json-objects + // per usage und wants one (the second one) back. + let mut counter = 0; + let stdin = stdin(); + let stdin = stdin.lock(); + if let Ok(ttasks) = import_tasks(stdin) { + for ttask in ttasks { + if counter % 2 == 1 { + // Only every second task is needed, the first one is the + // task before the change, and the second one after + // the change. The (maybe modified) second one is + // expected by taskwarrior. println!("{}", match serde_json::ser::to_string(&ttask) { Ok(val) => val, Err(e) => { @@ -68,155 +112,117 @@ fn main() { return; } }); - match ttask.into_filelockentry(rt.store()) { - Ok(val) => { - println!("Task {} stored in imag", uuid); - val - }, - Err(e) => { - trace_error(&e); - error!("{}", e); - return; - } - }; - } - else { - error!("No usable input"); - return; - } - } - else if subcmd.is_present("delete") { - // The used hook is "on-modify". This hook gives two json-objects - // per usage und wants one (the second one) back. - let mut counter = 0; - let stdin = stdin(); - let stdin = stdin.lock(); - if let Ok(ttasks) = import_tasks(stdin) { - for ttask in ttasks { - if counter % 2 == 1 { - // Only every second task is needed, the first one is the - // task before the change, and the second one after - // the change. The (maybe modified) second one is - // expected by taskwarrior. - println!("{}", match serde_json::ser::to_string(&ttask) { - Ok(val) => val, + match ttask.status() { + &task_hookrs::status::TaskStatus::Deleted => { + match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) { + Ok(_) => { + println!("Deleted task {}", *ttask.uuid()); + } Err(e) => { + trace_error(&e); error!("{}", e); return; } - }); - match ttask.status() { - &task_hookrs::status::TaskStatus::Deleted => { - match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) { - Ok(_) => { - println!("Deleted task {}", *ttask.uuid()); - } - Err(e) => { - trace_error(&e); - error!("{}", e); - return; - } - } - } - _ => { - } - } // end match ttask.status() - } // end if c % 2 - counter += 1; - } // end for - } // end if let - else { - error!("No usable input"); - } - } - else { - // Should not be possible, as one argument is required via - // ArgGroup - unreachable!(); - } - }, - Some("exec") => { - let subcmd = rt.cli().subcommand_matches("exec").unwrap(); - let mut args = Vec::new(); - if let Some(exec_string) = subcmd.values_of("command") { - for e in exec_string { - args.push(e); - } - let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| { - panic!("failed to execute taskwarrior: {}", e); - }); - - let output = tw_process.wait_with_output().unwrap_or_else(|e| { - panic!("failed to unwrap output: {}", e); - }); - let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| { - panic!("failed to ececute: {}", e); - }); - println!("{}", outstring); - } else { - panic!("faild to execute: You need to exec --command"); - } - } - Some("list") => { - let subcmd = rt.cli().subcommand_matches("list").unwrap(); - let mut args = Vec::new(); - let verbose = subcmd.is_present("verbose"); - let iter = match libimagtodo::read::get_todo_iterator(rt.store()) { - //let iter = match rt.store().retrieve_for_module("todo/taskwarrior") { - Err(e) => { - error!("{}", e); - return; - } - Ok(val) => val, - }; - for task in iter { - match task { - Ok(val) => { - //let val = libimagtodo::task::Task::new(fle); - //println!("{:#?}", val.flentry); - let uuid = match val.flentry.get_header().read("todo.uuid") { - Ok(Some(u)) => u, - Ok(None) => continue, - Err(e) => { - error!("{}", e); - continue; } - }; - if verbose { - args.clear(); - args.push(format!("uuid:{}", uuid)); - args.push(format!("{}", "information")); - let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn() - .unwrap_or_else(|e| { - error!("{}", e); - panic!("failed"); - }); - let output = tw_process.wait_with_output().unwrap_or_else(|e| { - panic!("failed to unwrap output: {}", e); - }); - let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| { - panic!("failed to ececute: {}", e); - }); - println!("{}", outstring); } - else { - println!("{}", match uuid { - toml::Value::String(s) => s, - _ => { - error!("Unexpected type for todo.uuid: {}", uuid); - continue; - }, - }); + _ => { } - } + } // end match ttask.status() + } // end if c % 2 + counter += 1; + } // end for + } // end if let + else { + error!("No usable input"); + } + } + else { + // Should not be possible, as one argument is required via + // ArgGroup + unreachable!(); + } +} + +fn exec(rt: &Runtime) { + let subcmd = rt.cli().subcommand_matches("exec").unwrap(); + let mut args = Vec::new(); + if let Some(exec_string) = subcmd.values_of("command") { + for e in exec_string { + args.push(e); + } + let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| { + panic!("failed to execute taskwarrior: {}", e); + }); + + let output = tw_process.wait_with_output().unwrap_or_else(|e| { + panic!("failed to unwrap output: {}", e); + }); + let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| { + panic!("failed to ececute: {}", e); + }); + println!("{}", outstring); + } else { + panic!("faild to execute: You need to exec --command"); + } +} + +fn list(rt: &Runtime) { + let subcmd = rt.cli().subcommand_matches("list").unwrap(); + let mut args = Vec::new(); + let verbose = subcmd.is_present("verbose"); + let iter = match libimagtodo::read::get_todo_iterator(rt.store()) { + //let iter = match rt.store().retrieve_for_module("todo/taskwarrior") { + Err(e) => { + error!("{}", e); + return; + } + Ok(val) => val, + }; + for task in iter { + match task { + Ok(val) => { + //let val = libimagtodo::task::Task::new(fle); + //println!("{:#?}", val.flentry); + let uuid = match val.flentry.get_header().read("todo.uuid") { + Ok(Some(u)) => u, + Ok(None) => continue, Err(e) => { error!("{}", e); continue; } - } // end match task - } // end for - } - _ => unimplemented!(), - } // end match scmd -} // end main + }; + if verbose { + args.clear(); + args.push(format!("uuid:{}", uuid)); + args.push(format!("{}", "information")); + let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn() + .unwrap_or_else(|e| { + error!("{}", e); + panic!("failed"); + }); + let output = tw_process.wait_with_output().unwrap_or_else(|e| { + panic!("failed to unwrap output: {}", e); + }); + let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| { + panic!("failed to ececute: {}", e); + }); + println!("{}", outstring); + } + else { + println!("{}", match uuid { + toml::Value::String(s) => s, + _ => { + error!("Unexpected type for todo.uuid: {}", uuid); + continue; + }, + }); + } + } + Err(e) => { + error!("{}", e); + continue; + } + } // end match task + } // end for +} From aef80874da57bb434d6cac0fd65ad0940def8964 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 19:50:55 +0200 Subject: [PATCH 47/98] Remove the most ugly parts --- imag-todo/src/main.rs | 103 +++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 56 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 7f2583ff..e1610dc4 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -44,8 +44,7 @@ fn main() { } }; - let scmd = rt.cli().subcommand_name(); - match scmd { + match rt.cli().subcommand_name() { Some("tw-hook") => tw_hook(&rt), Some("exec") => exec(&rt), Some("list") => list(&rt), @@ -56,25 +55,25 @@ fn main() { fn tw_hook(rt: &Runtime) { let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap(); if subcmd.is_present("add") { - let stdin = stdin(); + let stdin = stdin(); let mut stdin = stdin.lock(); - let mut line = String::new(); - match stdin.read_line(&mut line) { - Ok(_) => { } - Err(e) => { - error!("{}", e); - return; - } + let mut line = String::new(); + + if let Err(e) = stdin.read_line(&mut line) { + trace_error(&e); + exit(1); }; + if let Ok(ttask) = import_task(&line.as_str()) { - let uuid = *ttask.uuid(); - println!("{}", match serde_json::ser::to_string(&ttask) { - Ok(val) => val, + match serde_json::ser::to_string(&ttask) { + Ok(val) => println!("{}", val), Err(e) => { - error!("{}", e); - return; + trace_error(&e); + exit(1); } - }); + } + + let uuid = *ttask.uuid(); match ttask.into_filelockentry(rt.store()) { Ok(val) => { println!("Task {} stored in imag", uuid); @@ -82,22 +81,20 @@ fn tw_hook(rt: &Runtime) { }, Err(e) => { trace_error(&e); - error!("{}", e); - return; + exit(1); } }; - } - else { + } else { error!("No usable input"); - return; + exit(1); } - } - else if subcmd.is_present("delete") { + } else if subcmd.is_present("delete") { // The used hook is "on-modify". This hook gives two json-objects // per usage und wants one (the second one) back. - let mut counter = 0; - let stdin = stdin(); - let stdin = stdin.lock(); + let mut counter = 0; + let stdin = stdin(); + let stdin = stdin.lock(); + if let Ok(ttasks) = import_tasks(stdin) { for ttask in ttasks { if counter % 2 == 1 { @@ -105,23 +102,21 @@ fn tw_hook(rt: &Runtime) { // task before the change, and the second one after // the change. The (maybe modified) second one is // expected by taskwarrior. - println!("{}", match serde_json::ser::to_string(&ttask) { - Ok(val) => val, + match serde_json::ser::to_string(&ttask) { + Ok(val) => println!("{}", val), Err(e) => { - error!("{}", e); - return; + trace_error(&e); + exit(1); } - }); + } + match ttask.status() { &task_hookrs::status::TaskStatus::Deleted => { match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) { - Ok(_) => { - println!("Deleted task {}", *ttask.uuid()); - } + Ok(_) => println!("Deleted task {}", *ttask.uuid()), Err(e) => { trace_error(&e); - error!("{}", e); - return; + exit(1); } } } @@ -131,12 +126,10 @@ fn tw_hook(rt: &Runtime) { } // end if c % 2 counter += 1; } // end for - } // end if let - else { + } else { error!("No usable input"); } - } - else { + } else { // Should not be possible, as one argument is required via // ArgGroup unreachable!(); @@ -167,48 +160,46 @@ fn exec(rt: &Runtime) { } fn list(rt: &Runtime) { - let subcmd = rt.cli().subcommand_matches("list").unwrap(); + let subcmd = rt.cli().subcommand_matches("list").unwrap(); let mut args = Vec::new(); - let verbose = subcmd.is_present("verbose"); - let iter = match libimagtodo::read::get_todo_iterator(rt.store()) { - //let iter = match rt.store().retrieve_for_module("todo/taskwarrior") { + let verbose = subcmd.is_present("verbose"); + let iter = match libimagtodo::read::get_todo_iterator(rt.store()) { Err(e) => { - error!("{}", e); - return; + trace_error(&e); + exit(1); } Ok(val) => val, }; + for task in iter { match task { Ok(val) => { - //let val = libimagtodo::task::Task::new(fle); - //println!("{:#?}", val.flentry); let uuid = match val.flentry.get_header().read("todo.uuid") { Ok(Some(u)) => u, - Ok(None) => continue, - Err(e) => { - error!("{}", e); + Ok(None) => continue, + Err(e) => { + trace_error(&e); continue; } }; + if verbose { args.clear(); args.push(format!("uuid:{}", uuid)); args.push(format!("{}", "information")); let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn() .unwrap_or_else(|e| { - error!("{}", e); + trace_error(&e); panic!("failed"); }); let output = tw_process.wait_with_output().unwrap_or_else(|e| { panic!("failed to unwrap output: {}", e); }); let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| { - panic!("failed to ececute: {}", e); + panic!("failed to execute: {}", e); }); println!("{}", outstring); - } - else { + } else { println!("{}", match uuid { toml::Value::String(s) => s, _ => { @@ -219,7 +210,7 @@ fn list(rt: &Runtime) { } } Err(e) => { - error!("{}", e); + trace_error(&e); continue; } } // end match task From 247cda035296b519802714e4228913014a052dbb Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 19:51:21 +0200 Subject: [PATCH 48/98] Rip out exec() --- imag-todo/src/main.rs | 24 ------------------------ imag-todo/src/ui.rs | 14 -------------- 2 files changed, 38 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index e1610dc4..31274761 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -46,7 +46,6 @@ fn main() { match rt.cli().subcommand_name() { Some("tw-hook") => tw_hook(&rt), - Some("exec") => exec(&rt), Some("list") => list(&rt), _ => unimplemented!(), } // end match scmd @@ -136,29 +135,6 @@ fn tw_hook(rt: &Runtime) { } } -fn exec(rt: &Runtime) { - let subcmd = rt.cli().subcommand_matches("exec").unwrap(); - let mut args = Vec::new(); - if let Some(exec_string) = subcmd.values_of("command") { - for e in exec_string { - args.push(e); - } - let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| { - panic!("failed to execute taskwarrior: {}", e); - }); - - let output = tw_process.wait_with_output().unwrap_or_else(|e| { - panic!("failed to unwrap output: {}", e); - }); - let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| { - panic!("failed to ececute: {}", e); - }); - println!("{}", outstring); - } else { - panic!("faild to execute: You need to exec --command"); - } -} - fn list(rt: &Runtime) { let subcmd = rt.cli().subcommand_matches("list").unwrap(); let mut args = Vec::new(); diff --git a/imag-todo/src/ui.rs b/imag-todo/src/ui.rs index ae2adc07..507f4379 100644 --- a/imag-todo/src/ui.rs +++ b/imag-todo/src/ui.rs @@ -27,20 +27,6 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .required(true)) ) - .subcommand(SubCommand::with_name("exec") - .about("Send a command to taskwarrior") - .version("0.1") - - .arg(Arg::with_name("command") - .long("command") - .short("c") - .takes_value(true) - .multiple(true) - .required(true) - .help("Args written in the string will be send directly to taskwarrior") - ) - ) - .subcommand(SubCommand::with_name("add") .about("create a task") .version("0.1") From 84890bf8fc620c16ca861fcb8cb50bd3008c1c78 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 19:52:00 +0200 Subject: [PATCH 49/98] Rip out ui setup for "add" subcommand --- imag-todo/src/ui.rs | 43 ------------------------------------------- 1 file changed, 43 deletions(-) diff --git a/imag-todo/src/ui.rs b/imag-todo/src/ui.rs index 507f4379..7ec89d39 100644 --- a/imag-todo/src/ui.rs +++ b/imag-todo/src/ui.rs @@ -27,49 +27,6 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .required(true)) ) - .subcommand(SubCommand::with_name("add") - .about("create a task") - .version("0.1") - - .arg(Arg::with_name("description") - .long("description") - .short("d") - .takes_value(true) - .required(true) - .help("Name/Description of the new task") - ) - - .arg(Arg::with_name("priority") - .long("priority") - .short("p") - .takes_value(true) - .required(false) - .help("One of l, m, h for low, medium and high priority") - ) - - .arg(Arg::with_name("project") - .long("project") - .takes_value(true) - .required(false) - .help("Name of the project the task is related to") - ) - - .arg(Arg::with_name("due") - .long("due") - .takes_value(true) - .required(false) - .help("Due date of the new task") - ) - - .arg(Arg::with_name("frequency") - .long("frequency") - .short("f") - .takes_value(true) - .required(false) - .help("Frequency of the recurrence of a task") - ) - ) - .subcommand(SubCommand::with_name("list") .about("List all tasks") .version("0.1") From b78da80717dc481d7895019ca686a7b969207c80 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 19:53:47 +0200 Subject: [PATCH 50/98] Do not hide the error here, yell it out! --- imag-todo/src/main.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 31274761..d02755e1 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -94,8 +94,8 @@ fn tw_hook(rt: &Runtime) { let stdin = stdin(); let stdin = stdin.lock(); - if let Ok(ttasks) = import_tasks(stdin) { - for ttask in ttasks { + match import_tasks(stdin) { + Ok(ttasks) => for ttask in ttasks { if counter % 2 == 1 { // Only every second task is needed, the first one is the // task before the change, and the second one after @@ -124,9 +124,11 @@ fn tw_hook(rt: &Runtime) { } // end match ttask.status() } // end if c % 2 counter += 1; - } // end for - } else { - error!("No usable input"); + }, + Err(e) => { + trace_error(&e); + exit(1); + }, } } else { // Should not be possible, as one argument is required via From b2eb2de3fd6607e89fbef7bfc646de2cda39b422 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 19:56:41 +0200 Subject: [PATCH 51/98] We do not need to String::push() here twice --- imag-todo/src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index d02755e1..092a15e0 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -163,8 +163,7 @@ fn list(rt: &Runtime) { if verbose { args.clear(); - args.push(format!("uuid:{}", uuid)); - args.push(format!("{}", "information")); + args.push(format!("uuid:{} information", uuid)); let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn() .unwrap_or_else(|e| { trace_error(&e); From 0752058cf585fd6e541872404fb147cf3e131919 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 19:57:49 +0200 Subject: [PATCH 52/98] Format code --- imag-todo/src/main.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 092a15e0..4b31a7b6 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -28,10 +28,10 @@ mod ui; use ui::build_ui; fn main() { - let name = "imag-todo"; + let name = "imag-todo"; let version = &version!()[..]; - let about = "Interface with taskwarrior"; - let ui = build_ui(Runtime::get_default_cli_builder(name, version, about)); + let about = "Interface with taskwarrior"; + let ui = build_ui(Runtime::get_default_cli_builder(name, version, about)); let rt = { let rt = Runtime::new(ui); @@ -164,17 +164,21 @@ fn list(rt: &Runtime) { if verbose { args.clear(); args.push(format!("uuid:{} information", uuid)); - let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn() + + let tw_process = Command::new("task") + .stdin(Stdio::null()) + .args(&args) + .spawn() .unwrap_or_else(|e| { trace_error(&e); panic!("failed"); }); - let output = tw_process.wait_with_output().unwrap_or_else(|e| { - panic!("failed to unwrap output: {}", e); - }); - let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| { - panic!("failed to execute: {}", e); - }); + let output = tw_process + .wait_with_output() + .unwrap_or_else(|e| panic!("failed to unwrap output: {}", e)); + let outstring = String::from_utf8(output.stdout) + .unwrap_or_else(|e| panic!("failed to execute: {}", e)); + println!("{}", outstring); } else { println!("{}", match uuid { From b12974043dd150adaf13ad33d76b49efe1356c15 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 20:03:20 +0200 Subject: [PATCH 53/98] Remove the most ugly parts from the lib --- libimagtodo/src/read.rs | 6 ++---- libimagtodo/src/task.rs | 30 ++++++++++++++++-------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/libimagtodo/src/read.rs b/libimagtodo/src/read.rs index 57c326c9..f547ac30 100644 --- a/libimagtodo/src/read.rs +++ b/libimagtodo/src/read.rs @@ -5,7 +5,6 @@ use task::Task; use result::Result; pub fn get_todo_iterator(store: &Store) -> Result { - store.retrieve_for_module("todo/taskwarrior") .map(|iter| TaskIterator::new(store, iter)) .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) @@ -38,14 +37,13 @@ impl<'a> TaskIterator<'a> { iditer: iditer, } } + } impl<'a> Iterator for TaskIterator<'a> { type Item = Result>; fn next(&mut self) -> Option>> { - self.iditer - .next() - .map(|id| Task::from_storeid(self.store, id)) + self.iditer.next().map(|id| Task::from_storeid(self.store, id)) } } diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index ba9c7e9e..277a5e40 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -17,18 +17,21 @@ pub struct Task<'a> { } impl<'a> Task<'a> { + /// Concstructs a new `Task` with a `FileLockEntry` pub fn new(fle : FileLockEntry<'a>) -> Task<'a> { Task { flentry : fle } } + } /// A trait to get a `libimagtodo::task::Task` out of the implementing object. /// This Task struct is merely a wrapper for a `FileLockEntry`, therefore the function name /// `into_filelockentry`. pub trait IntoTask<'a> { + /// # Usage /// ```ignore /// use std::io::stdin; @@ -44,25 +47,24 @@ pub trait IntoTask<'a> { /// } /// ``` fn into_filelockentry(self, store : &'a Store) -> Result>; + } + impl<'a> IntoTask<'a> for TTask { + fn into_filelockentry(self, store : &'a Store) -> Result> { - let uuid = self.uuid(); + let uuid = self.uuid(); let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); + match store.retrieve(store_id) { - Err(e) => { - return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) - }, + Err(e) => return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), Ok(mut fle) => { { let mut header = fle.get_header_mut(); match header.read("todo") { Ok(None) => { - match header.set("todo", Value::Table(BTreeMap::new())) { - Ok(_) => { }, - Err(e) => { - return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) - } + if let Err(e) = header.set("todo", Value::Table(BTreeMap::new())) { + return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) } } Ok(Some(_)) => { } @@ -70,16 +72,16 @@ impl<'a> IntoTask<'a> for TTask { return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) } } - match header.set("todo.uuid", Value::String(format!("{}",uuid))) { - Ok(_) => { }, - Err(e) => { - return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) - } + + if let Err(e) = header.set("todo.uuid", Value::String(format!("{}",uuid))) { + return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) } } + // If none of the errors above have returned the function, everything is fine Ok(Task { flentry : fle } ) } } } + } From f3dc1e90af12a9477f80f7f9c575c9f591bdf040 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 20:04:22 +0200 Subject: [PATCH 54/98] The Task type can have a unnamed member --- libimagtodo/src/task.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 277a5e40..87429683 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -12,17 +12,13 @@ use result::Result; /// Task struct containing a `FileLockEntry` #[derive(Debug)] -pub struct Task<'a> { - pub flentry : FileLockEntry<'a>, -} +pub struct Task<'a>(FileLockEntry<'a>); impl<'a> Task<'a> { /// Concstructs a new `Task` with a `FileLockEntry` - pub fn new(fle : FileLockEntry<'a>) -> Task<'a> { - Task { - flentry : fle - } + pub fn new(fle: FileLockEntry<'a>) -> Task<'a> { + Task(fle) } } @@ -79,7 +75,7 @@ impl<'a> IntoTask<'a> for TTask { } // If none of the errors above have returned the function, everything is fine - Ok(Task { flentry : fle } ) + Ok(Task::new(fle)) } } } From 07ab966d3797ad4d98898f087024d5039b5f6bf7 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 20:05:37 +0200 Subject: [PATCH 55/98] Impl {Deref, DerefMut} for Task --- libimagtodo/src/task.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 87429683..0c68e4c0 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -1,4 +1,6 @@ use std::collections::BTreeMap; +use std::ops::{Deref, DerefMut}; + use toml::Value; use task_hookrs::task::Task as TTask; @@ -23,6 +25,23 @@ impl<'a> Task<'a> { } +impl<'a> Deref for Task<'a> { + type Target = FileLockEntry<'a>; + + fn deref(&self) -> &FileLockEntry<'a> { + &self.0 + } + +} + +impl<'a> DerefMut for Task<'a> { + + fn deref_mut(&mut self) -> &mut FileLockEntry<'a> { + &mut self.0 + } + +} + /// A trait to get a `libimagtodo::task::Task` out of the implementing object. /// This Task struct is merely a wrapper for a `FileLockEntry`, therefore the function name /// `into_filelockentry`. From df5abef44795ee4c6710232909ef1f2e98b87083 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 20:08:50 +0200 Subject: [PATCH 56/98] Move delete functionality to the place where it belongs --- libimagtodo/src/delete.rs | 19 ------------------- libimagtodo/src/lib.rs | 1 - libimagtodo/src/task.rs | 6 ++++++ 3 files changed, 6 insertions(+), 20 deletions(-) delete mode 100644 libimagtodo/src/delete.rs diff --git a/libimagtodo/src/delete.rs b/libimagtodo/src/delete.rs deleted file mode 100644 index ed56dc0c..00000000 --- a/libimagtodo/src/delete.rs +++ /dev/null @@ -1,19 +0,0 @@ -use uuid::Uuid; - -use libimagstore::store::Store; -use libimagstore::storeid::IntoStoreId; -use module_path::ModuleEntryPath; - -use error::{TodoError, TodoErrorKind}; - -/// With the uuid we get the storeid and then we can delete the entry -pub fn delete(store : &Store, uuid: Uuid) -> Result<(),TodoError> { - // With the uuid we get the storeid - let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); - // It deletes an entry - match store.delete(store_id) { - Ok(val) => Ok(val), - Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), - } -} - diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index 0396704a..cf1f966c 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -7,7 +7,6 @@ extern crate task_hookrs; module_entry_path_mod!("todo", "0.1.0"); -pub mod delete; pub mod error; pub mod read; pub mod result; diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 0c68e4c0..ebfb4b7e 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -2,6 +2,7 @@ use std::collections::BTreeMap; use std::ops::{Deref, DerefMut}; use toml::Value; +use uuid::Uuid; use task_hookrs::task::Task as TTask; @@ -23,6 +24,11 @@ impl<'a> Task<'a> { Task(fle) } + pub fn delete_by_uuid(store: &Store, uuid: Uuid) -> Result<()> { + store.delete(ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid()) + .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) + } + } impl<'a> Deref for Task<'a> { From c9be7a7483a076a2ffc240adc9100a7e22a6a7f7 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 20:11:31 +0200 Subject: [PATCH 57/98] Move read::* code to the place where it belongs --- libimagtodo/src/lib.rs | 1 - libimagtodo/src/read.rs | 49 ----------------------------------------- libimagtodo/src/task.rs | 47 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 51 deletions(-) delete mode 100644 libimagtodo/src/read.rs diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index cf1f966c..bc217a4b 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -8,7 +8,6 @@ extern crate task_hookrs; module_entry_path_mod!("todo", "0.1.0"); pub mod error; -pub mod read; pub mod result; pub mod task; diff --git a/libimagtodo/src/read.rs b/libimagtodo/src/read.rs deleted file mode 100644 index f547ac30..00000000 --- a/libimagtodo/src/read.rs +++ /dev/null @@ -1,49 +0,0 @@ -use libimagstore::storeid::{StoreIdIterator, StoreId}; -use libimagstore::store::Store; -use error::{TodoError, TodoErrorKind}; -use task::Task; -use result::Result; - -pub fn get_todo_iterator(store: &Store) -> Result { - store.retrieve_for_module("todo/taskwarrior") - .map(|iter| TaskIterator::new(store, iter)) - .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) -} - -trait FromStoreId { - fn from_storeid<'a>(&'a Store, StoreId) -> Result>; -} - -impl<'a> FromStoreId for Task<'a> { - - fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result> { - match store.retrieve(id) { - Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), - Ok(c) => Ok(Task::new( c )), - } - } -} - -pub struct TaskIterator<'a> { - store: &'a Store, - iditer: StoreIdIterator, -} - -impl<'a> TaskIterator<'a> { - - pub fn new(store: &'a Store, iditer: StoreIdIterator) -> TaskIterator<'a> { - TaskIterator { - store: store, - iditer: iditer, - } - } - -} - -impl<'a> Iterator for TaskIterator<'a> { - type Item = Result>; - - fn next(&mut self) -> Option>> { - self.iditer.next().map(|id| Task::from_storeid(self.store, id)) - } -} diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index ebfb4b7e..3bf897d8 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -7,7 +7,7 @@ use uuid::Uuid; use task_hookrs::task::Task as TTask; use libimagstore::store::{FileLockEntry, Store}; -use libimagstore::storeid::IntoStoreId; +use libimagstore::storeid::{IntoStoreId, StoreIdIterator, StoreId}; use module_path::ModuleEntryPath; use error::{TodoError, TodoErrorKind}; @@ -29,6 +29,12 @@ impl<'a> Task<'a> { .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) } + pub fn all(store: &Store) -> Result { + store.retrieve_for_module("todo/taskwarrior") + .map(|iter| TaskIterator::new(store, iter)) + .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) + } + } impl<'a> Deref for Task<'a> { @@ -106,3 +112,42 @@ impl<'a> IntoTask<'a> for TTask { } } + +trait FromStoreId { + fn from_storeid<'a>(&'a Store, StoreId) -> Result>; +} + +impl<'a> FromStoreId for Task<'a> { + + fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result> { + match store.retrieve(id) { + Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))), + Ok(c) => Ok(Task::new( c )), + } + } +} + +pub struct TaskIterator<'a> { + store: &'a Store, + iditer: StoreIdIterator, +} + +impl<'a> TaskIterator<'a> { + + pub fn new(store: &'a Store, iditer: StoreIdIterator) -> TaskIterator<'a> { + TaskIterator { + store: store, + iditer: iditer, + } + } + +} + +impl<'a> Iterator for TaskIterator<'a> { + type Item = Result>; + + fn next(&mut self) -> Option>> { + self.iditer.next().map(|id| Task::from_storeid(self.store, id)) + } +} + From 879fa3fb482caa2953a5706bf827409902ad5bcc Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 20:13:20 +0200 Subject: [PATCH 58/98] Provide more detailed access to the ids and tasks --- libimagtodo/src/task.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 3bf897d8..db757735 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -29,12 +29,16 @@ impl<'a> Task<'a> { .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) } - pub fn all(store: &Store) -> Result { + pub fn all_as_ids(store: &Store) -> Result { store.retrieve_for_module("todo/taskwarrior") - .map(|iter| TaskIterator::new(store, iter)) .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) } + pub fn all(store: &Store) -> Result { + Task::all_as_ids(store) + .map(|iter| TaskIterator::new(store, iter)) + } + } impl<'a> Deref for Task<'a> { From a8bb444f1d52ea51f4eed2a955bae4509e1bdfe3 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 6 Jul 2016 20:14:26 +0200 Subject: [PATCH 59/98] Fix misleading function name --- imag-todo/src/main.rs | 2 +- libimagtodo/src/task.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 4b31a7b6..85ab4647 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -73,7 +73,7 @@ fn tw_hook(rt: &Runtime) { } let uuid = *ttask.uuid(); - match ttask.into_filelockentry(rt.store()) { + match ttask.into_task(rt.store()) { Ok(val) => { println!("Task {} stored in imag", uuid); val diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index db757735..eb5663e1 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -77,13 +77,13 @@ pub trait IntoTask<'a> { /// println!("Task with uuid: {}", task.flentry.get_header().get("todo.uuid")); /// } /// ``` - fn into_filelockentry(self, store : &'a Store) -> Result>; + fn into_task(self, store : &'a Store) -> Result>; } impl<'a> IntoTask<'a> for TTask { - fn into_filelockentry(self, store : &'a Store) -> Result> { + fn into_task(self, store : &'a Store) -> Result> { let uuid = self.uuid(); let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); From b7f4b6317ed47bdc1db241486f64af39e54c71aa Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 7 Jul 2016 16:20:00 +0200 Subject: [PATCH 60/98] Adapt for new interface of libimagtodo --- imag-todo/src/main.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 85ab4647..cde6cf43 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -22,6 +22,7 @@ use task_hookrs::import::{import_task, import_tasks}; use libimagrt::runtime::Runtime; use libimagtodo::task::IntoTask; +use libimagtodo::task::Task; use libimagerror::trace::trace_error; mod ui; @@ -111,7 +112,7 @@ fn tw_hook(rt: &Runtime) { match ttask.status() { &task_hookrs::status::TaskStatus::Deleted => { - match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) { + match Task::delete_by_uuid(rt.store(), *ttask.uuid()) { Ok(_) => println!("Deleted task {}", *ttask.uuid()), Err(e) => { trace_error(&e); @@ -141,18 +142,18 @@ fn list(rt: &Runtime) { let subcmd = rt.cli().subcommand_matches("list").unwrap(); let mut args = Vec::new(); let verbose = subcmd.is_present("verbose"); - let iter = match libimagtodo::read::get_todo_iterator(rt.store()) { - Err(e) => { + let iter = match Task::all(rt.store()) { + Ok(iter) => iter, + Err(e) => { trace_error(&e); exit(1); - } - Ok(val) => val, + }, }; for task in iter { match task { Ok(val) => { - let uuid = match val.flentry.get_header().read("todo.uuid") { + let uuid = match val.get_header().read("todo.uuid") { Ok(Some(u)) => u, Ok(None) => continue, Err(e) => { From 053c5c13e8ddc350fe36f725728ba8ffd5806453 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 8 Jul 2016 21:49:23 +0200 Subject: [PATCH 61/98] Use generate_runtime_setup() instead of doing it manually --- imag-todo/src/main.rs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index cde6cf43..cf2453c9 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -21,6 +21,7 @@ use std::io::BufRead; use task_hookrs::import::{import_task, import_tasks}; use libimagrt::runtime::Runtime; +use libimagrt::setup::generate_runtime_setup; use libimagtodo::task::IntoTask; use libimagtodo::task::Task; use libimagerror::trace::trace_error; @@ -29,21 +30,10 @@ mod ui; use ui::build_ui; fn main() { - let name = "imag-todo"; - let version = &version!()[..]; - let about = "Interface with taskwarrior"; - let ui = build_ui(Runtime::get_default_cli_builder(name, version, about)); - - let rt = { - let rt = Runtime::new(ui); - if rt.is_ok() { - rt.unwrap() - } else { - println!("Could not set up Runtime"); - println!("{:?}", rt.unwrap_err()); - exit(1); - } - }; + let rt = generate_runtime_setup("imag-todo", + &version!()[..], + "Interface with taskwarrior", + build_ui); match rt.cli().subcommand_name() { Some("tw-hook") => tw_hook(&rt), From f55f1e627e2ad99c6a558f75ac0841d64eff06c3 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Jul 2016 16:23:39 +0200 Subject: [PATCH 62/98] Rewrite error module --- libimagtodo/src/error.rs | 74 ++++++---------------------------------- 1 file changed, 10 insertions(+), 64 deletions(-) diff --git a/libimagtodo/src/error.rs b/libimagtodo/src/error.rs index 58fe7758..8aa42410 100644 --- a/libimagtodo/src/error.rs +++ b/libimagtodo/src/error.rs @@ -1,66 +1,12 @@ -use std::error::Error; -use std::clone::Clone; -use std::fmt::Error as FmtError; -use std::fmt::{Display, Formatter}; +generate_error_module!( + generate_error_types!(TodoError, TodoErrorKind, + ConversionError => "Conversion Error", + StoreError => "Store Error", + ImportError => "Error importing" + ); +); -/// Enum of Error Types, as of now we have two: -/// * ConversionError: for Errors concerning conversion failures from task_hookrs::task::Task to -/// libimagtodo::task::Task. unused. -/// * StoreError: For Errors thrown by functions of the Store/structs relates to the Store -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum TodoErrorKind { - ConversionError, - StoreError, -} +pub use self::error::TodoError; +pub use self::error::TodoErrorKind; +pub use self::error::MapErrInto; -/// Maps a TodoErrorKind to a String -fn todo_error_type_as_str(e: &TodoErrorKind) -> &'static str { - match e { - &TodoErrorKind::ConversionError => "Conversion Error", - &TodoErrorKind::StoreError => "Store Error", - } -} - -impl Display for TodoErrorKind { - fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> { - try!(write!(fmt, "{}", todo_error_type_as_str(self))); - Ok(()) - } -} - -/// Error struct for the imag-todo module -#[derive(Debug)] -pub struct TodoError { - err_type : TodoErrorKind, - cause : Option>, -} - -impl TodoError { - /// Creates a new TodoError, with TodoErrorKind errtype and an optional cause - pub fn new(errtype : TodoErrorKind, cause : Option>) -> TodoError { - TodoError { - err_type : errtype, - cause : cause, - } - } - /// Returns the error type (TodoErrorKind) - pub fn err_type(&self) -> TodoErrorKind { - self.err_type.clone() - } -} - -impl Display for TodoError { - fn fmt(&self, fmt : &mut Formatter) -> Result<(), FmtError> { - try!(write!(fmt, "[{}]", todo_error_type_as_str(&self.err_type.clone()))); - Ok(()) - } -} - -impl Error for TodoError { - fn description(&self) -> &str { - todo_error_type_as_str(&self.err_type.clone()) - } - fn cause(&self) -> Option<&Error> { - self.cause.as_ref().map(|e| &**e) - } -} From e63f17d51e4f025548a05069b32ae7fdead9ba16 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Jul 2016 16:24:15 +0200 Subject: [PATCH 63/98] Add dependency: libimagerror --- libimagtodo/Cargo.toml | 4 ++++ libimagtodo/src/lib.rs | 1 + 2 files changed, 5 insertions(+) diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index b6582ac4..a3b652c5 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -11,3 +11,7 @@ toml = "0.1.28" [dependencies.libimagstore] path = "../libimagstore" + +[dependencies.libimagerror] +path = "../libimagerror" + diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index bc217a4b..10966aba 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -3,6 +3,7 @@ extern crate uuid; extern crate toml; #[macro_use] extern crate libimagstore; +#[macro_use] extern crate libimagerror; extern crate task_hookrs; module_entry_path_mod!("todo", "0.1.0"); From 0041a648c34ddeed4d8e636ee0fb2534114b37dd Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Jul 2016 16:33:49 +0200 Subject: [PATCH 64/98] Add Task::import() --- libimagtodo/src/task.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index eb5663e1..bc306b80 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -1,16 +1,18 @@ use std::collections::BTreeMap; use std::ops::{Deref, DerefMut}; +use std::io::BufRead; use toml::Value; use uuid::Uuid; use task_hookrs::task::Task as TTask; +use task_hookrs::import::{import_task, import_tasks}; use libimagstore::store::{FileLockEntry, Store}; use libimagstore::storeid::{IntoStoreId, StoreIdIterator, StoreId}; use module_path::ModuleEntryPath; -use error::{TodoError, TodoErrorKind}; +use error::{TodoError, TodoErrorKind, MapErrInto}; use result::Result; /// Task struct containing a `FileLockEntry` @@ -24,6 +26,17 @@ impl<'a> Task<'a> { Task(fle) } + pub fn import(store: &'a Store, mut r: R) -> Result<(Task<'a>, Uuid)> { + let mut line = String::new(); + r.read_line(&mut line); + import_task(&line.as_str()) + .map_err_into(TodoErrorKind::ImportError) + .and_then(|t| { + let uuid = t.uuid().clone(); + t.into_task(store).map(|t| (t, uuid)) + }) + } + pub fn delete_by_uuid(store: &Store, uuid: Uuid) -> Result<()> { store.delete(ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid()) .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) From b918f4abbe095f1cba64a187824fb55bd5620700 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Jul 2016 16:35:24 +0200 Subject: [PATCH 65/98] Rewrite UI with Task::import() --- imag-todo/src/main.rs | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index cf2453c9..4bad0a26 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -47,36 +47,13 @@ fn tw_hook(rt: &Runtime) { if subcmd.is_present("add") { let stdin = stdin(); let mut stdin = stdin.lock(); - let mut line = String::new(); - if let Err(e) = stdin.read_line(&mut line) { - trace_error(&e); - exit(1); - }; - - if let Ok(ttask) = import_task(&line.as_str()) { - match serde_json::ser::to_string(&ttask) { - Ok(val) => println!("{}", val), - Err(e) => { - trace_error(&e); - exit(1); - } + match Task::import(rt.store(), stdin) { + Ok((_, uuid)) => info!("Task {} stored in imag", uuid), + Err(e) => { + trace_error(&e); + exit(1); } - - let uuid = *ttask.uuid(); - match ttask.into_task(rt.store()) { - Ok(val) => { - println!("Task {} stored in imag", uuid); - val - }, - Err(e) => { - trace_error(&e); - exit(1); - } - }; - } else { - error!("No usable input"); - exit(1); } } else if subcmd.is_present("delete") { // The used hook is "on-modify". This hook gives two json-objects From f3639d34ebcead1840aa7160cdae12e701038d0c Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Jul 2016 16:50:18 +0200 Subject: [PATCH 66/98] Add more required functionality, not implemented yet --- libimagtodo/src/task.rs | 112 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index bc306b80..fa92a8de 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -37,6 +37,118 @@ impl<'a> Task<'a> { }) } + /// Get a task from an import string. That is: read the imported string, get the UUID from it + /// and try to load this UUID from store. + /// + /// Possible return values are: + /// + /// * Ok(Ok(Task)) + /// * Ok(Err(String)) - where the String is the String read from the `r` parameter + /// * Err(_) - where the error is an error that happened during evaluation + /// + pub fn get_from_import(store: &'a Store, mut r: R) -> Result, String>> + { + unimplemented!() + } + + /// Get a task from a String. The String is expected to contain the JSON-representation of the + /// Task to get from the store (only the UUID really matters in this case) + pub fn get_from_string(store: &'a Store, s: String) -> Result> { + unimplemented!() + } + + /// Get a task from an UUID. + pub fn get_from_uuid(store: &'a Store, uuid: Uuid) -> Result> { + unimplemented!() + } + + /// Same as Task::get_from_import() but uses Store::retrieve() rather than Store::get(), to + /// implicitely create the task if it does not exist. + pub fn retrieve_from_import(store: &'a Store, mut r: R) -> Result> { + unimplemented!() + } + + /// Retrieve a task from a String. The String is expected to contain the JSON-representation of + /// the Task to retrieve from the store (only the UUID really matters in this case) + pub fn retrieve_from_string(store: &'a Store, s: String) -> Result> { + unimplemented!() + } + + /// Retrieve a task from an UUID. + pub fn retrieve_from_uuid(store: &'a Store, uuid: Uuid) -> Result> { + unimplemented!() + } + + /// Call `Task::update_from_imports_with()` function with `Task::copy_information()` + pub fn update_from_imports(store: &'a Store, mut r: R) -> Result<(Task<'a>, + Task<'a>)> { + unimplemented!() + } + + /// Call `Task::update_from_strings_with()` function with `Task::copy_information()` + pub fn update_from_strings(store: &'a Store, old_t: String, new_t: String) -> Result<(Task<'a>, Task<'a>)> + where R: BufRead + { + unimplemented!() + } + + /// Call `Task::update_from_uuid_and_string_with()` function with `Task::copy_information()` + pub fn update_from_uuid_and_string(store: &'a Store, old_t: Uuid, new_t: String) -> Result<(Task<'a>, Task<'a>)> + where R: BufRead + { + unimplemented!() + } + + /// Update a task from imports. + /// + /// Expects the `r` variable to return two JSON objects, the first one beeing the Task before + /// the modification, the second one after the modification. + /// + /// It then tries to load the first task, getting the corrosponding object from the store, + /// and updating the task with the new information. That is + /// + /// * Writing a new task object to the store + /// * Copying all information from the header of the old task to the new task via + /// the passed copy-functionality + /// * Returning both Task objects in a tuple (old, new) + /// + pub fn update_from_imports_with(store: &'a Store, mut r: R, f: F) -> Result<(Task<'a>, Task<'a>)> + where R: BufRead, + F: Fn(&mut Task<'a>, &mut Task<'a>) -> Result<()> + { + unimplemented!() + } + + /// Same as `Task::update_from_imports_with()` but with two Strings rather than reading from a + /// BufRead. Expects both Strings to contain readable JSON. + pub fn update_from_strings_with(store: &'a Store, old_t: String, new_t: String, f: F) -> Result<(Task<'a>, Task<'a>)> + where R: BufRead, + F: Fn(&mut Task<'a>, &mut Task<'a>) -> Result<()> + { + unimplemented!() + } + + /// Same as `Task::update_from_strings_with()` but with the parameter for the old task beeing + /// the uuid of the task. + pub fn update_from_uuid_and_string_with(store: &'a Store, old_t: Uuid, new_t: String, f: F) -> Result<(Task<'a>, Task<'a>)> + where R: BufRead, + F: Fn(&mut Task<'a>, &mut Task<'a>) -> Result<()> + { + unimplemented!() + } + + /// Copy information from one task to the second task. This function can be used to copy + /// information from one task to another. + /// + /// Two kinds of informations are copied: + /// + /// 1. links (via libimagentrylink) + /// 1. tags (via libimagentrytag) + /// + pub fn copy_information(old_task: &mut Task<'a>, new_task: &mut Task<'a>) -> Result<()> { + unimplemented!() + } + pub fn delete_by_uuid(store: &Store, uuid: Uuid) -> Result<()> { store.delete(ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid()) .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) From 1ec11749f23adcf3bf8b8a9d06cd2ea4d75638b6 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 15:18:33 +0200 Subject: [PATCH 67/98] We can't actually retrieve() from a UUID, as we cannot implicitely create a task from a UUID --- libimagtodo/src/task.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index fa92a8de..2d978cb9 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -74,11 +74,6 @@ impl<'a> Task<'a> { unimplemented!() } - /// Retrieve a task from an UUID. - pub fn retrieve_from_uuid(store: &'a Store, uuid: Uuid) -> Result> { - unimplemented!() - } - /// Call `Task::update_from_imports_with()` function with `Task::copy_information()` pub fn update_from_imports(store: &'a Store, mut r: R) -> Result<(Task<'a>, Task<'a>)> { From 9ff26360e454cb0df6d3cc6c7aa0c0d129d83d98 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 15:21:13 +0200 Subject: [PATCH 68/98] Remove the Task::update...() foo, as we do only store UUIDs which do not change --- libimagtodo/src/task.rs | 70 ----------------------------------------- 1 file changed, 70 deletions(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 2d978cb9..101f3288 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -74,76 +74,6 @@ impl<'a> Task<'a> { unimplemented!() } - /// Call `Task::update_from_imports_with()` function with `Task::copy_information()` - pub fn update_from_imports(store: &'a Store, mut r: R) -> Result<(Task<'a>, - Task<'a>)> { - unimplemented!() - } - - /// Call `Task::update_from_strings_with()` function with `Task::copy_information()` - pub fn update_from_strings(store: &'a Store, old_t: String, new_t: String) -> Result<(Task<'a>, Task<'a>)> - where R: BufRead - { - unimplemented!() - } - - /// Call `Task::update_from_uuid_and_string_with()` function with `Task::copy_information()` - pub fn update_from_uuid_and_string(store: &'a Store, old_t: Uuid, new_t: String) -> Result<(Task<'a>, Task<'a>)> - where R: BufRead - { - unimplemented!() - } - - /// Update a task from imports. - /// - /// Expects the `r` variable to return two JSON objects, the first one beeing the Task before - /// the modification, the second one after the modification. - /// - /// It then tries to load the first task, getting the corrosponding object from the store, - /// and updating the task with the new information. That is - /// - /// * Writing a new task object to the store - /// * Copying all information from the header of the old task to the new task via - /// the passed copy-functionality - /// * Returning both Task objects in a tuple (old, new) - /// - pub fn update_from_imports_with(store: &'a Store, mut r: R, f: F) -> Result<(Task<'a>, Task<'a>)> - where R: BufRead, - F: Fn(&mut Task<'a>, &mut Task<'a>) -> Result<()> - { - unimplemented!() - } - - /// Same as `Task::update_from_imports_with()` but with two Strings rather than reading from a - /// BufRead. Expects both Strings to contain readable JSON. - pub fn update_from_strings_with(store: &'a Store, old_t: String, new_t: String, f: F) -> Result<(Task<'a>, Task<'a>)> - where R: BufRead, - F: Fn(&mut Task<'a>, &mut Task<'a>) -> Result<()> - { - unimplemented!() - } - - /// Same as `Task::update_from_strings_with()` but with the parameter for the old task beeing - /// the uuid of the task. - pub fn update_from_uuid_and_string_with(store: &'a Store, old_t: Uuid, new_t: String, f: F) -> Result<(Task<'a>, Task<'a>)> - where R: BufRead, - F: Fn(&mut Task<'a>, &mut Task<'a>) -> Result<()> - { - unimplemented!() - } - - /// Copy information from one task to the second task. This function can be used to copy - /// information from one task to another. - /// - /// Two kinds of informations are copied: - /// - /// 1. links (via libimagentrylink) - /// 1. tags (via libimagentrytag) - /// - pub fn copy_information(old_task: &mut Task<'a>, new_task: &mut Task<'a>) -> Result<()> { - unimplemented!() - } - pub fn delete_by_uuid(store: &Store, uuid: Uuid) -> Result<()> { store.delete(ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid()) .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) From ab613426c6793b95874e9d715c77be64645c1c74 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 15:34:10 +0200 Subject: [PATCH 69/98] Fix return types of getter functions --- libimagtodo/src/task.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 101f3288..ebb76498 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -1,6 +1,7 @@ use std::collections::BTreeMap; use std::ops::{Deref, DerefMut}; use std::io::BufRead; +use std::result::Result as RResult; use toml::Value; use uuid::Uuid; @@ -53,12 +54,16 @@ impl<'a> Task<'a> { /// Get a task from a String. The String is expected to contain the JSON-representation of the /// Task to get from the store (only the UUID really matters in this case) - pub fn get_from_string(store: &'a Store, s: String) -> Result> { + /// + /// For an explanation on the return values see `Task::get_from_import()`. + pub fn get_from_string(store: &'a Store, s: String) -> Result, String>> { unimplemented!() } /// Get a task from an UUID. - pub fn get_from_uuid(store: &'a Store, uuid: Uuid) -> Result> { + /// + /// If there is no task with this UUID, this returns `Ok(None)`. + pub fn get_from_uuid(store: &'a Store, uuid: Uuid) -> Result>> { unimplemented!() } From 475a73ee5c1034d3c59dc4804ae35c9d431dacc9 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 15:34:21 +0200 Subject: [PATCH 70/98] Impl Task::get_from_import() --- libimagtodo/src/task.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index ebb76498..36f4a75d 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -49,7 +49,9 @@ impl<'a> Task<'a> { /// pub fn get_from_import(store: &'a Store, mut r: R) -> Result, String>> { - unimplemented!() + let mut line = String::new(); + r.read_line(&mut line); + Task::get_from_string(store, line) } /// Get a task from a String. The String is expected to contain the JSON-representation of the From 302b46be5f7ccd9a05d5d3df06372554b7548ef9 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 15:34:31 +0200 Subject: [PATCH 71/98] Impl Task::get_from_string() --- libimagtodo/src/task.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 36f4a75d..3459bdfc 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -59,7 +59,14 @@ impl<'a> Task<'a> { /// /// For an explanation on the return values see `Task::get_from_import()`. pub fn get_from_string(store: &'a Store, s: String) -> Result, String>> { - unimplemented!() + import_task(s.as_str()) + .map_err_into(TodoErrorKind::ImportError) + .map(|t| t.uuid().clone()) + .and_then(|uuid| Task::get_from_uuid(store, uuid)) + .and_then(|o| match o { + None => Ok(Err(s)), + Some(t) => Ok(Ok(t)), + }) } /// Get a task from an UUID. From 58162d8d90da00201a1f780aae947ab7b2c4a292 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 15:34:41 +0200 Subject: [PATCH 72/98] Impl Task::get_from_uuid() --- libimagtodo/src/task.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 3459bdfc..127deae9 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -73,7 +73,11 @@ impl<'a> Task<'a> { /// /// If there is no task with this UUID, this returns `Ok(None)`. pub fn get_from_uuid(store: &'a Store, uuid: Uuid) -> Result>> { - unimplemented!() + let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid(); + + store.get(store_id) + .map(|o| o.map(Task::new)) + .map_err_into(TodoErrorKind::StoreError) } /// Same as Task::get_from_import() but uses Store::retrieve() rather than Store::get(), to From 077471f3da318518eebae937c089a43f475cde80 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 15:41:51 +0200 Subject: [PATCH 73/98] Impl Task::retrieve_from_string --- libimagtodo/src/task.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 127deae9..4e46feff 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -89,7 +89,13 @@ impl<'a> Task<'a> { /// Retrieve a task from a String. The String is expected to contain the JSON-representation of /// the Task to retrieve from the store (only the UUID really matters in this case) pub fn retrieve_from_string(store: &'a Store, s: String) -> Result> { - unimplemented!() + Task::get_from_string(store, s) + .and_then(|opt| match opt { + Ok(task) => Ok(task), + Err(string) => import_task(string.as_str()) + .map_err_into(TodoErrorKind::ImportError) + .and_then(|t| t.into_task(store)), + }) } pub fn delete_by_uuid(store: &Store, uuid: Uuid) -> Result<()> { From 8e4471cc07385d3dcbb210cbf4733f3584d087b8 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 15:42:02 +0200 Subject: [PATCH 74/98] Impl Task::retrieve_from_import() --- libimagtodo/src/task.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 4e46feff..c4f0f51b 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -83,7 +83,9 @@ impl<'a> Task<'a> { /// Same as Task::get_from_import() but uses Store::retrieve() rather than Store::get(), to /// implicitely create the task if it does not exist. pub fn retrieve_from_import(store: &'a Store, mut r: R) -> Result> { - unimplemented!() + let mut line = String::new(); + r.read_line(&mut line); + Task::retrieve_from_string(store, line) } /// Retrieve a task from a String. The String is expected to contain the JSON-representation of From 3af6712d8bb8688a81224c1a705ff75954c5ad7e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 21:06:11 +0200 Subject: [PATCH 75/98] Fix indentation in ui definition --- imag-todo/src/ui.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/imag-todo/src/ui.rs b/imag-todo/src/ui.rs index 7ec89d39..f781673e 100644 --- a/imag-todo/src/ui.rs +++ b/imag-todo/src/ui.rs @@ -27,16 +27,16 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .required(true)) ) - .subcommand(SubCommand::with_name("list") - .about("List all tasks") - .version("0.1") + .subcommand(SubCommand::with_name("list") + .about("List all tasks") + .version("0.1") - .arg(Arg::with_name("verbose") - .long("verbose") - .short("v") - .takes_value(false) - .required(false) - .help("Asks taskwarrior for all the details") - ) - ) + .arg(Arg::with_name("verbose") + .long("verbose") + .short("v") + .takes_value(false) + .required(false) + .help("Asks taskwarrior for all the details") + ) + ) } From ca7a9012697d5820892d732c14ac7c01cbd75f62 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 21:07:03 +0200 Subject: [PATCH 76/98] Use the right macro here --- imag-todo/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 4bad0a26..9771442e 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -38,7 +38,7 @@ fn main() { match rt.cli().subcommand_name() { Some("tw-hook") => tw_hook(&rt), Some("list") => list(&rt), - _ => unimplemented!(), + _ => unreachable!(), } // end match scmd } // end main From 0cca04c6ac31fcd358660a9efb72ded9f25b2f8e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 21:21:36 +0200 Subject: [PATCH 77/98] Use Iterator::enumerate() instead of mut variable --- imag-todo/src/main.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 9771442e..764e7bae 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -58,12 +58,11 @@ fn tw_hook(rt: &Runtime) { } else if subcmd.is_present("delete") { // The used hook is "on-modify". This hook gives two json-objects // per usage und wants one (the second one) back. - let mut counter = 0; let stdin = stdin(); let stdin = stdin.lock(); match import_tasks(stdin) { - Ok(ttasks) => for ttask in ttasks { + Ok(ttasks) => for (counter, ttask) in ttasks.enumerate() { if counter % 2 == 1 { // Only every second task is needed, the first one is the // task before the change, and the second one after @@ -91,7 +90,6 @@ fn tw_hook(rt: &Runtime) { } } // end match ttask.status() } // end if c % 2 - counter += 1; }, Err(e) => { trace_error(&e); From 8d89f7bf7443c6d515a8f8088e576ac1784fb3cc Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 21:24:49 +0200 Subject: [PATCH 78/98] Use if() instead of match here, to have less noise --- imag-todo/src/main.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 764e7bae..e7971080 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -19,6 +19,7 @@ use std::io::stdin; use std::io::BufRead; use task_hookrs::import::{import_task, import_tasks}; +use task_hookrs::status::TaskStatus; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; @@ -62,7 +63,7 @@ fn tw_hook(rt: &Runtime) { let stdin = stdin.lock(); match import_tasks(stdin) { - Ok(ttasks) => for (counter, ttask) in ttasks.enumerate() { + Ok(ttasks) => for (counter, ttask) in ttasks.iter().enumerate() { if counter % 2 == 1 { // Only every second task is needed, the first one is the // task before the change, and the second one after @@ -76,19 +77,15 @@ fn tw_hook(rt: &Runtime) { } } - match ttask.status() { - &task_hookrs::status::TaskStatus::Deleted => { - match Task::delete_by_uuid(rt.store(), *ttask.uuid()) { - Ok(_) => println!("Deleted task {}", *ttask.uuid()), - Err(e) => { - trace_error(&e); - exit(1); - } + if *ttask.status() == TaskStatus::Deleted { + match Task::delete_by_uuid(rt.store(), *ttask.uuid()) { + Ok(_) => println!("Deleted task {}", *ttask.uuid()), + Err(e) => { + trace_error(&e); + exit(1); } } - _ => { - } - } // end match ttask.status() + } } // end if c % 2 }, Err(e) => { From 1f50301ffa41225b2f6f2d8a501eae4d8d26fed2 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 21:27:28 +0200 Subject: [PATCH 79/98] Do not use "mut" here, we don't need it --- imag-todo/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index e7971080..959d9271 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -46,8 +46,8 @@ fn main() { fn tw_hook(rt: &Runtime) { let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap(); if subcmd.is_present("add") { - let stdin = stdin(); - let mut stdin = stdin.lock(); + let stdin = stdin(); + let stdin = stdin.lock(); match Task::import(rt.store(), stdin) { Ok((_, uuid)) => info!("Task {} stored in imag", uuid), From 0da8df3c2680b62bcbb1a13b42efa11996d6810d Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 15 Jul 2016 21:37:51 +0200 Subject: [PATCH 80/98] Remove unused imports --- imag-todo/src/main.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 959d9271..b0d5ee0e 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -16,14 +16,12 @@ extern crate libimagtodo; use std::process::exit; use std::process::{Command, Stdio}; use std::io::stdin; -use std::io::BufRead; -use task_hookrs::import::{import_task, import_tasks}; +use task_hookrs::import::import_tasks; use task_hookrs::status::TaskStatus; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; -use libimagtodo::task::IntoTask; use libimagtodo::task::Task; use libimagerror::trace::trace_error; From 98a8356150f1525a133b31d5085f6245c5fd3cf7 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 21 Jul 2016 15:54:38 +0200 Subject: [PATCH 81/98] Reimplement list() --- imag-todo/src/main.rs | 101 ++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 54 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index b0d5ee0e..ecf127eb 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -17,6 +17,8 @@ use std::process::exit; use std::process::{Command, Stdio}; use std::io::stdin; +use toml::Value; + use task_hookrs::import::import_tasks; use task_hookrs::status::TaskStatus; @@ -99,63 +101,54 @@ fn tw_hook(rt: &Runtime) { } fn list(rt: &Runtime) { - let subcmd = rt.cli().subcommand_matches("list").unwrap(); - let mut args = Vec::new(); - let verbose = subcmd.is_present("verbose"); - let iter = match Task::all(rt.store()) { - Ok(iter) => iter, - Err(e) => { - trace_error(&e); - exit(1); - }, - }; + let subcmd = rt.cli().subcommand_matches("list").unwrap(); + let verbose = subcmd.is_present("verbose"); - for task in iter { - match task { - Ok(val) => { - let uuid = match val.get_header().read("todo.uuid") { - Ok(Some(u)) => u, - Ok(None) => continue, - Err(e) => { + let res = Task::all(rt.store()) + .map(|iter| { + let uuids : Vec<_> = iter.filter_map(|t| match t { + Ok(v) => match v.get_header().read("todo.uuid") { + Ok(Some(Value::String(ref u))) => Some(u.clone()), + Ok(Some(_)) => { + warn!("Header type error"); + None + }, + Ok(None) => None, + Err(e) => { trace_error(&e); - continue; + None } - }; - - if verbose { - args.clear(); - args.push(format!("uuid:{} information", uuid)); - - let tw_process = Command::new("task") - .stdin(Stdio::null()) - .args(&args) - .spawn() - .unwrap_or_else(|e| { - trace_error(&e); - panic!("failed"); - }); - let output = tw_process - .wait_with_output() - .unwrap_or_else(|e| panic!("failed to unwrap output: {}", e)); - let outstring = String::from_utf8(output.stdout) - .unwrap_or_else(|e| panic!("failed to execute: {}", e)); - - println!("{}", outstring); - } else { - println!("{}", match uuid { - toml::Value::String(s) => s, - _ => { - error!("Unexpected type for todo.uuid: {}", uuid); - continue; - }, - }); + }, + Err(e) => { + trace_error(&e); + None } - } - Err(e) => { - trace_error(&e); - continue; - } - } // end match task - } // end for + }) + .collect(); + + let outstring = if verbose { + let output = Command::new("task") + .stdin(Stdio::null()) + .args(&uuids) + .spawn() + .unwrap_or_else(|e| { + trace_error(&e); + panic!("Failed to execute `task` on the commandline. I'm dying now."); + }) + .wait_with_output() + .unwrap_or_else(|e| panic!("failed to unwrap output: {}", e)); + + String::from_utf8(output.stdout) + .unwrap_or_else(|e| panic!("failed to execute: {}", e)) + } else { + uuids.join("\n") + }; + + println!("{}", outstring); + }); + + if let Err(e) = res { + trace_error(&e); + } } From 01ee30537ea732edc7886cd5fbdc30f1ab6c13f9 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 10:07:26 +0200 Subject: [PATCH 82/98] Add note why we stdin.lock() here --- imag-todo/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index ecf127eb..cde1268d 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -47,7 +47,7 @@ fn tw_hook(rt: &Runtime) { let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap(); if subcmd.is_present("add") { let stdin = stdin(); - let stdin = stdin.lock(); + let stdin = stdin.lock(); // implements BufRead which is required for `Task::import()` match Task::import(rt.store(), stdin) { Ok((_, uuid)) => info!("Task {} stored in imag", uuid), From d0592d002956468fee6c9edd994667541ea97ccb Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 10:11:22 +0200 Subject: [PATCH 83/98] Return the imported string as well --- libimagtodo/src/task.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index c4f0f51b..c57640a7 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -27,14 +27,14 @@ impl<'a> Task<'a> { Task(fle) } - pub fn import(store: &'a Store, mut r: R) -> Result<(Task<'a>, Uuid)> { + pub fn import(store: &'a Store, mut r: R) -> Result<(Task<'a>, String, Uuid)> { let mut line = String::new(); r.read_line(&mut line); import_task(&line.as_str()) .map_err_into(TodoErrorKind::ImportError) .and_then(|t| { let uuid = t.uuid().clone(); - t.into_task(store).map(|t| (t, uuid)) + t.into_task(store).map(|t| (t, line, uuid)) }) } From 0d2cd16e940ad4f7ea6b0836032a6c6c37c7908d Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 10:11:42 +0200 Subject: [PATCH 84/98] Print the imported string before the information output --- imag-todo/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index cde1268d..e373d3f7 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -50,7 +50,7 @@ fn tw_hook(rt: &Runtime) { let stdin = stdin.lock(); // implements BufRead which is required for `Task::import()` match Task::import(rt.store(), stdin) { - Ok((_, uuid)) => info!("Task {} stored in imag", uuid), + Ok((_, line, uuid)) => info!("{}\nTask {} stored in imag", line, uuid), Err(e) => { trace_error(&e); exit(1); From 1a01a391f12b68c26a99b352da926a966df94146 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 10:14:01 +0200 Subject: [PATCH 85/98] Add comment to task delete procedure --- imag-todo/src/main.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index e373d3f7..28aa7464 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -77,6 +77,11 @@ fn tw_hook(rt: &Runtime) { } } + // Taskwarrior does not have the concept of deleted tasks, but only modified + // ones. + // + // Here we check if the status of a task is deleted and if yes, we delete it + // from the store. if *ttask.status() == TaskStatus::Deleted { match Task::delete_by_uuid(rt.store(), *ttask.uuid()) { Ok(_) => println!("Deleted task {}", *ttask.uuid()), From dc78b1553ea54cb3e7c64a3b301affe11686e2fe Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 10:17:26 +0200 Subject: [PATCH 86/98] Comments for listing subcommand --- imag-todo/src/main.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 28aa7464..b0d533b1 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -109,8 +109,9 @@ fn list(rt: &Runtime) { let subcmd = rt.cli().subcommand_matches("list").unwrap(); let verbose = subcmd.is_present("verbose"); - let res = Task::all(rt.store()) - .map(|iter| { + let res = Task::all(rt.store()) // get all tasks + .map(|iter| { // and if this succeeded + // filter out the ones were we can read the uuid let uuids : Vec<_> = iter.filter_map(|t| match t { Ok(v) => match v.get_header().read("todo.uuid") { Ok(Some(Value::String(ref u))) => Some(u.clone()), @@ -131,7 +132,8 @@ fn list(rt: &Runtime) { }) .collect(); - let outstring = if verbose { + // compose a `task` call with them, ... + let outstring = if verbose { // ... if verbose let output = Command::new("task") .stdin(Stdio::null()) .args(&uuids) @@ -145,10 +147,11 @@ fn list(rt: &Runtime) { String::from_utf8(output.stdout) .unwrap_or_else(|e| panic!("failed to execute: {}", e)) - } else { + } else { // ... else just join them uuids.join("\n") }; + /// and then print that println!("{}", outstring); }); From 57c4089d80bac7219f278be35209a673bddad24b Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 10:51:16 +0200 Subject: [PATCH 87/98] Remove outdated comment part --- libimagtodo/src/task.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index c57640a7..89db1b71 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -135,8 +135,6 @@ impl<'a> DerefMut for Task<'a> { } /// A trait to get a `libimagtodo::task::Task` out of the implementing object. -/// This Task struct is merely a wrapper for a `FileLockEntry`, therefore the function name -/// `into_filelockentry`. pub trait IntoTask<'a> { /// # Usage From 6567f3a879b18020e26e649acd971dc2b9684c68 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 11:08:57 +0200 Subject: [PATCH 88/98] Fix comment which broke the build --- imag-todo/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index b0d533b1..dae6a34d 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -151,7 +151,7 @@ fn list(rt: &Runtime) { uuids.join("\n") }; - /// and then print that + // and then print that println!("{}", outstring); }); From 819f026d480cdb87e16b8ce16aa809c8412a90ff Mon Sep 17 00:00:00 2001 From: mario Date: Sat, 6 Aug 2016 11:11:40 +0200 Subject: [PATCH 89/98] change to task_hookrs 0.2.0 --- imag-todo/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imag-todo/Cargo.toml b/imag-todo/Cargo.toml index 845a0901..a5b84d8f 100644 --- a/imag-todo/Cargo.toml +++ b/imag-todo/Cargo.toml @@ -9,7 +9,7 @@ glob = "0.2.11" log = "0.3.6" semver = "0.2.3" serde_json = "0.7.3" -task-hookrs = { git = "https://github.com/mario-kr/task-hookrs.git" } +task-hookrs = "0.2.0" toml = "0.1.28" version = "2.0.1" From 71bce41e0f5dd867cca62ce263d3db22541490cc Mon Sep 17 00:00:00 2001 From: mario Date: Sat, 6 Aug 2016 11:23:52 +0200 Subject: [PATCH 90/98] change to task_hookrs 0.2.0 --- imag-todo/Cargo.toml | 2 +- libimagtodo/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imag-todo/Cargo.toml b/imag-todo/Cargo.toml index a5b84d8f..0580c74f 100644 --- a/imag-todo/Cargo.toml +++ b/imag-todo/Cargo.toml @@ -8,7 +8,7 @@ clap = "2.4.3" glob = "0.2.11" log = "0.3.6" semver = "0.2.3" -serde_json = "0.7.3" +serde_json = "0.7.4" task-hookrs = "0.2.0" toml = "0.1.28" version = "2.0.1" diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index a3b652c5..a1dd4294 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -5,7 +5,7 @@ authors = ["mario "] [dependencies] semver = "0.2" -task-hookrs = { git = "https://github.com/mario-kr/task-hookrs.git" } +task-hookrs = "0.2" uuid = "0.2.0" toml = "0.1.28" From 6d14212042a28ca73a783d3e87e44d25a7046313 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 11:30:25 +0200 Subject: [PATCH 91/98] Add dependency: log --- libimagtodo/Cargo.toml | 1 + libimagtodo/src/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index a1dd4294..7dcb5516 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -8,6 +8,7 @@ semver = "0.2" task-hookrs = "0.2" uuid = "0.2.0" toml = "0.1.28" +log = "0.3.6" [dependencies.libimagstore] path = "../libimagstore" diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index 10966aba..169f0748 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -1,6 +1,7 @@ extern crate semver; extern crate uuid; extern crate toml; +#[macro_use] extern crate log; #[macro_use] extern crate libimagstore; #[macro_use] extern crate libimagerror; From 6222aac83774ac3da2ca5c0e9cf892e359839beb Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 11:31:49 +0200 Subject: [PATCH 92/98] Add dependency: serde_json --- libimagtodo/Cargo.toml | 1 + libimagtodo/src/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index 7dcb5516..7ef12711 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -9,6 +9,7 @@ task-hookrs = "0.2" uuid = "0.2.0" toml = "0.1.28" log = "0.3.6" +serde_json = "0.7.3" [dependencies.libimagstore] path = "../libimagstore" diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index 169f0748..3189021d 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -2,6 +2,7 @@ extern crate semver; extern crate uuid; extern crate toml; #[macro_use] extern crate log; +extern crate serde_json; #[macro_use] extern crate libimagstore; #[macro_use] extern crate libimagerror; From 0fd8b3b286f42cccfa5728b13de2070a9252d35c Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 11:39:31 +0200 Subject: [PATCH 93/98] Move deletion logic into lib --- imag-todo/src/main.rs | 41 +++-------------------------------------- libimagtodo/src/task.rs | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index dae6a34d..d5149ad8 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -60,44 +60,9 @@ fn tw_hook(rt: &Runtime) { // The used hook is "on-modify". This hook gives two json-objects // per usage und wants one (the second one) back. let stdin = stdin(); - let stdin = stdin.lock(); - - match import_tasks(stdin) { - Ok(ttasks) => for (counter, ttask) in ttasks.iter().enumerate() { - if counter % 2 == 1 { - // Only every second task is needed, the first one is the - // task before the change, and the second one after - // the change. The (maybe modified) second one is - // expected by taskwarrior. - match serde_json::ser::to_string(&ttask) { - Ok(val) => println!("{}", val), - Err(e) => { - trace_error(&e); - exit(1); - } - } - - // Taskwarrior does not have the concept of deleted tasks, but only modified - // ones. - // - // Here we check if the status of a task is deleted and if yes, we delete it - // from the store. - if *ttask.status() == TaskStatus::Deleted { - match Task::delete_by_uuid(rt.store(), *ttask.uuid()) { - Ok(_) => println!("Deleted task {}", *ttask.uuid()), - Err(e) => { - trace_error(&e); - exit(1); - } - } - } - } // end if c % 2 - }, - Err(e) => { - trace_error(&e); - exit(1); - }, - } + Task::delete_by_imports(rt.store(), stdin.lock()) + .map_err(|e| trace_error(&e)) + .ok(); } else { // Should not be possible, as one argument is required via // ArgGroup diff --git a/libimagtodo/src/task.rs b/libimagtodo/src/task.rs index 89db1b71..1b44259b 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -100,6 +100,43 @@ impl<'a> Task<'a> { }) } + pub fn delete_by_imports(store: &Store, r: R) -> Result<()> { + use serde_json::ser::to_string as serde_to_string; + use task_hookrs::status::TaskStatus; + + for (counter, res_ttask) in import_tasks(r).into_iter().enumerate() { + match res_ttask { + Ok(ttask) => { + if counter % 2 == 1 { + // Only every second task is needed, the first one is the + // task before the change, and the second one after + // the change. The (maybe modified) second one is + // expected by taskwarrior. + match serde_to_string(&ttask).map_err_into(TodoErrorKind::ImportError) { + // use println!() here, as we talk with TW + Ok(val) => println!("{}", val), + Err(e) => return Err(e), + } + + // Taskwarrior does not have the concept of deleted tasks, but only modified + // ones. + // + // Here we check if the status of a task is deleted and if yes, we delete it + // from the store. + if *ttask.status() == TaskStatus::Deleted { + match Task::delete_by_uuid(store, *ttask.uuid()) { + Ok(_) => info!("Deleted task {}", *ttask.uuid()), + Err(e) => return Err(e), + } + } + } // end if c % 2 + }, + Err(e) => return Err(e).map_err_into(TodoErrorKind::ImportError), + } + } + Ok(()) + } + pub fn delete_by_uuid(store: &Store, uuid: Uuid) -> Result<()> { store.delete(ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid()) .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))) From f915a7fa269e70a87d39db1912b3b5d53b541e7f Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 11:50:50 +0200 Subject: [PATCH 94/98] We must actually use println!() here --- imag-todo/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index dae6a34d..859e7579 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -50,7 +50,7 @@ fn tw_hook(rt: &Runtime) { let stdin = stdin.lock(); // implements BufRead which is required for `Task::import()` match Task::import(rt.store(), stdin) { - Ok((_, line, uuid)) => info!("{}\nTask {} stored in imag", line, uuid), + Ok((_, line, uuid)) => println!("{}\nTask {} stored in imag", line, uuid), Err(e) => { trace_error(&e); exit(1); From 2da3eadc1cefd5b7c30c171979568bb74c2f6f8f Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 11:54:20 +0200 Subject: [PATCH 95/98] Do not panic if there was no command passed --- imag-todo/src/main.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 859e7579..446b3e7c 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -39,6 +39,9 @@ fn main() { match rt.cli().subcommand_name() { Some("tw-hook") => tw_hook(&rt), Some("list") => list(&rt), + None => { + warn!("No command"); + }, _ => unreachable!(), } // end match scmd } // end main From a860b8f25fba2ee1a25e05393084b6e2cb45f55e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 12:02:42 +0200 Subject: [PATCH 96/98] Add on-add taskwarrior hook script --- imag-todo/etc/on-add.sh | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 imag-todo/etc/on-add.sh diff --git a/imag-todo/etc/on-add.sh b/imag-todo/etc/on-add.sh new file mode 100644 index 00000000..a58e4989 --- /dev/null +++ b/imag-todo/etc/on-add.sh @@ -0,0 +1,4 @@ +#/!usr/bin/env bash + +imag todo tw-hook --add + From f967fc3d621c6c04ae02a99aac7ee890582bab36 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 12:02:54 +0200 Subject: [PATCH 97/98] Add on-modify taskwarrior hook script --- imag-todo/etc/on-modify.sh | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 imag-todo/etc/on-modify.sh diff --git a/imag-todo/etc/on-modify.sh b/imag-todo/etc/on-modify.sh new file mode 100644 index 00000000..89be96d0 --- /dev/null +++ b/imag-todo/etc/on-modify.sh @@ -0,0 +1,4 @@ +#/!usr/bin/env bash + +imag todo tw-hook --delete + From e98bc05cfcbf30a943566e955339da0815030dd2 Mon Sep 17 00:00:00 2001 From: mario Date: Sat, 6 Aug 2016 12:46:04 +0200 Subject: [PATCH 98/98] removed unused imports. functionality which required these imports has been moved to libimagtodo by matthiasbeyer --- imag-todo/src/main.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 5a457954..1163fe3c 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -19,9 +19,6 @@ use std::io::stdin; use toml::Value; -use task_hookrs::import::import_tasks; -use task_hookrs::status::TaskStatus; - use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagtodo::task::Task;