diff --git a/libimagentrydate/Cargo.toml b/libimagentrydate/Cargo.toml index 428a72a5..6ea5d084 100644 --- a/libimagentrydate/Cargo.toml +++ b/libimagentrydate/Cargo.toml @@ -1,6 +1,30 @@ [package] name = "libimagentrydate" -version = "0.1.0" +version = "0.3.0" authors = ["Matthias Beyer "] +description = "Library for the imag core distribution" + +keywords = ["imag", "PIM", "personal", "information", "management"] +readme = "../README.md" +license = "LGPL-2.1" + +documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.html" +repository = "https://github.com/matthiasbeyer/imag" +homepage = "http://imag-pim.org" + [dependencies] +chrono = "0.3" +toml-query = "0.1" +lazy_static = "0.2" +toml = "0.4" + +[dependencies.libimagerror] +path = "../libimagerror" + +[dependencies.libimagstore] +path = "../libimagstore" + +[dependencies.libimagutil] +path = "../libimagutil" + diff --git a/libimagentrydate/src/entrydate.rs b/libimagentrydate/src/entrydate.rs new file mode 100644 index 00000000..46a404f5 --- /dev/null +++ b/libimagentrydate/src/entrydate.rs @@ -0,0 +1,100 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer and contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +use chrono::naive::datetime::NaiveDateTime; +use toml_query::delete::TomlValueDeleteExt; +use toml_query::insert::TomlValueInsertExt; +use toml_query::read::TomlValueReadExt; +use toml::Value; + +use libimagstore::store::Entry; +use libimagerror::into::IntoError; + +use error::DateErrorKind as DEK; +use error::*; +use result::Result; + +pub trait EntryDate { + + fn delete_date(&mut self) -> Result<()>; + fn read_date(&self) -> Result; + fn set_date(&mut self, d: NaiveDateTime) -> Result>>; + +} + +lazy_static! { + static ref DATE_HEADER_LOCATION : String = String::from("date.value"); + static ref DATE_FMT : &'static str = "%Y-%m-%d %H:%M:%S"; +} + +impl EntryDate for Entry { + + fn delete_date(&mut self) -> Result<()> { + self.get_header_mut() + .delete(&DATE_HEADER_LOCATION) + .map(|_| ()) + .map_err_into(DEK::StoreWriteError) + } + + fn read_date(&self) -> Result { + self.get_header() + .read(&DATE_HEADER_LOCATION) + .map_err_into(DEK::StoreReadError) + .and_then(|v| { + match v { + &Value::String(ref s) => s.parse::() + .map_err_into(DEK::DateTimeParsingError), + _ => Err(DEK::DateHeaderFieldTypeError.into_error()), + } + }) + } + + /// Set a Date for this entry + /// + /// # Return value + /// + /// This function returns funny things, I know. But I find it more attractive to be explicit + /// what failed when here, instead of beeing nice to the user here. + /// + /// So here's a list how things are returned: + /// + /// - Err(_) if the inserting failed + /// - Ok(None) if the inserting succeeded and _did not replace an existing value_. + /// - Ok(Some(Ok(_))) if the inserting succeeded, but replaced an existing value which then got + /// parsed into a NaiveDateTime object + /// - Ok(Some(Err(_))) if the inserting succeeded, but replaced an existing value which then + /// got parsed into a NaiveDateTime object, where the parsing failed for some reason. + /// + fn set_date(&mut self, d: NaiveDateTime) -> Result>> { + let date = d.format(&DATE_FMT).to_string(); + + self.get_header_mut() + .insert(&DATE_HEADER_LOCATION, Value::String(date)) + .map(|opt| opt.map(|stri| { + match stri { + Value::String(ref s) => s.parse::() + .map_err_into(DEK::DateTimeParsingError), + _ => Err(DEK::DateHeaderFieldTypeError.into_error()), + } + })) + .map_err_into(DEK::StoreWriteError) + } + +} + diff --git a/libimagentrydate/src/error.rs b/libimagentrydate/src/error.rs new file mode 100644 index 00000000..49f5b294 --- /dev/null +++ b/libimagentrydate/src/error.rs @@ -0,0 +1,33 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer and contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +generate_error_module!( + generate_error_types!(DateError, DateErrorKind, + StoreReadError => "Store read error", + StoreWriteError => "Store write error", + + DateHeaderFieldTypeError => "Expected the header field in the entry to have type 'String', but have other type", + DateTimeParsingError => "Error parsing DateTime" + ); +); + +pub use self::error::DateError; +pub use self::error::DateErrorKind; +pub use self::error::MapErrInto; + diff --git a/libimagentrydate/src/lib.rs b/libimagentrydate/src/lib.rs index cdfbe1aa..8e262daf 100644 --- a/libimagentrydate/src/lib.rs +++ b/libimagentrydate/src/lib.rs @@ -1,6 +1,32 @@ -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - } -} +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer and contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +#[macro_use] extern crate lazy_static; +extern crate chrono; +extern crate toml_query; +extern crate toml; + +#[macro_use] extern crate libimagerror; +extern crate libimagstore; +extern crate libimagutil; + +pub mod entrydate; +pub mod error; +pub mod result; + diff --git a/libimagentrydate/src/result.rs b/libimagentrydate/src/result.rs new file mode 100644 index 00000000..d6d0a5af --- /dev/null +++ b/libimagentrydate/src/result.rs @@ -0,0 +1,25 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer and contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +use std::result::Result as RResult; + +use error::DateError; + +pub type Result = RResult; +