diff options
| -rw-r--r-- | src/config_list.rs | 8 | ||||
| -rw-r--r-- | src/ffi.rs | 10 | ||||
| -rw-r--r-- | src/message.rs | 30 | ||||
| -rw-r--r-- | src/message_properties.rs | 2 | ||||
| -rw-r--r-- | src/tags.rs | 2 | ||||
| -rw-r--r-- | src/thread.rs | 13 | ||||
| -rw-r--r-- | src/utils.rs | 14 | ||||
| -rw-r--r-- | tests/test_message.rs | 14 |
8 files changed, 57 insertions, 36 deletions
diff --git a/src/config_list.rs b/src/config_list.rs index 632603c..b819418 100644 --- a/src/config_list.rs +++ b/src/config_list.rs @@ -6,7 +6,7 @@ use ffi; use Database; use Filenames; use FilenamesOwner; -use utils::{ScopedSupercow, ScopedPhantomcow}; +use utils::{ToStr, ScopedSupercow, ScopedPhantomcow}; #[derive(Debug)] @@ -46,15 +46,15 @@ impl<'d> Iterator for ConfigList<'d> } let (k, v) = unsafe { - let key = CStr::from_ptr(ffi::notmuch_config_list_key(self.ptr)); - let value = CStr::from_ptr(ffi::notmuch_config_list_value(self.ptr)); + let key = ffi::notmuch_config_list_key(self.ptr); + let value = ffi::notmuch_config_list_value(self.ptr); ffi::notmuch_config_list_move_to_next(self.ptr); (key, value) }; - Some((k.to_str().unwrap().to_string(), v.to_str().unwrap().to_string())) + Some((k.to_string_lossy().to_string(), v.to_string_lossy().to_string())) } } @@ -6,7 +6,7 @@ use libc::{c_char, c_double, c_int, c_uint, c_ulong, c_void, time_t}; use error::{Error, Result}; use std::{error, fmt, str}; - +use std::borrow::Cow; use utils::ToStr; notmuch_enum! { @@ -57,6 +57,14 @@ impl ToStr for Status { fn to_str<'a>(&self) -> std::result::Result<&'a str, str::Utf8Error> { unsafe { notmuch_status_to_string((*self).into()) }.to_str() } + + fn to_str_unchecked<'a>(&self) -> &'a str { + unsafe { notmuch_status_to_string((*self).into()) }.to_str_unchecked() + } + + fn to_string_lossy<'a>(&self) -> Cow<'a, str> { + unsafe { notmuch_status_to_string((*self).into()) }.to_string_lossy() + } } impl fmt::Display for Status { diff --git a/src/message.rs b/src/message.rs index 8263908..20ad957 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1,7 +1,9 @@ use std::ffi::{CString, CStr}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::cell::RefCell; +use std::borrow::Cow; use std::ptr; + use supercow::{Supercow}; use error::{Error, Result}; @@ -54,14 +56,14 @@ where } } - pub fn id(self: &Self) -> String { + pub fn id(self: &Self) -> Cow<'_, str> { let mid = unsafe { ffi::notmuch_message_get_message_id(self.ptr) }; - mid.to_str().unwrap().to_string() + mid.to_string_lossy() } - pub fn thread_id(self: &Self) -> String { + pub fn thread_id(self: &Self) -> Cow<'_, str> { let tid = unsafe { ffi::notmuch_message_get_thread_id(self.ptr) }; - tid.to_str().unwrap().to_string() + tid.to_string_lossy() } pub fn replies(self: &Self) -> Messages<'o, O> { @@ -93,16 +95,18 @@ where unsafe { ffi::notmuch_message_get_date(self.ptr) as i64 } } - pub fn header(&self, name: &str) -> Result<Option<&str>> { + pub fn header(&self, name: &str) -> Result<Option<Cow<'_, str>>> { let name = CString::new(name).unwrap(); let ret = unsafe { ffi::notmuch_message_get_header(self.ptr, name.as_ptr()) }; if ret.is_null() { Err(Error::UnspecifiedError) } else { - Ok(match ret.to_str().unwrap() { - "" => None, - ret => Some(ret), - }) + let ret_str = ret.to_string_lossy(); + if ret_str.is_empty() { + Ok(None) + } else{ + Ok(Some(ret_str)) + } } } @@ -196,7 +200,7 @@ where Ok(cnt) } - pub fn property(&self, key: &str, exact: bool) -> Result<String> + pub fn property(&self, key: &str) -> Result<Cow<'_, str>> { let key_str = CString::new(key).unwrap(); let mut prop = ptr::null(); @@ -208,9 +212,7 @@ where Err(Error::UnspecifiedError) } else { // TODO: the unwrap here is not good - Ok(unsafe{ - CStr::from_ptr(prop) - }.to_str().unwrap().to_string()) + Ok(prop.to_string_lossy()) } } diff --git a/src/message_properties.rs b/src/message_properties.rs index 4802383..19ea960 100644 --- a/src/message_properties.rs +++ b/src/message_properties.rs @@ -64,7 +64,7 @@ where (key, value) }; - Some((k.to_str().unwrap().to_string(), v.to_str().unwrap().to_string())) + Some((k.to_string_lossy().to_string(), v.to_string_lossy().to_string())) } } diff --git a/src/tags.rs b/src/tags.rs index 40a45c8..5f3ec60 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -69,7 +69,7 @@ where CStr::from_ptr(t) }; - Some(ctag.to_str().unwrap().to_string()) + Some(ctag.to_string_lossy().to_string()) } } diff --git a/src/thread.rs b/src/thread.rs index 1ebcc24..ffc1f2f 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -1,4 +1,5 @@ use std::ops::Drop; +use std::borrow::Cow; use ffi; use utils::{ToStr, ScopedSupercow, ScopedPhantomcow}; @@ -43,9 +44,9 @@ where } } - pub fn id(self: &Self) -> String { + pub fn id(self: &Self) -> &str { let tid = unsafe { ffi::notmuch_thread_get_thread_id(self.ptr) }; - tid.to_str().unwrap().to_string() + tid.to_str().unwrap() } pub fn total_messages(self: &Self) -> i32 { @@ -75,18 +76,16 @@ where <Self as ThreadExt<'d, 'q>>::tags(self) } - pub fn subject(self: &Self) -> String { + pub fn subject(self: &Self) -> Cow<'_, str> { let sub = unsafe { ffi::notmuch_thread_get_subject(self.ptr) }; - - sub.to_str().unwrap().to_string() + sub.to_string_lossy() } pub fn authors(self: &Self) -> Vec<String> { let athrs = unsafe { ffi::notmuch_thread_get_authors(self.ptr) }; athrs - .to_str() - .unwrap() + .to_string_lossy() .split(',') .map(|s| s.to_string()) .collect() diff --git a/src/utils.rs b/src/utils.rs index 022d508..6030f38 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,17 +1,29 @@ use libc; use std::{ffi, str}; - +use std::borrow::Cow; use supercow::{Supercow, DefaultFeatures/*, NonSyncFeatures*/}; use supercow::ext::{BoxedStorage}; pub trait ToStr { fn to_str<'a>(&self) -> Result<&'a str, str::Utf8Error>; + + fn to_str_unchecked<'a>(&self) -> &'a str; + + fn to_string_lossy<'a>(&self) -> Cow<'a, str>; } impl ToStr for *const libc::c_char { fn to_str<'a>(&self) -> Result<&'a str, str::Utf8Error> { str::from_utf8(unsafe { ffi::CStr::from_ptr(*self) }.to_bytes()) } + + fn to_str_unchecked<'a>(&self) -> &'a str { + unsafe { str::from_utf8_unchecked(ffi::CStr::from_ptr(*self).to_bytes()) } + } + + fn to_string_lossy<'a>(&self) -> Cow<'a, str> { + unsafe { ffi::CStr::from_ptr(*self) }.to_string_lossy() + } } pub trait ToString { diff --git a/tests/test_message.rs b/tests/test_message.rs index 152f565..7a6391d 100644 --- a/tests/test_message.rs +++ b/tests/test_message.rs @@ -70,7 +70,7 @@ mod message { #[test] fn test_header() { let msg = MessageFixture::new(); - assert_eq!(msg.message.header(&"from").unwrap(), Some("<src@example.com>")); + assert_eq!(msg.message.header(&"from").unwrap().unwrap().to_string(), "<src@example.com>"); } #[test] @@ -172,10 +172,10 @@ mod properties { fn test_add_single() { let msg = MessageFixture::new(); msg.message.add_property(&"foo", &"bar").unwrap(); - assert_eq!(msg.message.property(&"foo", true).unwrap(), "bar"); + assert_eq!(msg.message.property(&"foo").unwrap(), "bar"); msg.message.add_property(&"bar", &"baz").unwrap(); - assert_eq!(msg.message.property(&"bar", true).unwrap(), "baz"); + assert_eq!(msg.message.property(&"bar").unwrap(), "baz"); } #[test] @@ -184,7 +184,7 @@ mod properties { msg.message.add_property(&"foo", &"bar").unwrap(); msg.message.add_property(&"foo", &"baz").unwrap(); - assert_eq!(msg.message.property(&"foo", true).unwrap(), "bar"); + assert_eq!(msg.message.property(&"foo").unwrap(), "bar"); let props = msg.message.properties(&"foo", true); let expect = vec![("foo", "bar"), ("foo", "baz")]; @@ -222,7 +222,7 @@ mod properties { msg.message.add_property(&"foo", &"b").unwrap(); msg.message.remove_all_properties(Some(&"foo")).unwrap(); - assert!(msg.message.property(&"foo", true).is_err()); + assert!(msg.message.property(&"foo").is_err()); } #[test] @@ -232,7 +232,7 @@ mod properties { msg.message.add_property(&"foo", &"b").unwrap(); msg.message.remove_property(&"foo", &"a").unwrap(); - assert_eq!(msg.message.property(&"foo", true).unwrap(), "b"); + assert_eq!(msg.message.property(&"foo").unwrap(), "b"); } #[test] @@ -241,7 +241,7 @@ mod properties { msg.message.add_property(&"foo", &"a").unwrap(); msg.message.remove_all_properties(None).unwrap(); - assert!(msg.message.property(&"foo", true).is_err()); + assert!(msg.message.property(&"foo").is_err()); } #[test] |
