diff options
Diffstat (limited to 'lib/domain/libimagdiary/src')
-rw-r--r-- | lib/domain/libimagdiary/src/config.rs | 43 | ||||
-rw-r--r-- | lib/domain/libimagdiary/src/diary.rs | 128 | ||||
-rw-r--r-- | lib/domain/libimagdiary/src/diaryid.rs | 257 | ||||
-rw-r--r-- | lib/domain/libimagdiary/src/entry.rs | 90 | ||||
-rw-r--r-- | lib/domain/libimagdiary/src/error.rs | 38 | ||||
-rw-r--r-- | lib/domain/libimagdiary/src/is_in_diary.rs | 44 | ||||
-rw-r--r-- | lib/domain/libimagdiary/src/iter.rs | 132 | ||||
-rw-r--r-- | lib/domain/libimagdiary/src/lib.rs | 62 | ||||
-rw-r--r-- | lib/domain/libimagdiary/src/result.rs | 24 | ||||
-rw-r--r-- | lib/domain/libimagdiary/src/viewer.rs | 64 |
10 files changed, 882 insertions, 0 deletions
diff --git a/lib/domain/libimagdiary/src/config.rs b/lib/domain/libimagdiary/src/config.rs new file mode 100644 index 00000000..c2a6a980 --- /dev/null +++ b/lib/domain/libimagdiary/src/config.rs @@ -0,0 +1,43 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> 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 toml::Value; + +use libimagrt::runtime::Runtime; + +use toml_query::read::TomlValueReadExt; + +pub fn get_default_diary_name(rt: &Runtime) -> Option<String> { + get_diary_config_section(rt) + .and_then(|config| { + match config.read(&String::from("default_diary")) { + Ok(Some(&Value::String(ref s))) => Some(s.clone()), + _ => None, + } + }) +} + +pub fn get_diary_config_section<'a>(rt: &'a Runtime) -> Option<&'a Value> { + rt.config() + .map(|config| config.config()) + .and_then(|config| match config.read(&String::from("diary")) { + Ok(x) => x, + Err(_) => None, + }) +} diff --git a/lib/domain/libimagdiary/src/diary.rs b/lib/domain/libimagdiary/src/diary.rs new file mode 100644 index 00000000..431b6320 --- /dev/null +++ b/lib/domain/libimagdiary/src/diary.rs @@ -0,0 +1,128 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> 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::cmp::Ordering; + +use libimagstore::store::Store; +use libimagstore::storeid::IntoStoreId; +use libimagerror::trace::trace_error; + +use chrono::offset::Local; +use chrono::Datelike; +use itertools::Itertools; +use chrono::naive::NaiveDateTime; + +use entry::Entry; +use diaryid::DiaryId; +use error::DiaryError as DE; +use error::DiaryErrorKind as DEK; +use result::Result; +use iter::DiaryEntryIterator; +use is_in_diary::IsInDiary; + +#[derive(Debug)] +pub struct Diary<'a> { + store: &'a Store, + name: &'a str, +} + +impl<'a> Diary<'a> { + + pub fn open(store: &'a Store, name: &'a str) -> Diary<'a> { + Diary { + store: store, + name: name, + } + } + + // create or get a new entry for today + pub fn new_entry_today(&self) -> Result<Entry> { + let dt = Local::now(); + let ndt = dt.naive_local(); + let id = DiaryId::new(String::from(self.name), ndt.year(), ndt.month(), ndt.day(), 0, 0); + self.new_entry_by_id(id) + } + + pub fn new_entry_by_id(&self, id: DiaryId) -> Result<Entry> { + self.retrieve(id.with_diary_name(String::from(self.name))) + } + + pub fn retrieve(&self, id: DiaryId) -> Result<Entry> { + id.into_storeid() + .and_then(|id| self.store.retrieve(id)) + .map(|fle| Entry::new(fle)) + .map_err(|e| DE::new(DEK::StoreWriteError, Some(Box::new(e)))) + } + + // Get an iterator for iterating over all entries + pub fn entries(&self) -> Result<DiaryEntryIterator<'a>> { + self.store + .retrieve_for_module("diary") + .map(|iter| DiaryEntryIterator::new(self.name, self.store, iter)) + .map_err(|e| DE::new(DEK::StoreReadError, Some(Box::new(e)))) + } + + pub fn delete_entry(&self, entry: Entry) -> Result<()> { + if !entry.is_in_diary(self.name) { + return Err(DE::new(DEK::EntryNotInDiary, None)); + } + let id = entry.get_location().clone(); + drop(entry); + + self.store.delete(id) + .map_err(|e| DE::new(DEK::StoreWriteError, Some(Box::new(e)))) + } + + pub fn get_youngest_entry(&self) -> Option<Result<Entry>> { + match self.entries() { + Err(e) => Some(Err(e)), + Ok(entries) => { + entries.sorted_by(|a, b| { + match (a, b) { + (&Ok(ref a), &Ok(ref b)) => { + let a : NaiveDateTime = a.diary_id().into(); + let b : NaiveDateTime = b.diary_id().into(); + + a.cmp(&b) + }, + + (&Ok(_), &Err(ref e)) => { + trace_error(e); + Ordering::Less + }, + (&Err(ref e), &Ok(_)) => { + trace_error(e); + Ordering::Greater + }, + (&Err(ref e1), &Err(ref e2)) => { + trace_error(e1); + trace_error(e2); + Ordering::Equal + }, + } + }).into_iter().next() + } + } + } + + pub fn name(&self) -> &'a str { + &self.name + } +} + diff --git a/lib/domain/libimagdiary/src/diaryid.rs b/lib/domain/libimagdiary/src/diaryid.rs new file mode 100644 index 00000000..da1afc42 --- /dev/null +++ b/lib/domain/libimagdiary/src/diaryid.rs @@ -0,0 +1,257 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> 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::convert::Into; +use std::fmt::{Display, Formatter, Error as FmtError}; + +use chrono::naive::NaiveDateTime; +use chrono::naive::NaiveTime; +use chrono::naive::NaiveDate; +use chrono::Datelike; +use chrono::Timelike; + +use libimagstore::storeid::StoreId; +use libimagstore::storeid::IntoStoreId; +use libimagstore::store::Result as StoreResult; + +use error::DiaryError as DE; +use error::DiaryErrorKind as DEK; +use error::MapErrInto; +use libimagerror::into::IntoError; + +use module_path::ModuleEntryPath; + +#[derive(Debug, Clone)] +pub struct DiaryId { + name: String, + year: i32, + month: u32, + day: u32, + hour: u32, + minute: u32, +} + +impl DiaryId { + + pub fn new(name: String, y: i32, m: u32, d: u32, h: u32, min: u32) -> DiaryId { + DiaryId { + name: name, + year: y, + month: m, + day: d, + hour: h, + minute: min, + } + } + + pub fn from_datetime<DT: Datelike + Timelike>(diary_name: String, dt: DT) -> DiaryId { + DiaryId::new(diary_name, dt.year(), dt.month(), dt.day(), dt.hour(), dt.minute()) + } + + pub fn diary_name(&self) -> &String { + &self.name + } + + pub fn year(&self) -> i32 { + self.year + } + + pub fn month(&self) -> u32 { + self.month + } + + pub fn day(&self) -> u32 { + self.day + } + + pub fn hour(&self) -> u32 { + self.hour + } + + pub fn minute(&self) -> u32 { + self.minute + } + + pub fn with_diary_name(mut self, name: String) -> DiaryId { + self.name = name; + self + } + + pub fn with_year(mut self, year: i32) -> DiaryId { + self.year = year; + self + } + + pub fn with_month(mut self, month: u32) -> DiaryId { + self.month = month; + self + } + + pub fn with_day(mut self, day: u32) -> DiaryId { + self.day = day; + self + } + + pub fn with_hour(mut self, hour: u32) -> DiaryId { + self.hour = hour; + self + } + + pub fn with_minute(mut self, minute: u32) -> DiaryId { + self.minute = minute; + self + } + + pub fn now(name: String) -> DiaryId { + use chrono::offset::Local; + + let now = Local::now(); + let now_date = now.date().naive_local(); + let now_time = now.time(); + let dt = NaiveDateTime::new(now_date, now_time); + + DiaryId::new(name, dt.year(), dt.month(), dt.day(), dt.hour(), dt.minute()) + } + +} + +impl Default for DiaryId { + + /// Create a default DiaryId which is a diaryid for a diary named "default" with + /// time = 0000-00-00 00:00:00 + fn default() -> DiaryId { + let dt = NaiveDateTime::new(NaiveDate::from_ymd(0, 0, 0), NaiveTime::from_hms(0, 0, 0)); + DiaryId::from_datetime(String::from("default"), dt) + } +} + +impl IntoStoreId for DiaryId { + + fn into_storeid(self) -> StoreResult<StoreId> { + let s : String = self.into(); + ModuleEntryPath::new(s).into_storeid() + } + +} + +impl Into<String> for DiaryId { + + fn into(self) -> String { + format!("{}/{:0>4}/{:0>2}/{:0>2}/{:0>2}:{:0>2}", + self.name, self.year, self.month, self.day, self.hour, self.minute) + } + +} + +impl Display for DiaryId { + + fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> { + write!(fmt, "{}/{:0>4}/{:0>2}/{:0>2}/{:0>2}:{:0>2}", + self.name, self.year, self.month, self.day, self.hour, self.minute) + } + +} + +impl Into<NaiveDateTime> for DiaryId { + + fn into(self) -> NaiveDateTime { + let d = NaiveDate::from_ymd(self.year, self.month, self.day); + let t = NaiveTime::from_hms(self.hour, self.minute, 0); + NaiveDateTime::new(d, t) + } + +} + +pub trait FromStoreId : Sized { + + fn from_storeid(&StoreId) -> Result<Self, DE>; + +} + +use std::path::Component; + +fn component_to_str<'a>(com: Component<'a>) -> Result<&'a str, DE> { + match com { + Component::Normal(s) => Some(s), + _ => None, + }.and_then(|s| s.to_str()) + .ok_or(DEK::IdParseError.into_error()) +} + +impl FromStoreId for DiaryId { + + fn from_storeid(s: &StoreId) -> Result<DiaryId, DE> { + use std::str::FromStr; + + use std::path::Components; + use std::iter::Rev; + + fn next_component<'a>(components: &'a mut Rev<Components>) -> Result<&'a str, DE> { + components.next() + .ok_or(DEK::IdParseError.into_error()) + .and_then(component_to_str) + } + + let mut cmps = s.components().rev(); + + let (hour, minute) = try!(next_component(&mut cmps).and_then(|time| { + let mut time = time.split(":"); + let hour = time.next().and_then(|s| FromStr::from_str(s).ok()); + let minute = time.next() + .and_then(|s| s.split("~").next()) + .and_then(|s| FromStr::from_str(s).ok()); + + debug!("Hour = {:?}", hour); + debug!("Minute = {:?}", minute); + + match (hour, minute) { + (Some(h), Some(m)) => Ok((h, m)), + _ => return Err(DE::new(DEK::IdParseError, None)), + } + })); + + let day: Result<u32,_> = next_component(&mut cmps) + .and_then(|s| s.parse::<u32>() + .map_err_into(DEK::IdParseError)); + + let month: Result<u32,_> = next_component(&mut cmps) + .and_then(|s| s.parse::<u32>() + .map_err_into(DEK::IdParseError)); + + let year: Result<i32,_> = next_component(&mut cmps) + .and_then(|s| s.parse::<i32>() + .map_err_into(DEK::IdParseError)); + + let name = next_component(&mut cmps).map(String::from); + + debug!("Day = {:?}", day); + debug!("Month = {:?}", month); + debug!("Year = {:?}", year); + debug!("Name = {:?}", name); + + let day = try!(day); + let month = try!(month); + let year = try!(year); + let name = try!(name); + + Ok(DiaryId::new(name, year, month, day, hour, minute)) + } + +} + diff --git a/lib/domain/libimagdiary/src/entry.rs b/lib/domain/libimagdiary/src/entry.rs new file mode 100644 index 00000000..0148b59d --- /dev/null +++ b/lib/domain/libimagdiary/src/entry.rs @@ -0,0 +1,90 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> 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::ops::Deref; +use std::ops::DerefMut; + +use libimagstore::store::FileLockEntry; +use libimagentryedit::edit::Edit; +use libimagentryedit::result::Result as EditResult; +use libimagrt::runtime::Runtime; + +use diaryid::DiaryId; +use diaryid::FromStoreId; + +#[derive(Debug)] +pub struct Entry<'a>(FileLockEntry<'a>); + +impl<'a> Deref for Entry<'a> { + type Target = FileLockEntry<'a>; + + fn deref(&self) -> &FileLockEntry<'a> { + &self.0 + } + +} + +impl<'a> DerefMut for Entry<'a> { + + fn deref_mut(&mut self) -> &mut FileLockEntry<'a> { + &mut self.0 + } + +} + +impl<'a> Entry<'a> { + + pub fn new(fle: FileLockEntry<'a>) -> Entry<'a> { + Entry(fle) + } + + /// Get the diary id for this entry. + /// + /// TODO: calls Option::unwrap() as it assumes that an existing Entry has an ID that is parsable + pub fn diary_id(&self) -> DiaryId { + DiaryId::from_storeid(&self.0.get_location().clone()).unwrap() + } + +} + +impl<'a> Into<FileLockEntry<'a>> for Entry<'a> { + + fn into(self) -> FileLockEntry<'a> { + self.0 + } + +} + +impl<'a> From<FileLockEntry<'a>> for Entry<'a> { + + fn from(fle: FileLockEntry<'a>) -> Entry<'a> { + Entry::new(fle) + } + +} + +impl<'a> Edit for Entry<'a> { + + fn edit_content(&mut self, rt: &Runtime) -> EditResult<()> { + self.0.edit_content(rt) + } + +} + + diff --git a/lib/domain/libimagdiary/src/error.rs b/lib/domain/libimagdiary/src/error.rs new file mode 100644 index 00000000..b5406b12 --- /dev/null +++ b/lib/domain/libimagdiary/src/error.rs @@ -0,0 +1,38 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> 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!(DiaryError, DiaryErrorKind, + StoreWriteError => "Error writing store", + StoreReadError => "Error reading store", + CannotFindDiary => "Cannot find diary", + CannotCreateNote => "Cannot create Note object for diary entry", + DiaryEditError => "Cannot edit diary entry", + PathConversionError => "Error while converting paths internally", + EntryNotInDiary => "Entry not in Diary", + IOError => "IO Error", + ViewError => "Error viewing diary entry", + IdParseError => "Error while parsing ID" + ); +); + +pub use self::error::DiaryError; +pub use self::error::DiaryErrorKind; +pub use self::error::MapErrInto; + diff --git a/lib/domain/libimagdiary/src/is_in_diary.rs b/lib/domain/libimagdiary/src/is_in_diary.rs new file mode 100644 index 00000000..09228072 --- /dev/null +++ b/lib/domain/libimagdiary/src/is_in_diary.rs @@ -0,0 +1,44 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> 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 libimagstore::store::Entry; +use libimagstore::storeid::StoreId; + +pub trait IsInDiary { + + fn is_in_diary(&self, name: &str) -> bool; + +} + +impl IsInDiary for Entry { + + fn is_in_diary(&self, name: &str) -> bool { + self.get_location().clone().is_in_diary(name) + } + +} + +impl IsInDiary for StoreId { + + fn is_in_diary(&self, name: &str) -> bool { + self.local().starts_with(format!("diary/{}", name)) + } + +} + diff --git a/lib/domain/libimagdiary/src/iter.rs b/lib/domain/libimagdiary/src/iter.rs new file mode 100644 index 00000000..de849872 --- /dev/null +++ b/lib/domain/libimagdiary/src/iter.rs @@ -0,0 +1,132 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> 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::fmt::{Debug, Formatter, Error as FmtError}; +use std::result::Result as RResult; + +use libimagstore::store::Store; +use libimagstore::storeid::StoreIdIterator; + +use diaryid::DiaryId; +use diaryid::FromStoreId; +use is_in_diary::IsInDiary; +use entry::Entry as DiaryEntry; +use error::DiaryError as DE; +use error::DiaryErrorKind as DEK; +use result::Result; +use libimagerror::trace::trace_error; + +/// A iterator for iterating over diary entries +pub struct DiaryEntryIterator<'a> { + store: &'a Store, + name: &'a str, + iter: StoreIdIterator, + + year: Option<i32>, + month: Option<u32>, + day: Option<u32>, +} + +impl<'a> Debug for DiaryEntryIterator<'a> { + + fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> { + write!(fmt, "DiaryEntryIterator<name = {}, year = {:?}, month = {:?}, day = {:?}>", + self.name, self.year, self.month, self.day) + } + +} + +impl<'a> DiaryEntryIterator<'a> { + + pub fn new(diaryname: &'a str, store: &'a Store, iter: StoreIdIterator) -> DiaryEntryIterator<'a> { + DiaryEntryIterator { + store: store, + name: diaryname, + iter: iter, + + year: None, + month: None, + day: None, + } + } + + // Filter by year, get all diary entries for this year + pub fn year(mut self, year: i32) -> DiaryEntryIterator<'a> { + self.year = Some(year); + self + } + + // Filter by month, get all diary entries for this month (every year) + pub fn month(mut self, month: u32) -> DiaryEntryIterator<'a> { + self.month = Some(month); + self + } + + // Filter by day, get all diary entries for this day (every year, every year) + pub fn day(mut self, day: u32) -> DiaryEntryIterator<'a> { + self.day = Some(day); + self + } + +} + +impl<'a> Iterator for DiaryEntryIterator<'a> { + type Item = Result<DiaryEntry<'a>>; + + fn next(&mut self) -> Option<Result<DiaryEntry<'a>>> { + loop { + let next = match self.iter.next() { + Some(s) => s, + None => return None, + }; + debug!("Next element: {:?}", next); + + if next.is_in_diary(self.name) { + debug!("Seems to be in diary: {:?}", next); + let id = match DiaryId::from_storeid(&next) { + Ok(i) => i, + Err(e) => { + trace_error(&e); + debug!("Couldn't parse {:?} into DiaryId: {:?}", next, e); + continue; + } + }; + debug!("Success parsing id = {:?}", id); + + let y = match self.year { None => true, Some(y) => y == id.year() }; + let m = match self.month { None => true, Some(m) => m == id.month() }; + let d = match self.day { None => true, Some(d) => d == id.day() }; + + if y && m && d { + debug!("Return = {:?}", id); + return Some(self + .store + .retrieve(next) + .map(|fle| DiaryEntry::new(fle)) + .map_err(|e| DE::new(DEK::StoreReadError, Some(Box::new(e)))) + ); + } + } else { + debug!("Not in the requested diary ({}): {:?}", self.name, next); + } + } + } + +} + diff --git a/lib/domain/libimagdiary/src/lib.rs b/lib/domain/libimagdiary/src/lib.rs new file mode 100644 index 00000000..fcabc94e --- /dev/null +++ b/lib/domain/libimagdiary/src/lib.rs @@ -0,0 +1,62 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> 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 +// + +#![deny( + dead_code, + non_camel_case_types, + non_snake_case, + path_statements, + trivial_numeric_casts, + unstable_features, + unused_allocation, + unused_import_braces, + unused_imports, + unused_must_use, + unused_mut, + unused_qualifications, + while_true, +)] + +extern crate chrono; +#[macro_use] extern crate log; +extern crate semver; +extern crate toml; +extern crate toml_query; +extern crate regex; +extern crate itertools; + +#[macro_use] extern crate libimagstore; +#[macro_use] extern crate libimagerror; +extern crate libimagentryedit; +extern crate libimagentryview; +extern crate libimagrt; +extern crate libimagutil; + +module_entry_path_mod!("diary"); + +pub mod config; +pub mod error; +pub mod diaryid; +pub mod diary; +pub mod is_in_diary; +pub mod entry; +pub mod iter; +pub mod result; +pub mod viewer; + diff --git a/lib/domain/libimagdiary/src/result.rs b/lib/domain/libimagdiary/src/result.rs new file mode 100644 index 00000000..b4f5f382 --- /dev/null +++ b/lib/domain/libimagdiary/src/result.rs @@ -0,0 +1,24 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> 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::DiaryError; + +pub type Result<T> = RResult<T, DiaryError>; diff --git a/lib/domain/libimagdiary/src/viewer.rs b/lib/domain/libimagdiary/src/viewer.rs new file mode 100644 index 00000000..93b155a7 --- /dev/null +++ b/lib/domain/libimagdiary/src/viewer.rs @@ -0,0 +1,64 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +//! A diary viewer built on libimagentryview. + +use entry::Entry; +use error::DiaryErrorKind as DEK; +use error::MapErrInto; +use result::Result; + +use libimagentryview::viewer::Viewer; +use libimagentryview::builtin::plain::PlainViewer; + +/// This viewer does _not_ implement libimagentryview::viewer::Viewer because we need to be able to +/// call some diary-type specific functions on the entries passed to this. +/// +/// This type is mainly just written to be constructed-called-deleted in one go: +/// +/// ```ignore +/// DiaryViewer::new(show_header).view_entries(entries); +/// ``` +/// +pub struct DiaryViewer(PlainViewer); + +impl DiaryViewer { + + pub fn new(show_header: bool) -> DiaryViewer { + DiaryViewer(PlainViewer::new(show_header)) + } + + /// View all entries from the iterator, or stop immediately if an error occurs, returning that + /// error. + pub fn view_entries<'a, I: Iterator<Item = Entry<'a>>>(&self, entries: I) -> Result<()> { + for entry in entries { + let id = entry.diary_id(); + println!("{} :\n", id); + let _ = try!(self.0 + .view_entry(&entry) + .map_err_into(DEK::ViewError) + .map_err_into(DEK::IOError)); + println!("\n---\n"); + } + + Ok(()) + } + +} + |