aboutsummaryrefslogtreecommitdiffstats
path: root/src/messages.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/messages.rs')
-rw-r--r--src/messages.rs140
1 files changed, 76 insertions, 64 deletions
diff --git a/src/messages.rs b/src/messages.rs
index 88c52ec..dc0f59e 100644
--- a/src/messages.rs
+++ b/src/messages.rs
@@ -1,63 +1,51 @@
use std::ops::Drop;
-use supercow::{Phantomcow, Supercow};
-
-use crate::ffi;
-use crate::utils::{StreamingIterator, StreamingIteratorExt};
-use crate::Message;
-use crate::MessageOwner;
-use crate::Tags;
-use crate::TagsOwner;
-
-pub trait MessagesOwner {}
+use ffi;
+use utils::ScopedPhantomcow;
+use MessageOwner;
+use Message;
+use Tags;
+use TagsOwner;
#[derive(Debug)]
-pub struct MessagesPtr {
- pub ptr: *mut ffi::notmuch_messages_t,
+pub struct Messages<'o, O>
+where
+ O: MessageOwner + 'o,
+{
+ pub(crate) ptr: *mut ffi::notmuch_messages_t,
+ marker: ScopedPhantomcow<'o, O>,
}
-impl Drop for MessagesPtr {
+impl<'o, O> Drop for Messages<'o, O>
+where
+ O: MessageOwner + 'o,
+{
fn drop(self: &mut Self) {
- let valid = unsafe { ffi::notmuch_messages_valid(self.ptr) };
-
- if valid == 0 {
- return;
- }
-
unsafe { ffi::notmuch_messages_destroy(self.ptr) };
}
}
-#[derive(Debug)]
-pub struct Messages<'o, O>
-where
- O: MessagesOwner,
-{
- pub(crate) handle: MessagesPtr,
- marker: Phantomcow<'o, O>,
-}
-
impl<'o, O> Messages<'o, O>
where
- O: MessagesOwner + 'o,
+ O: MessageOwner + 'o,
{
pub(crate) fn from_ptr<P>(ptr: *mut ffi::notmuch_messages_t, owner: P) -> Messages<'o, O>
where
- P: Into<Phantomcow<'o, O>>,
+ P: Into<ScopedPhantomcow<'o, O>>,
{
Messages {
- handle: MessagesPtr { ptr },
+ ptr,
marker: owner.into(),
}
}
}
-impl<'o, O> MessageOwner for Messages<'o, O> where O: MessagesOwner + 'o {}
-impl<'o, O> TagsOwner for Messages<'o, O> where O: MessagesOwner + 'o {}
+impl<'o, O> MessageOwner for Messages<'o, O> where O: MessageOwner + 'o {}
+impl<'o, O> TagsOwner for Messages<'o, O> where O: MessageOwner + 'o {}
impl<'o, O> Messages<'o, O>
where
- O: MessagesOwner + 'o,
+ O: MessageOwner + 'o,
{
/**
* Return a list of tags from all messages.
@@ -74,53 +62,77 @@ where
*/
pub fn collect_tags<'m>(self: &'o Self) -> Tags<'m, Self> {
Tags::from_ptr(
- unsafe { ffi::notmuch_messages_collect_tags(self.handle.ptr) },
+ unsafe { ffi::notmuch_messages_collect_tags(self.ptr) },
self,
)
}
}
-impl<'s, 'o: 's, O> StreamingIterator<'s, Message<'s, Self>> for Messages<'o, O>
+impl<'o, O> Iterator for Messages<'o, O>
where
- O: MessagesOwner + 'o,
+ O: MessageOwner + 'o,
{
- fn next(&'s mut self) -> Option<Message<'s, Self>> {
- <Self as StreamingIteratorExt<'s, Message<'s, Self>>>::next(Supercow::borrowed(self))
+ type Item = Message<'o, O>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let valid = unsafe { ffi::notmuch_messages_valid(self.ptr) };
+
+ if valid == 0 {
+ return None;
+ }
+
+ let cthrd = unsafe {
+ let thrd = ffi::notmuch_messages_get(self.ptr);
+ ffi::notmuch_messages_move_to_next(self.ptr);
+ thrd
+ };
+
+ Some(Message::from_ptr(cthrd, ScopedPhantomcow::<'o, O>::share(&mut self.marker)))
}
}
+
+
pub trait MessagesExt<'o, O>
where
- O: MessagesOwner + 'o,
+ O: MessageOwner + 'o,
{
}
-impl<'o, O> MessagesExt<'o, O> for Messages<'o, O> where O: MessagesOwner + 'o {}
-
-impl<'s, 'o: 's, O> StreamingIteratorExt<'s, Message<'s, Self>> for Messages<'o, O>
-where
- O: MessagesOwner + 'o,
-{
- fn next<S>(messages: S) -> Option<Message<'s, Self>>
- where
- S: Into<Supercow<'s, Messages<'o, O>>>,
- {
- let messagesref = messages.into();
- let valid = unsafe { ffi::notmuch_messages_valid(messagesref.handle.ptr) };
+impl<'o, O> MessagesExt<'o, O> for Messages<'o, O> where O: MessageOwner + 'o {}
- if valid == 0 {
- return None;
- }
- let cmsg = unsafe {
- let msg = ffi::notmuch_messages_get(messagesref.handle.ptr);
- ffi::notmuch_messages_move_to_next(messagesref.handle.ptr);
- msg
- };
+unsafe impl<'o, O> Send for Messages<'o, O> where O: MessageOwner + 'o {}
+unsafe impl<'o, O> Sync for Messages<'o, O> where O: MessageOwner + 'o {}
- Some(Message::from_ptr(cmsg, Supercow::phantom(messagesref)))
+#[cfg(test)]
+mod tests {
+ // This will not compile if ownership can't be subject to recursion
+ fn descend<'o, O: 'o + super::MessageOwner, T: Iterator<Item=super::Message<'o, O>>>(iter: T)
+ -> usize {
+ iter.map(|msg| descend(msg.replies()) ).count()
+ }
+
+ use query::Query;
+ use database;
+
+ #[test]
+ #[should_panic] // until test data is filled in
+ fn recurse() -> () {
+ match database::Database::open(
+ &String::new(),
+ database::DatabaseMode::ReadOnly,
+ ) {
+ /* This will not happen without test data, but will force the compiler to compile
+ * the descend function.
+ */
+ Ok(db) => {
+ let q = Query::create(db, &String::new()).unwrap();
+ descend::<Query, super::Messages<Query>>(q.search_messages().unwrap());
+ }
+ Err(err) => {
+ panic!("Got error while trying to open db: {:?}", err);
+ }
+ }
}
}
-
-unsafe impl<'o, O> Send for Messages<'o, O> where O: MessagesOwner + 'o {}
-unsafe impl<'o, O> Sync for Messages<'o, O> where O: MessagesOwner + 'o {}