diff --git a/libimagdiary/src/diaryid.rs b/libimagdiary/src/diaryid.rs index ad91ccf3..906097d8 100644 --- a/libimagdiary/src/diaryid.rs +++ b/libimagdiary/src/diaryid.rs @@ -30,6 +30,11 @@ 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)] @@ -175,62 +180,77 @@ impl Into for DiaryId { pub trait FromStoreId : Sized { - fn from_storeid(&StoreId) -> Option; + fn from_storeid(&StoreId) -> Result; } use std::path::Component; -fn component_to_str<'a>(com: Component<'a>) -> Option<&'a str> { +fn component_to_str<'a>(com: Component<'a>) -> Result<&'a str, DE> { match com { Component::Normal(s) => Some(s), - _ => None + _ => None, }.and_then(|s| s.to_str()) + .ok_or(DEK::IdParseError.into_error()) } impl FromStoreId for DiaryId { - fn from_storeid(s: &StoreId) -> Option { + fn from_storeid(s: &StoreId) -> Result { use std::str::FromStr; + use std::path::Components; + use std::iter::Rev; + + fn next_component<'a>(components: &'a mut Rev) -> 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) = match cmps.next().and_then(component_to_str) - .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); + 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()); - match (hour, minute) { - (Some(h), Some(m)) => Some((h, m)), - _ => None, - } - }) - { - Some(s) => s, - None => return None, - }; + debug!("Hour = {:?}", hour); + debug!("Minute = {:?}", minute); - let day :Option = cmps.next().and_then(component_to_str).and_then(|s| FromStr::from_str(s).ok()); - let month :Option = cmps.next().and_then(component_to_str).and_then(|s| FromStr::from_str(s).ok()); - let year :Option = cmps.next().and_then(component_to_str).and_then(|s| FromStr::from_str(s).ok()); - let name = cmps.next().and_then(component_to_str).map(String::from); + match (hour, minute) { + (Some(h), Some(m)) => Ok((h, m)), + _ => return Err(DE::new(DEK::IdParseError, None)), + } + })); + + let day: Result = next_component(&mut cmps) + .and_then(|s| s.parse::() + .map_err_into(DEK::IdParseError)); + + let month: Result = next_component(&mut cmps) + .and_then(|s| s.parse::() + .map_err_into(DEK::IdParseError)); + + let year: Result = next_component(&mut cmps) + .and_then(|s| s.parse::() + .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 = match day { None => return None, Some(day) => day }; - let month = match month { None => return None, Some(month) => month }; - let year = match year { None => return None, Some(year) => year }; - let name = match name { None => return None, Some(name) => name }; + let day = try!(day); + let month = try!(month); + let year = try!(year); + let name = try!(name); - Some(DiaryId::new(name, year, month, day, hour, minute)) + Ok(DiaryId::new(name, year, month, day, hour, minute)) } } diff --git a/libimagdiary/src/error.rs b/libimagdiary/src/error.rs index b6dc2bfd..b5406b12 100644 --- a/libimagdiary/src/error.rs +++ b/libimagdiary/src/error.rs @@ -27,7 +27,8 @@ generate_error_module!( PathConversionError => "Error while converting paths internally", EntryNotInDiary => "Entry not in Diary", IOError => "IO Error", - ViewError => "Error viewing diary entry" + ViewError => "Error viewing diary entry", + IdParseError => "Error while parsing ID" ); ); diff --git a/libimagdiary/src/iter.rs b/libimagdiary/src/iter.rs index 73f180d2..de849872 100644 --- a/libimagdiary/src/iter.rs +++ b/libimagdiary/src/iter.rs @@ -30,6 +30,7 @@ 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> { @@ -99,9 +100,10 @@ impl<'a> Iterator for DiaryEntryIterator<'a> { if next.is_in_diary(self.name) { debug!("Seems to be in diary: {:?}", next); let id = match DiaryId::from_storeid(&next) { - Some(i) => i, - None => { - debug!("Couldn't parse {:?} into DiaryId", next); + Ok(i) => i, + Err(e) => { + trace_error(&e); + debug!("Couldn't parse {:?} into DiaryId: {:?}", next, e); continue; } };