diff options
| author | Dirk Van Haerenborgh <vhdirk@gmail.com> | 2018-10-16 21:01:58 +0200 |
|---|---|---|
| committer | Dirk Van Haerenborgh <vhdirk@gmail.com> | 2018-10-24 07:12:55 +0200 |
| commit | a4ffe47c51d1617fc0e728c7bbd7e9b3738878cb (patch) | |
| tree | 017d0717ac8e2d5e0f6a46e47ea9e731ce63697b | |
| parent | b93d4cb749714699b44b2566e50a7086c2854ac7 (diff) | |
| download | mail-a4ffe47c51d1617fc0e728c7bbd7e9b3738878cb.tar.gz | |
some tries towards better lifetimes
| -rw-r--r-- | src/database.rs | 57 | ||||
| -rw-r--r-- | src/directory.rs | 44 | ||||
| -rw-r--r-- | src/filenames.rs | 41 | ||||
| -rw-r--r-- | src/message.rs | 66 | ||||
| -rw-r--r-- | src/messages.rs | 80 | ||||
| -rw-r--r-- | src/query.rs | 61 | ||||
| -rw-r--r-- | src/tags.rs | 6 | ||||
| -rw-r--r-- | src/thread.rs | 71 | ||||
| -rw-r--r-- | src/threads.rs | 40 | ||||
| -rw-r--r-- | src/utils.rs | 10 |
10 files changed, 279 insertions, 197 deletions
diff --git a/src/database.rs b/src/database.rs index 90f6574..6d98413 100644 --- a/src/database.rs +++ b/src/database.rs @@ -7,7 +7,7 @@ use libc; use error::Result; use utils::{ - NewFromPtr, + FromPtr, ToStr, }; @@ -30,7 +30,22 @@ pub struct Revision{ } #[derive(Debug)] -pub struct Database(*mut ffi::notmuch_database_t); +pub(crate) struct DatabasePtr { + pub ptr: *mut ffi::notmuch_database_t +} + +impl Drop for DatabasePtr { + fn drop(&mut self) { + unsafe { + ffi::notmuch_database_destroy(self.ptr) + }; + } +} + +#[derive(Debug)] +pub struct Database{ + pub(crate) handle: DatabasePtr +} impl Database { pub fn create<P: AsRef<Path>>(path: &P) -> Result<Self> { @@ -41,7 +56,7 @@ impl Database { ffi::notmuch_database_create(path_str.as_ptr(), &mut db) }.as_result()); - Ok(Database(db)) + Ok(Database{handle:DatabasePtr{ptr:db}}) } pub fn open<P: AsRef<Path>>(path: &P, mode: DatabaseMode) -> Result<Self> { @@ -56,12 +71,12 @@ impl Database { ) }.as_result()); - Ok(Database(db)) + Ok(Database{handle:DatabasePtr{ptr:db}}) } pub fn close(self) -> Result<()> { try!(unsafe { - ffi::notmuch_database_close(self.0) + ffi::notmuch_database_close(self.handle.ptr) }.as_result()); Ok(()) @@ -114,13 +129,13 @@ impl Database { pub fn path(&self) -> &Path { Path::new(unsafe { - ffi::notmuch_database_get_path(self.0) + ffi::notmuch_database_get_path(self.handle.ptr) }.to_str().unwrap()) } pub fn version(&self) -> Version { Version(unsafe { - ffi::notmuch_database_get_version(self.0) + ffi::notmuch_database_get_version(self.handle.ptr) }) } @@ -128,7 +143,7 @@ impl Database { pub fn revision(&self) -> Revision { let uuid_p: *const libc::c_char = ptr::null(); let revision = unsafe { - ffi::notmuch_database_get_revision(self.0, (&uuid_p) as *const _ as *mut *const libc::c_char) + ffi::notmuch_database_get_revision(self.handle.ptr, (&uuid_p) as *const _ as *mut *const libc::c_char) }; let uuid = unsafe { CStr::from_ptr(uuid_p) }; @@ -138,7 +153,7 @@ impl Database { pub fn needs_upgrade(&self) -> bool { unsafe { - ffi::notmuch_database_needs_upgrade(self.0) == 1 + ffi::notmuch_database_needs_upgrade(self.handle.ptr) == 1 } } @@ -165,7 +180,7 @@ impl Database { try!(unsafe { ffi::notmuch_database_upgrade( - self.0, + self.handle.ptr, if status.is_some() { Some(wrapper::<F>) } else { None }, status.map_or(ptr::null_mut(), |f| { &f as *const _ as *mut libc::c_void @@ -182,38 +197,30 @@ impl Database { let mut dir = ptr::null_mut(); try!(unsafe { ffi::notmuch_database_get_directory( - self.0, path_str.as_ptr(), &mut dir, + self.handle.ptr, path_str.as_ptr(), &mut dir, ) }.as_result()); - if dir.is_null() { Ok(None) } else { Ok(Some(Directory::new(dir))) } + if dir.is_null() { Ok(None) } else { Ok(Some(Directory::from_ptr(dir))) } } pub fn create_query<'d>(&'d self, query_string: &str) -> Result<Query<'d>> { let query_str = CString::new(query_string).unwrap(); let query = unsafe { - ffi::notmuch_query_create(self.0, query_str.as_ptr()) + ffi::notmuch_query_create(self.handle.ptr, query_str.as_ptr()) }; - Ok(Query::new(query)) + Ok(Query::from_ptr(query)) } - pub fn all_tags<'d>(&self) -> Result<Tags<'d>> { + pub fn all_tags<'d>(&self) -> Result<Tags> { let tags = unsafe { - ffi::notmuch_database_get_all_tags(self.0) + ffi::notmuch_database_get_all_tags(self.handle.ptr) }; - Ok(Tags::new(tags)) - } -} - -impl Drop for Database { - fn drop(&mut self) { - unsafe { - ffi::notmuch_database_destroy(self.0) - }; + Ok(Tags::from_ptr(tags)) } } diff --git a/src/directory.rs b/src/directory.rs index b0bb415..4bf0a7a 100644 --- a/src/directory.rs +++ b/src/directory.rs @@ -1,7 +1,7 @@ use std::ops::Drop; use std::marker::PhantomData; -use utils::NewFromPtr; +use utils::FromPtr; use Database; use Filenames; @@ -9,30 +9,38 @@ use Filenames; use ffi; #[derive(Debug)] -pub struct Directory<'d>( - *mut ffi::notmuch_directory_t, - PhantomData<&'d Database>, -); +pub(crate) struct DirectoryPtr { + pub ptr: *mut ffi::notmuch_directory_t +} -impl<'d> Directory<'d>{ - pub fn child_directories(self: &'d Self) -> Filenames<'d>{ - Filenames::new(unsafe { - ffi::notmuch_directory_get_child_directories(self.0) - }) +impl Drop for DirectoryPtr { + fn drop(&mut self) { + unsafe { + ffi::notmuch_directory_destroy(self.ptr) + }; } } -impl<'d> NewFromPtr<*mut ffi::notmuch_directory_t> for Directory<'d> { - fn new(ptr: *mut ffi::notmuch_directory_t) -> Directory<'d> { - Directory(ptr, PhantomData) +#[derive(Debug)] +pub struct Directory<'d>{ + handle: DirectoryPtr, + phantom: PhantomData<&'d Database>, +} + +impl<'d> Directory<'d>{ + pub fn child_directories(self: &'d Self) -> Filenames<'d>{ + Filenames::from_ptr(unsafe { + ffi::notmuch_directory_get_child_directories(self.handle.ptr) + }) } } -impl<'d> Drop for Directory<'d> { - fn drop(self: &mut Self) { - unsafe { - ffi::notmuch_directory_destroy(self.0) - }; +impl<'d> FromPtr<*mut ffi::notmuch_directory_t> for Directory<'d> { + fn from_ptr(ptr: *mut ffi::notmuch_directory_t) -> Directory<'d> { + Directory{ + handle: DirectoryPtr{ptr}, + phantom: PhantomData + } } } diff --git a/src/filenames.rs b/src/filenames.rs index d9e5bd8..5f369e8 100644 --- a/src/filenames.rs +++ b/src/filenames.rs @@ -4,35 +4,43 @@ use std::marker::PhantomData; use std::path::PathBuf; use std::ffi::CStr; -use utils::NewFromPtr; +use utils::FromPtr; use Database; use ffi; #[derive(Debug)] -pub struct Filenames<'d>( - *mut ffi::notmuch_filenames_t, - PhantomData<&'d Database>, -); - -impl<'d> NewFromPtr<*mut ffi::notmuch_filenames_t> for Filenames<'d> { - fn new(ptr: *mut ffi::notmuch_filenames_t) -> Filenames<'d> { - Filenames(ptr, PhantomData) - } +pub(crate) struct FilenamesPtr { + pub ptr: *mut ffi::notmuch_filenames_t } -impl<'d> Drop for Filenames<'d> { +impl Drop for FilenamesPtr { fn drop(self: &mut Self) { let valid = unsafe { - ffi::notmuch_filenames_valid(self.0) + ffi::notmuch_filenames_valid(self.ptr) }; if valid != 0 { unsafe { - ffi::notmuch_filenames_destroy(self.0) + ffi::notmuch_filenames_destroy(self.ptr) }; } } } + +#[derive(Debug)] +pub struct Filenames<'d>{ + pub(crate) handle: FilenamesPtr, + phantom: PhantomData<&'d Database> +} + +impl<'d> FromPtr<*mut ffi::notmuch_filenames_t> for Filenames<'d> { + fn from_ptr(ptr: *mut ffi::notmuch_filenames_t) -> Filenames<'d> { + Filenames{ + handle: FilenamesPtr{ptr}, + phantom: PhantomData + } + } +} impl<'d> Iterator for Filenames<'d> { type Item = PathBuf; @@ -40,7 +48,7 @@ impl<'d> Iterator for Filenames<'d> { fn next(self: &mut Self) -> Option<Self::Item> { let valid = unsafe { - ffi::notmuch_filenames_valid(self.0) + ffi::notmuch_filenames_valid(self.handle.ptr) }; if valid == 0{ @@ -48,8 +56,8 @@ impl<'d> Iterator for Filenames<'d> { } let ctag = unsafe { - let t = ffi::notmuch_filenames_get(self.0); - ffi::notmuch_filenames_move_to_next(self.0); + let t = ffi::notmuch_filenames_get(self.handle.ptr); + ffi::notmuch_filenames_move_to_next(self.handle.ptr); CStr::from_ptr(t) }; @@ -57,6 +65,5 @@ impl<'d> Iterator for Filenames<'d> { } } - unsafe impl<'d> Send for Filenames<'d>{} unsafe impl<'d> Sync for Filenames<'d>{} diff --git a/src/message.rs b/src/message.rs index 086670c..ddcb356 100644 --- a/src/message.rs +++ b/src/message.rs @@ -8,22 +8,39 @@ use error::{Error, Result}; use ffi; use utils::{ ToStr, - NewFromPtr + FromPtr }; use Query; use Messages; use Filenames; use Tags; + #[derive(Debug)] -pub struct Message<'d:'q, 'q>( - pub(crate) *mut ffi::notmuch_message_t, - PhantomData<&'q Query<'d>>, -); - -impl<'d, 'q> NewFromPtr<*mut ffi::notmuch_message_t> for Message<'d, 'q> { - fn new(ptr: *mut ffi::notmuch_message_t) -> Message<'d, 'q> { - Message(ptr, PhantomData) +pub(crate) struct MessagePtr { + pub ptr: *mut ffi::notmuch_message_t +} + +impl Drop for MessagePtr { + fn drop(&mut self) { + unsafe { + ffi::notmuch_message_destroy(self.ptr) + }; + } +} + +#[derive(Debug)] +pub struct Message<'d:'q, 'q>{ + pub(crate) handle: MessagePtr, + phantom: PhantomData<&'q Query<'d>>, +} + +impl<'d, 'q> FromPtr<*mut ffi::notmuch_message_t> for Message<'d, 'q> { + fn from_ptr(ptr: *mut ffi::notmuch_message_t) -> Message<'d, 'q> { + Message{ + handle: MessagePtr{ptr}, + phantom: PhantomData + } } } @@ -31,46 +48,46 @@ impl<'d, 'q> Message<'d, 'q>{ pub fn id(self: &Self) -> String{ let mid = unsafe { - ffi::notmuch_message_get_message_id(self.0) + ffi::notmuch_message_get_message_id(self.handle.ptr) }; mid.to_str().unwrap().to_string() } pub fn thread_id(self: &Self) -> String{ let tid = unsafe { - ffi::notmuch_message_get_thread_id(self.0) + ffi::notmuch_message_get_thread_id(self.handle.ptr) }; tid.to_str().unwrap().to_string() } pub fn replies(self: &'q Self) -> Messages<'d, 'q>{ - Messages::new(unsafe { - ffi::notmuch_message_get_replies(self.0) + Messages::from_ptr(unsafe { + ffi::notmuch_message_get_replies(self.handle.ptr) }) } #[cfg(feature = "v0_26")] pub fn count_files(self: &Self) -> i32{ unsafe { - ffi::notmuch_message_count_files(self.0) + ffi::notmuch_message_count_files(self.handle.ptr) } } pub fn filenames(self: &'d Self) -> Filenames<'d>{ - Filenames::new(unsafe { - ffi::notmuch_message_get_filenames(self.0) + Filenames::from_ptr(unsafe { + ffi::notmuch_message_get_filenames(self.handle.ptr) }) } pub fn filename(self: &Self) -> PathBuf{ PathBuf::from(unsafe { - ffi::notmuch_message_get_filename(self.0) + ffi::notmuch_message_get_filename(self.handle.ptr) }.to_str().unwrap()) } pub fn header(&self, name: &str) -> Result<&str> { let ret = unsafe { - ffi::notmuch_message_get_header(self.0, + ffi::notmuch_message_get_header(self.handle.ptr, CString::new(name).unwrap().as_ptr()) }; if ret.is_null() { @@ -81,20 +98,11 @@ impl<'d, 'q> Message<'d, 'q>{ } pub fn tags(self: &'d Self) -> Tags<'d>{ - Tags::new(unsafe { - ffi::notmuch_message_get_tags(self.0) + Tags::from_ptr(unsafe { + ffi::notmuch_message_get_tags(self.handle.ptr) }) } } - -impl<'d, 'q> Drop for Message<'d, 'q> { - fn drop(self: &mut Self) { - unsafe { - ffi::notmuch_message_destroy(self.0) - }; - } -} - unsafe impl<'d, 'q> Send for Message<'d, 'q>{} unsafe impl<'d, 'q> Sync for Message<'d, 'q>{} diff --git a/src/messages.rs b/src/messages.rs index 65e1248..4bc90e9 100644 --- a/src/messages.rs +++ b/src/messages.rs @@ -4,40 +4,22 @@ use std::marker::PhantomData; use ffi; use utils::{ - NewFromPtr, + FromPtr, }; use Query; use Message; use Tags; -#[derive(Debug)] -pub struct Messages<'d:'q, 'q>( - // TODO: is this lifetime specifier correct? - // query may outlive messages. - pub(crate) *mut ffi::notmuch_messages_t, - PhantomData<&'q Query<'d>>, -); - -impl<'d, 'q> NewFromPtr<*mut ffi::notmuch_messages_t> for Messages<'d, 'q> { - fn new(ptr: *mut ffi::notmuch_messages_t) -> Messages<'d, 'q> { - Messages(ptr, PhantomData) - } -} - -impl<'d, 'q> Messages<'d, 'q>{ - - pub fn collect_tags(self: &'d Self) -> Tags<'d>{ - Tags::new(unsafe { - ffi::notmuch_messages_collect_tags(self.0) - }) - } +#[derive(Debug)] +pub(crate) struct MessagesPtr { + pub ptr: *mut ffi::notmuch_messages_t } -impl<'d, 'q> Drop for Messages<'d, 'q> { +impl Drop for MessagesPtr { fn drop(self: &mut Self) { let valid = unsafe { - ffi::notmuch_messages_valid(self.0) + ffi::notmuch_messages_valid(self.ptr) }; if valid == 0{ @@ -45,18 +27,58 @@ impl<'d, 'q> Drop for Messages<'d, 'q> { } unsafe { - ffi::notmuch_messages_destroy(self.0) + ffi::notmuch_messages_destroy(self.ptr) }; } } + +#[derive(Debug)] +pub struct Messages<'d:'q, 'q>{ + pub(crate) handle: MessagesPtr, + phantom: PhantomData<&'q Query<'d>>, +} + +impl<'d, 'q> FromPtr<*mut ffi::notmuch_messages_t> for Messages<'d, 'q> { + fn from_ptr(ptr: *mut ffi::notmuch_messages_t) -> Messages<'d, 'q> { + Messages{ + handle: MessagesPtr{ptr}, + phantom: PhantomData + } + } +} + +impl<'d, 'q> Messages<'d, 'q>{ + + /** + * Return a list of tags from all messages. + * + * The resulting list is guaranteed not to contain duplicated tags. + * + * WARNING: You can no longer iterate over messages after calling this + * function, because the iterator will point at the end of the list. + * We do not have a function to reset the iterator yet and the only + * way how you can iterate over the list again is to recreate the + * message list. + * + * The function returns NULL on error. + */ + pub fn collect_tags(self: &'d Self) -> Tags{ + Tags::from_ptr(unsafe { + ffi::notmuch_messages_collect_tags(self.handle.ptr) + }) + } +} + + + impl<'d, 'q> Iterator for Messages<'d, 'q> { type Item = Message<'d, 'q>; fn next(&mut self) -> Option<Self::Item> { let valid = unsafe { - ffi::notmuch_messages_valid(self.0) + ffi::notmuch_messages_valid(self.handle.ptr) }; if valid == 0{ @@ -64,12 +86,12 @@ impl<'d, 'q> Iterator for Messages<'d, 'q> { } let cmsg = unsafe { - let msg = ffi::notmuch_messages_get(self.0); - ffi::notmuch_messages_move_to_next(self.0); + let msg = ffi::notmuch_messages_get(self.handle.ptr); + ffi::notmuch_messages_move_to_next(self.handle.ptr); msg }; - Some(Self::Item::new(cmsg)) + Some(Self::Item::from_ptr(cmsg)) } } diff --git a/src/query.rs b/src/query.rs index e0c748e..b4cd9a2 100644 --- a/src/query.rs +++ b/src/query.rs @@ -5,7 +5,7 @@ use std::marker::PhantomData; use error::Result; use ffi; -use utils::NewFromPtr; +use utils::FromPtr; use Database; use Messages; @@ -13,11 +13,32 @@ use Threads; use ffi::Sort; #[derive(Debug)] -pub struct Query<'d>( - pub(crate) *mut ffi::notmuch_query_t, - PhantomData<&'d Database>, -); +pub(crate) struct QueryPtr { + pub ptr: *mut ffi::notmuch_query_t +} +impl Drop for QueryPtr { + fn drop(&mut self) { + unsafe { + ffi::notmuch_query_destroy(self.ptr) + }; + } +} + +#[derive(Debug)] +pub struct Query<'d>{ + pub(crate) handle: QueryPtr, + phantom: PhantomData<&'d Database>, +} + +impl<'d> FromPtr<*mut ffi::notmuch_query_t> for Query<'d> { + fn from_ptr(ptr: *mut ffi::notmuch_query_t) -> Query<'d> { + Query{ + handle: QueryPtr{ptr}, + phantom: PhantomData + } + } +} impl<'d> Query<'d> { pub fn create(db: &'d Database, query_string: &str) -> Result<Self> { @@ -29,7 +50,7 @@ impl<'d> Query<'d> { { unsafe { ffi::notmuch_query_set_sort( - self.0, sort.into(), + self.handle.ptr, sort.into(), ) } } @@ -40,7 +61,7 @@ impl<'d> Query<'d> { { unsafe { ffi::notmuch_query_get_sort( - self.0, + self.handle.ptr, ) }.into() } @@ -52,11 +73,11 @@ impl<'d> Query<'d> { let mut msgs = ptr::null_mut(); try!(unsafe { ffi::notmuch_query_search_messages( - self.0, &mut msgs, + self.handle.ptr, &mut msgs, ) }.as_result()); - Ok(Messages::new(msgs)) + Ok(Messages::from_ptr(msgs)) } pub fn count_messages(self: &Self) -> Result<u32> @@ -64,7 +85,7 @@ impl<'d> Query<'d> { let mut cnt = 0; try!(unsafe { ffi::notmuch_query_count_messages( - self.0, &mut cnt, + self.handle.ptr, &mut cnt, ) }.as_result()); @@ -76,11 +97,11 @@ impl<'d> Query<'d> { let mut thrds = ptr::null_mut(); try!(unsafe { ffi::notmuch_query_search_threads( - self.0, &mut thrds, + self.handle.ptr, &mut thrds, ) }.as_result()); - Ok(Threads::new(thrds)) + Ok(Threads::from_ptr(thrds)) } pub fn count_threads(self: &Self) -> Result<u32> @@ -88,7 +109,7 @@ impl<'d> Query<'d> { let mut cnt = 0; try!(unsafe { ffi::notmuch_query_count_threads( - self.0, &mut cnt, + self.handle.ptr, &mut cnt, ) }.as_result()); @@ -96,20 +117,6 @@ impl<'d> Query<'d> { } } -impl<'d> NewFromPtr<*mut ffi::notmuch_query_t> for Query<'d> { - fn new(ptr: *mut ffi::notmuch_query_t) -> Query<'d> { - Query(ptr, PhantomData) - } -} - - -impl<'d> Drop for Query<'d> { - fn drop(&mut self) { - unsafe { - ffi::notmuch_query_destroy(self.0) - }; - } -} unsafe impl<'d> Send for Query<'d> {} unsafe impl<'d> Sync for Query<'d> {} diff --git a/src/tags.rs b/src/tags.rs index 04c7cd5..61f99b7 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -4,7 +4,7 @@ use std::marker::PhantomData; use std::ffi::CStr; use utils::{ - NewFromPtr, + FromPtr, }; use Database; @@ -16,8 +16,8 @@ pub struct Tags<'d>( PhantomData<&'d Database>, ); -impl<'d> NewFromPtr<*mut ffi::notmuch_tags_t> for Tags<'d> { - fn new(ptr: *mut ffi::notmuch_tags_t) -> Tags<'d> { +impl<'d> FromPtr<*mut ffi::notmuch_tags_t> for Tags<'d> { + fn from_ptr(ptr: *mut ffi::notmuch_tags_t) -> Tags<'d> { Tags(ptr, PhantomData) } } diff --git a/src/thread.rs b/src/thread.rs index 4f98c26..60782f5 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -2,7 +2,7 @@ use std::ops::Drop; use std::marker::PhantomData; use ffi; use utils::{ - NewFromPtr, + FromPtr, ToStr }; use Query; @@ -10,14 +10,31 @@ use Messages; use Tags; #[derive(Debug)] -pub struct Thread<'d:'q, 'q>( - pub(crate) *mut ffi::notmuch_thread_t, - PhantomData<&'q Query<'d>>, -); - -impl<'d, 'q> NewFromPtr<*mut ffi::notmuch_thread_t> for Thread<'d, 'q> { - fn new(ptr: *mut ffi::notmuch_thread_t) -> Thread<'d, 'q> { - Thread(ptr, PhantomData) +pub(crate) struct ThreadPtr { + pub ptr: *mut ffi::notmuch_thread_t +} + +impl Drop for ThreadPtr { + fn drop(&mut self) { + unsafe { + ffi::notmuch_thread_destroy(self.ptr) + }; + } +} + + +#[derive(Debug)] +pub struct Thread<'d:'q, 'q>{ + pub(crate) handle: ThreadPtr, + phantom: PhantomData<&'q Query<'d>>, +} + +impl<'d, 'q> FromPtr<*mut ffi::notmuch_thread_t> for Thread<'d, 'q> { + fn from_ptr(ptr: *mut ffi::notmuch_thread_t) -> Thread<'d, 'q> { + Thread{ + handle: ThreadPtr{ptr}, + phantom: PhantomData + } } } @@ -25,7 +42,7 @@ impl<'d, 'q> Thread<'d, 'q>{ pub fn id(self: &Self) -> String{ let tid = unsafe { - ffi::notmuch_thread_get_thread_id(self.0) + ffi::notmuch_thread_get_thread_id(self.handle.ptr) }; tid.to_str().unwrap().to_string() } @@ -33,42 +50,42 @@ impl<'d, 'q> Thread<'d, 'q>{ pub fn total_messages(self: &Self) -> i32{ unsafe { - ffi::notmuch_thread_get_total_messages(self.0) + ffi::notmuch_thread_get_total_messages(self.handle.ptr) } } #[cfg(feature = "0.26")] pub fn total_files(self: &Self) -> i32{ unsafe { - ffi::notmuch_thread_get_total_files(self.0) + ffi::notmuch_thread_get_total_files(self.handle.ptr) } } pub fn toplevel_messages(self: &Self) -> Messages{ - Messages::new(unsafe { - ffi::notmuch_thread_get_toplevel_messages(self.0) + Messages::from_ptr(unsafe { + ffi::notmuch_thread_get_toplevel_messages(self.handle.ptr) }) } /// Get a `Messages` iterator for all messages in 'thread' in /// oldest-first order. pub fn messages(self: &Self) -> Messages{ - Messages::new(unsafe { - ffi::notmuch_thread_get_messages(self.0) + Messages::from_ptr(unsafe { + ffi::notmuch_thread_get_messages(self.handle.ptr) }) } - pub fn tags(self: &Self) -> Tags{ - Tags::new(unsafe { - ffi::notmuch_thread_get_tags(self.0) + pub fn tags<'t>(self: &Self) -> Tags{ + Tags::from_ptr(unsafe { + ffi::notmuch_thread_get_tags(self.handle.ptr) }) } pub fn subject(self: &Self) -> String{ let sub = unsafe { - ffi::notmuch_thread_get_subject(self.0) + ffi::notmuch_thread_get_subject(self.handle.ptr) }; sub.to_str().unwrap().to_string() @@ -76,7 +93,7 @@ impl<'d, 'q> Thread<'d, 'q>{ pub fn authors(self: &Self) -> Vec<String>{ let athrs = unsafe { - ffi::notmuch_thread_get_authors(self.0) + ffi::notmuch_thread_get_authors(self.handle.ptr) }; athrs.to_str().unwrap().split(',').map(|s| s.to_string()).collect() @@ -85,26 +102,18 @@ impl<'d, 'q> Thread<'d, 'q>{ /// Get the date of the oldest message in 'thread' as a time_t value. pub fn oldest_date(self: &Self) -> i64 { unsafe { - ffi::notmuch_thread_get_oldest_date(self.0) + ffi::notmuch_thread_get_oldest_date(self.handle.ptr) } } /// Get the date of the newest message in 'thread' as a time_t value. pub fn newest_date(self: &Self) -> i64 { unsafe { - ffi::notmuch_thread_get_newest_date(self.0) + ffi::notmuch_thread_get_newest_date(self.handle.ptr) } } } -impl<'d, 'q> Drop for Thread<'d, 'q> { - fn drop(&mut self) { - unsafe { - ffi::notmuch_thread_destroy(self.0) - }; - } -} - unsafe impl<'d, 'q> Send for Thread<'d, 'q> {} unsafe impl<'d, 'q> Sync for Thread<'d, 'q> {} diff --git a/src/threads.rs b/src/threads.rs index 20fc302..a98caba 100644 --- a/src/threads.rs +++ b/src/threads.rs @@ -2,38 +2,46 @@ use std::ops::Drop; use std::iter::Iterator; use std::marker::PhantomData; -use utils::NewFromPtr; +use utils::FromPtr; use Query; use Thread; use ffi; #[derive(Debug)] -pub struct Threads<'d:'q, 'q>( - *mut ffi::notmuch_threads_t, - PhantomData<&'q Query<'d>>, -); - -impl<'d, 'q> NewFromPtr<*mut ffi::notmuch_threads_t> for Threads<'d, 'q> { - fn new(ptr: *mut ffi::notmuch_threads_t) -> Threads<'d, 'q> { - Threads(ptr, PhantomData) - } +pub(crate) struct ThreadsPtr { + pub ptr: *mut ffi::notmuch_threads_t } -impl<'d, 'q> Drop for Threads<'d, 'q> { +impl Drop for ThreadsPtr { fn drop(&mut self) { unsafe { - ffi::notmuch_threads_destroy(self.0) + ffi::notmuch_threads_destroy(self.ptr) }; } } +#[derive(Debug)] +pub struct Threads<'d:'q, 'q>{ + handle: ThreadsPtr, + phantom: PhantomData<&'q Query<'d>>, +} + +impl<'d, 'q> FromPtr<*mut ffi::notmuch_threads_t> for Threads<'d, 'q> { + fn from_ptr(ptr: *mut ffi::notmuch_threads_t) -> Threads<'d, 'q> { + Threads{ + handle: ThreadsPtr{ptr}, + phantom: PhantomData + } + } +} + impl<'d, 'q> Iterator for Threads<'d, 'q> { type Item = Thread<'d, 'q>; fn next(self: &mut Self) -> Option<Self::Item> { let valid = unsafe { - ffi::notmuch_threads_valid(self.0) + ffi::notmuch_threads_valid(self.handle.ptr) }; if valid == 0{ @@ -41,12 +49,12 @@ impl<'d, 'q> Iterator for Threads<'d, 'q> { } let cthread = unsafe { - let t = ffi::notmuch_threads_get(self.0); - ffi::notmuch_threads_move_to_next(self.0); + let t = ffi::notmuch_threads_get(self.handle.ptr); + ffi::notmuch_threads_move_to_next(self.handle.ptr); t }; - Some(Self::Item::new(cthread)) + Some(Self::Item::from_ptr(cthread)) } } diff --git a/src/utils.rs b/src/utils.rs index bdc8c4f..9de7e08 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,10 +4,14 @@ use std::{ }; use libc; -pub trait NewFromPtr<T> { - fn new(ptr: T) -> Self; +pub trait FromPtr<T> { + fn from_ptr(ptr: T) -> Self; } +// pub trait NewFromPtr<T, P> { +// fn new(ptr: T, parent: Rc<P>) -> Self; +// } + pub trait ToStr { fn to_str<'a>(&self) -> Result<&'a str, str::Utf8Error>; } @@ -31,3 +35,5 @@ impl ToString for *const libc::c_char { } } } + + |
