diff options
Diffstat (limited to 'melib/src')
-rw-r--r-- | melib/src/addressbook/vcard.rs | 3 | ||||
-rw-r--r-- | melib/src/backends/jmap/objects/email.rs | 3 | ||||
-rw-r--r-- | melib/src/datetime.rs | 51 | ||||
-rw-r--r-- | melib/src/email/parser.rs | 2 | ||||
-rw-r--r-- | melib/src/error.rs | 7 |
5 files changed, 39 insertions, 27 deletions
diff --git a/melib/src/addressbook/vcard.rs b/melib/src/addressbook/vcard.rs index bc57e739..ac06215c 100644 --- a/melib/src/addressbook/vcard.rs +++ b/melib/src/addressbook/vcard.rs @@ -201,7 +201,8 @@ impl<V: VCardVersion> TryInto<Card> for VCard<V> { T102200Z T102200-0800 */ - card.birthday = crate::datetime::timestamp_from_string(val.value.as_str(), "%Y%m%d"); + card.birthday = crate::datetime::timestamp_from_string(val.value.as_str(), "%Y%m%d") + .unwrap_or_default(); } if let Some(val) = self.0.remove("EMAIL") { card.set_email(val.value); diff --git a/melib/src/backends/jmap/objects/email.rs b/melib/src/backends/jmap/objects/email.rs index f303889c..ab5bbd17 100644 --- a/melib/src/backends/jmap/objects/email.rs +++ b/melib/src/backends/jmap/objects/email.rs @@ -235,7 +235,8 @@ impl std::convert::From<EmailObject> for crate::Envelope { env.set_datetime(d); } if let Some(ref mut sent_at) = t.sent_at { - let unix = crate::datetime::rfc3339_to_timestamp(sent_at.as_bytes().to_vec()); + let unix = + crate::datetime::rfc3339_to_timestamp(sent_at.as_bytes().to_vec()).unwrap_or(0); env.set_datetime(unix); env.set_date(std::mem::replace(sent_at, String::new()).as_bytes()); } diff --git a/melib/src/datetime.rs b/melib/src/datetime.rs index 33571db5..643b3107 100644 --- a/melib/src/datetime.rs +++ b/melib/src/datetime.rs @@ -22,6 +22,8 @@ use std::convert::TryInto; use std::ffi::{CStr, CString}; +use crate::error::Result; + pub type UnixTimestamp = u64; use libc::{timeval, timezone}; @@ -53,25 +55,26 @@ pub fn timestamp_to_string(timestamp: UnixTimestamp, fmt: Option<&str>) -> Strin let i: i64 = timestamp.try_into().unwrap_or(0); localtime_r(&i as *const i64, &mut new_tm as *mut ::libc::tm); } - let fmt = fmt.map(|slice| CString::new(slice).unwrap()); + let fmt = fmt + .map(|slice| CString::new(slice)) + .map(|res| res.ok()) + .and_then(|opt| opt); let format: &CStr = if let Some(ref s) = fmt { &s } else { unsafe { CStr::from_bytes_with_nul_unchecked(b"%a, %d %b %Y %T %z\0") } }; - let s: CString; - unsafe { - let mut vec: [u8; 256] = [0; 256]; - let ret = strftime( + let mut vec: [u8; 256] = [0; 256]; + let ret = unsafe { + strftime( vec.as_mut_ptr() as *mut _, 256, format.as_ptr(), &new_tm as *const _, - ); - s = CString::new(&vec[0..ret]).unwrap(); - } + ) + }; - s.to_string_lossy().to_string() + String::from_utf8_lossy(&vec[0..ret]).into_owned() } fn tm_to_secs(tm: ::libc::tm) -> std::result::Result<i64, ()> { @@ -184,11 +187,11 @@ fn month_to_secs(month: usize, is_leap: bool) -> i64 { return t; } -pub fn rfc822_to_timestamp<T>(s: T) -> UnixTimestamp +pub fn rfc822_to_timestamp<T>(s: T) -> Result<UnixTimestamp> where T: Into<Vec<u8>>, { - let s = CString::new(s).unwrap(); + let s = CString::new(s)?; let mut new_tm: ::libc::tm = unsafe { std::mem::zeroed() }; for fmt in &[ &b"%a, %e %h %Y %H:%M:%S \0"[..], @@ -231,19 +234,19 @@ where 0 } }; - return tm_to_secs(new_tm) + return Ok(tm_to_secs(new_tm) .map(|res| (res - tm_gmtoff) as u64) - .unwrap_or(0); + .unwrap_or(0)); } } - return 0; + return Ok(0); } -pub fn rfc3339_to_timestamp<T>(s: T) -> UnixTimestamp +pub fn rfc3339_to_timestamp<T>(s: T) -> Result<UnixTimestamp> where T: Into<Vec<u8>>, { - let s = CString::new(s).unwrap(); + let s = CString::new(s)?; let mut new_tm: ::libc::tm = unsafe { std::mem::zeroed() }; for fmt in &[&b"%Y-%m-%dT%H:%M:%S\0"[..], &b"%Y-%m-%d\0"[..]] { unsafe { @@ -284,31 +287,31 @@ where 0 } }; - return tm_to_secs(new_tm) + return Ok(tm_to_secs(new_tm) .map(|res| (res - tm_gmtoff) as u64) - .unwrap_or(0); + .unwrap_or(0)); } } - return 0; + return Ok(0); } // FIXME: Handle non-local timezone? -pub fn timestamp_from_string<T>(s: T, fmt: &str) -> Option<UnixTimestamp> +pub fn timestamp_from_string<T>(s: T, fmt: &str) -> Result<Option<UnixTimestamp>> where T: Into<Vec<u8>>, { let mut new_tm: ::libc::tm = unsafe { std::mem::zeroed() }; - let fmt = CString::new(fmt).unwrap(); + let fmt = CString::new(fmt)?; unsafe { let ret = strptime( - CString::new(s).unwrap().as_ptr(), + CString::new(s)?.as_ptr(), fmt.as_ptr(), &mut new_tm as *mut _, ); if ret.is_null() { - return None; + return Ok(None); } - return Some(mktime(&new_tm as *const _) as u64); + return Ok(Some(mktime(&new_tm as *const _) as u64)); } } diff --git a/melib/src/email/parser.rs b/melib/src/email/parser.rs index 849440cd..3240d5c6 100644 --- a/melib/src/email/parser.rs +++ b/melib/src/email/parser.rs @@ -664,7 +664,7 @@ pub fn date(input: &[u8]) -> Result<UnixTimestamp> { parsed_result[pos] = b'+'; } - Ok(crate::datetime::rfc822_to_timestamp(parsed_result.trim())) + crate::datetime::rfc822_to_timestamp(parsed_result.trim()) } named!(pub message_id<&[u8]>, diff --git a/melib/src/error.rs b/melib/src/error.rs index b66fdb63..984d25d2 100644 --- a/melib/src/error.rs +++ b/melib/src/error.rs @@ -167,6 +167,13 @@ impl From<serde_json::error::Error> for MeliError { } } +impl From<std::ffi::NulError> for MeliError { + #[inline] + fn from(kind: std::ffi::NulError) -> MeliError { + MeliError::new(format!("{}", kind)) + } +} + impl From<&str> for MeliError { #[inline] fn from(kind: &str) -> MeliError { |