aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDirk Van Haerenborgh <vhdirk@gmail.com>2018-10-16 21:01:58 +0200
committerDirk Van Haerenborgh <vhdirk@gmail.com>2018-10-24 07:12:55 +0200
commita4ffe47c51d1617fc0e728c7bbd7e9b3738878cb (patch)
tree017d0717ac8e2d5e0f6a46e47ea9e731ce63697b
parentb93d4cb749714699b44b2566e50a7086c2854ac7 (diff)
downloadmail-a4ffe47c51d1617fc0e728c7bbd7e9b3738878cb.tar.gz
some tries towards better lifetimes
-rw-r--r--src/database.rs57
-rw-r--r--src/directory.rs44
-rw-r--r--src/filenames.rs41
-rw-r--r--src/message.rs66
-rw-r--r--src/messages.rs80
-rw-r--r--src/query.rs61
-rw-r--r--src/tags.rs6
-rw-r--r--src/thread.rs71
-rw-r--r--src/threads.rs40
-rw-r--r--src/utils.rs10
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 {
}
}
}
+
+