diff --git a/libimagtodo/Cargo.toml b/libimagtodo/Cargo.toml index e1621658..dc1f6d8b 100644 --- a/libimagtodo/Cargo.toml +++ b/libimagtodo/Cargo.toml @@ -4,4 +4,10 @@ version = "0.1.0" authors = ["mario "] [dependencies] +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 new file mode 100644 index 00000000..d4be3a4d --- /dev/null +++ b/libimagtodo/src/error.rs @@ -0,0 +1,67 @@ +use std::error::Error; +use std::clone::Clone; +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", + } +} + +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) + } +} diff --git a/libimagtodo/src/lib.rs b/libimagtodo/src/lib.rs index 59b0070f..2f78a6c4 100644 --- a/libimagtodo/src/lib.rs +++ b/libimagtodo/src/lib.rs @@ -1,3 +1,13 @@ +extern crate semver; +extern crate uuid; +extern crate toml; + +extern crate task_hookrs; +#[macro_use] extern crate libimagstore; + +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 a6eec643..8c3b0886 100644 --- a/libimagtodo/src/task.rs +++ b/libimagtodo/src/task.rs @@ -1,8 +1,61 @@ -extern crate task_hookrs; +use std::ops::Deref; +use toml::Value; -use self::task_hookrs::task::Task as TTask; +use task_hookrs::task::Task as TTask; -pub struct Task { - uuid : str, +use libimagstore::store::{FileLockEntry, Store}; +use libimagstore::storeid::IntoStoreId; +use module_path::ModuleEntryPath; + +use error::{TodoError, TodoErrorKind}; + +/// Task struct containing a `FileLockEntry` +#[derive(Debug)] +pub struct Task<'a> { + flentry : FileLockEntry<'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; + /// + /// 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, 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 }) + } + }, + } + } +}