aboutsummaryrefslogtreecommitdiffstats
path: root/notmuch/src/thread.rs
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-04-25 16:58:17 +0200
committerGustav Sörnäs <gustav@sornas.net>2021-04-25 16:58:17 +0200
commit72c2b83748a601d02c82d5bcb4220d3b238281cc (patch)
tree38acb17db4a48fc9f340680ea5b86c6cd49d8f2a /notmuch/src/thread.rs
parent51fa75397dda2c280f29760e7b525caefc03642e (diff)
parent2231a5cf6cdeb90c1cdb75d161a0063d4a385576 (diff)
downloadmail-72c2b83748a601d02c82d5bcb4220d3b238281cc.tar.gz
Add 'notmuch/' from commit '2231a5cf6cdeb90c1cdb75d161a0063d4a385576'
git-subtree-dir: notmuch git-subtree-mainline: 51fa75397dda2c280f29760e7b525caefc03642e git-subtree-split: 2231a5cf6cdeb90c1cdb75d161a0063d4a385576
Diffstat (limited to 'notmuch/src/thread.rs')
-rw-r--r--notmuch/src/thread.rs148
1 files changed, 148 insertions, 0 deletions
diff --git a/notmuch/src/thread.rs b/notmuch/src/thread.rs
new file mode 100644
index 0000000..ffc1f2f
--- /dev/null
+++ b/notmuch/src/thread.rs
@@ -0,0 +1,148 @@
+use std::ops::Drop;
+use std::borrow::Cow;
+
+use ffi;
+use utils::{ToStr, ScopedSupercow, ScopedPhantomcow};
+use Messages;
+use MessageOwner;
+use Tags;
+use TagsOwner;
+use Query;
+
+#[derive(Debug)]
+pub struct Thread<'d, 'q>
+where
+ 'd: 'q
+{
+ pub(crate) ptr: *mut ffi::notmuch_thread_t,
+ pub(crate) marker: ScopedPhantomcow<'q, Query<'d>>,
+}
+
+impl<'d, 'q> Drop for Thread<'d, 'q>
+where
+ 'd: 'q
+{
+ fn drop(&mut self) {
+ unsafe { ffi::notmuch_thread_destroy(self.ptr) };
+ }
+}
+
+impl<'d, 'q> MessageOwner for Thread<'d, 'q> where 'd: 'q {}
+impl<'d, 'q> TagsOwner for Thread<'d, 'q> where 'd: 'q {}
+
+impl<'d, 'q> Thread<'d, 'q>
+where
+ 'd: 'q
+{
+ pub(crate) fn from_ptr<P>(ptr: *mut ffi::notmuch_thread_t, owner: P) -> Thread<'d, 'q>
+ where
+ P: Into<ScopedPhantomcow<'q, Query<'d>>>,
+ {
+ Thread {
+ ptr,
+ marker: owner.into(),
+ }
+ }
+
+ pub fn id(self: &Self) -> &str {
+ let tid = unsafe { ffi::notmuch_thread_get_thread_id(self.ptr) };
+ tid.to_str().unwrap()
+ }
+
+ pub fn total_messages(self: &Self) -> i32 {
+ unsafe { ffi::notmuch_thread_get_total_messages(self.ptr) }
+ }
+
+ #[cfg(feature = "0.26")]
+ pub fn total_files(self: &Self) -> i32 {
+ unsafe { ffi::notmuch_thread_get_total_files(self.ptr) }
+ }
+
+ pub fn toplevel_messages(self: &Self) -> Messages<'_, Self> {
+ <Self as ThreadExt<'d, 'q>>::toplevel_messages(self)
+ }
+
+ pub fn matched_messages(self: &Self) -> i32 {
+ unsafe { ffi::notmuch_thread_get_matched_messages(self.ptr) }
+ }
+
+ /// Get a `Messages` iterator for all messages in 'thread' in
+ /// oldest-first order.
+ pub fn messages(self: &Self) -> Messages<'_, Self> {
+ <Self as ThreadExt<'d, 'q>>::messages(self)
+ }
+
+ pub fn tags(&self) -> Tags<'_, Self> {
+ <Self as ThreadExt<'d, 'q>>::tags(self)
+ }
+
+ pub fn subject(self: &Self) -> Cow<'_, str> {
+ let sub = unsafe { ffi::notmuch_thread_get_subject(self.ptr) };
+ sub.to_string_lossy()
+ }
+
+ pub fn authors(self: &Self) -> Vec<String> {
+ let athrs = unsafe { ffi::notmuch_thread_get_authors(self.ptr) };
+
+ athrs
+ .to_string_lossy()
+ .split(',')
+ .map(|s| s.to_string())
+ .collect()
+ }
+
+ /// 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.ptr) as i64 }
+ }
+
+ /// 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.ptr) as i64 }
+ }
+}
+
+pub trait ThreadExt<'d, 'q>
+where
+ 'd: 'q
+{
+ fn tags<'s, S>(thread: S) -> Tags<'s, Thread<'d, 'q>>
+ where
+ S: Into<ScopedSupercow<'s, Thread<'d, 'q>>>,
+ {
+ let threadref = thread.into();
+ Tags::from_ptr(
+ unsafe { ffi::notmuch_thread_get_tags(threadref.ptr) },
+ ScopedSupercow::phantom(threadref),
+ )
+ }
+
+ fn toplevel_messages<'s, S>(thread: S) -> Messages<'s, Thread<'d, 'q>>
+ where
+ S: Into<ScopedSupercow<'s, Thread<'d, 'q>>>,
+ {
+ let threadref = thread.into();
+ Messages::from_ptr(
+ unsafe { ffi::notmuch_thread_get_toplevel_messages(threadref.ptr) },
+ ScopedSupercow::phantom(threadref),
+ )
+ }
+
+ /// Get a `Messages` iterator for all messages in 'thread' in
+ /// oldest-first order.
+ fn messages<'s, S>(thread: S) -> Messages<'s, Thread<'d, 'q>>
+ where
+ S: Into<ScopedSupercow<'s, Thread<'d, 'q>>>,
+ {
+ let threadref = thread.into();
+ Messages::from_ptr(
+ unsafe { ffi::notmuch_thread_get_messages(threadref.ptr) },
+ ScopedSupercow::phantom(threadref),
+ )
+ }
+}
+
+impl<'d, 'q> ThreadExt<'d, 'q> for Thread<'d, 'q> where 'd: 'q {}
+
+unsafe impl<'d, 'q> Send for Thread<'d, 'q> where 'd: 'q {}
+unsafe impl<'d, 'q> Sync for Thread<'d, 'q> where 'd: 'q {}