aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDirk Van Haerenborgh <vhdirk@gmail.com>2018-11-01 21:55:00 +0100
committerDirk Van Haerenborgh <vhdirk@gmail.com>2018-11-01 21:55:00 +0100
commit7d2be237297c16628cb3d58774e808cac9c92fc1 (patch)
tree55cb240828bac9968f94166e740b567b66928e3b
parent2932d67d87fa2ff41fcdf46ce269ba5b49294930 (diff)
downloadmail-7d2be237297c16628cb3d58774e808cac9c92fc1.tar.gz
improve lifetime management with supercow
-rw-r--r--Cargo.toml1
-rw-r--r--src/database.rs199
-rw-r--r--src/directory.rs62
-rw-r--r--src/error.rs9
-rw-r--r--src/filenames.rs53
-rw-r--r--src/lib.rs28
-rw-r--r--src/message.rs120
-rw-r--r--src/messages.rs90
-rw-r--r--src/query.rs105
-rw-r--r--src/tags.rs65
-rw-r--r--src/thread.rs126
-rw-r--r--src/threads.rs55
-rw-r--r--src/utils.rs31
-rw-r--r--tests/main.rs12
14 files changed, 421 insertions, 535 deletions
diff --git a/Cargo.toml b/Cargo.toml
index cc152bf..0d8ee81 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@ travis-ci = { repository = "vhdirk/notmuch-rs" }
[dependencies]
libc = "0.2"
clippy = { version = "0.0.193", optional = true }
+supercow = "0.1.0"
[dev-dependencies]
dirs = "1.0"
diff --git a/src/database.rs b/src/database.rs
index 467c3ba..6390c15 100644
--- a/src/database.rs
+++ b/src/database.rs
@@ -1,22 +1,17 @@
+use std::ffi::{CStr, CString};
use std::ops::Drop;
-use std::ptr;
use std::path::Path;
-use std::ffi::{CStr, CString};
+use std::ptr;
use libc;
use error::Result;
-use utils::{
- FromPtr,
- ToStr,
-};
-
+use ffi;
+use utils::ToStr;
use Directory;
use Query;
use Tags;
-use tags::TagsOwner;
-
-use ffi;
+use TagsOwner;
// Re-exported under database module for pretty namespacin'.
pub use ffi::DatabaseMode;
@@ -25,139 +20,145 @@ pub use ffi::DatabaseMode;
pub struct Version(libc::c_uint);
#[derive(Clone, Debug)]
-pub struct Revision{
+pub struct Revision {
pub revision: libc::c_ulong,
- pub uuid: String
+ pub uuid: String,
}
#[derive(Debug)]
pub(crate) struct DatabasePtr {
- pub ptr: *mut ffi::notmuch_database_t
+ pub ptr: *mut ffi::notmuch_database_t,
}
impl Drop for DatabasePtr {
fn drop(&mut self) {
- unsafe {
- ffi::notmuch_database_destroy(self.ptr)
- };
+ unsafe { ffi::notmuch_database_destroy(self.ptr) };
}
}
#[derive(Debug)]
-pub struct Database{
- pub(crate) handle: DatabasePtr
+pub struct Database {
+ pub(crate) handle: DatabasePtr,
}
-impl TagsOwner for Database{}
+impl TagsOwner for Database {}
impl Database {
pub fn create<P: AsRef<Path>>(path: &P) -> Result<Self> {
let path_str = CString::new(path.as_ref().to_str().unwrap()).unwrap();
let mut db = ptr::null_mut();
- try!(unsafe {
- ffi::notmuch_database_create(path_str.as_ptr(), &mut db)
- }.as_result());
+ try!(unsafe { ffi::notmuch_database_create(path_str.as_ptr(), &mut db) }.as_result());
- Ok(Database{handle:DatabasePtr{ptr:db}})
+ Ok(Database {
+ handle: DatabasePtr { ptr: db },
+ })
}
pub fn open<P: AsRef<Path>>(path: &P, mode: DatabaseMode) -> Result<Self> {
let path_str = CString::new(path.as_ref().to_str().unwrap()).unwrap();
let mut db = ptr::null_mut();
- try!(unsafe {
- ffi::notmuch_database_open(
- path_str.as_ptr(),
- mode.into(),
- &mut db,
- )
- }.as_result());
+ try!(
+ unsafe { ffi::notmuch_database_open(path_str.as_ptr(), mode.into(), &mut db,) }
+ .as_result()
+ );
- Ok(Database{handle:DatabasePtr{ptr:db}})
+ Ok(Database {
+ handle: DatabasePtr { ptr: db },
+ })
}
pub fn close(&mut self) -> Result<()> {
- try!(unsafe {
- ffi::notmuch_database_close(self.handle.ptr)
- }.as_result());
+ try!(unsafe { ffi::notmuch_database_close(self.handle.ptr) }.as_result());
Ok(())
}
pub fn compact<P: AsRef<Path>, F: FnMut(&str)>(
- path: &P, backup_path: Option<&P>,
+ path: &P,
+ backup_path: Option<&P>,
) -> Result<()> {
let status: Option<F> = None;
Database::_compact(path, backup_path, status)
}
pub fn compact_with_status<P: AsRef<Path>, F: FnMut(&str)>(
- path: &P, backup_path: Option<&P>, status: F,
+ path: &P,
+ backup_path: Option<&P>,
+ status: F,
) -> Result<()> {
Database::_compact(path, backup_path, Some(status))
}
fn _compact<P: AsRef<Path>, F: FnMut(&str)>(
- path: &P, backup_path: Option<&P>, status: Option<F>,
+ path: &P,
+ backup_path: Option<&P>,
+ status: Option<F>,
) -> Result<()> {
-
- extern fn wrapper<F: FnMut(&str)>(
- message:*const libc::c_char, closure: *mut libc::c_void,
+ extern "C" fn wrapper<F: FnMut(&str)>(
+ message: *const libc::c_char,
+ closure: *mut libc::c_void,
) {
let closure = closure as *mut F;
- unsafe {
- (*closure)(message.to_str().unwrap())
- }
+ unsafe { (*closure)(message.to_str().unwrap()) }
}
let path_str = CString::new(path.as_ref().to_str().unwrap()).unwrap();
- let backup_path = backup_path.map(|p| {
- CString::new(p.as_ref().to_str().unwrap()).unwrap()
- });
-
- try!(unsafe {
- ffi::notmuch_database_compact(
- path_str.as_ptr(), backup_path.map_or(ptr::null(), |p| p.as_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
- }),
- )
- }.as_result());
+ let backup_path = backup_path.map(|p| CString::new(p.as_ref().to_str().unwrap()).unwrap());
+
+ try!(
+ unsafe {
+ ffi::notmuch_database_compact(
+ path_str.as_ptr(),
+ backup_path.map_or(ptr::null(), |p| p.as_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),
+ )
+ }
+ .as_result()
+ );
Ok(())
}
pub fn path(&self) -> &Path {
- Path::new(unsafe {
- ffi::notmuch_database_get_path(self.handle.ptr)
- }.to_str().unwrap())
+ Path::new(
+ unsafe { ffi::notmuch_database_get_path(self.handle.ptr) }
+ .to_str()
+ .unwrap(),
+ )
}
pub fn version(&self) -> Version {
- Version(unsafe {
- ffi::notmuch_database_get_version(self.handle.ptr)
- })
+ Version(unsafe { ffi::notmuch_database_get_version(self.handle.ptr) })
}
#[cfg(feature = "v0_21")]
pub fn revision(&self) -> Revision {
let uuid_p: *const libc::c_char = ptr::null();
let revision = unsafe {
- ffi::notmuch_database_get_revision(self.handle.ptr, (&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) };
- Revision{revision, uuid: uuid.to_string_lossy().into_owned()}
+ Revision {
+ revision,
+ uuid: uuid.to_string_lossy().into_owned(),
+ }
}
pub fn needs_upgrade(&self) -> bool {
- unsafe {
- ffi::notmuch_database_needs_upgrade(self.handle.ptr) == 1
- }
+ unsafe { ffi::notmuch_database_needs_upgrade(self.handle.ptr) == 1 }
}
pub fn upgrade<F: FnMut(f64)>(&mut self) -> Result<()> {
@@ -170,26 +171,26 @@ impl Database {
}
fn _upgrade<F: FnMut(f64)>(&mut self, status: Option<F>) -> Result<()> {
-
#[allow(trivial_numeric_casts)]
- extern fn wrapper<F: FnMut(f64)>(
- closure: *mut libc::c_void, progress: libc::c_double,
- ) {
+ extern "C" fn wrapper<F: FnMut(f64)>(closure: *mut libc::c_void, progress: libc::c_double) {
let closure = closure as *mut F;
- unsafe {
- (*closure)(progress as f64)
- }
+ unsafe { (*closure)(progress as f64) }
}
- try!(unsafe {
- ffi::notmuch_database_upgrade(
- 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
- }),
- )
- }.as_result());
+ try!(
+ unsafe {
+ ffi::notmuch_database_upgrade(
+ 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),
+ )
+ }
+ .as_result()
+ );
Ok(())
}
@@ -198,32 +199,32 @@ impl Database {
let path_str = CString::new(path.as_ref().to_str().unwrap()).unwrap();
let mut dir = ptr::null_mut();
- try!(unsafe {
- ffi::notmuch_database_get_directory(
- self.handle.ptr, path_str.as_ptr(), &mut dir,
- )
- }.as_result());
+ try!(
+ unsafe {
+ ffi::notmuch_database_get_directory(self.handle.ptr, path_str.as_ptr(), &mut dir)
+ }
+ .as_result()
+ );
- if dir.is_null() { Ok(None) } else { Ok(Some(Directory::from_ptr(dir))) }
+ if dir.is_null() {
+ Ok(None)
+ } else {
+ Ok(Some(Directory::from_ptr(dir, self)))
+ }
}
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.handle.ptr, query_str.as_ptr())
- };
+ let query = unsafe { ffi::notmuch_query_create(self.handle.ptr, query_str.as_ptr()) };
- Ok(Query::from_ptr(query))
+ Ok(Query::from_ptr(query, self))
}
- pub fn all_tags<'d>(&self) -> Result<Tags<'d, Self>> {
-
- let tags = unsafe {
- ffi::notmuch_database_get_all_tags(self.handle.ptr)
- };
+ pub fn all_tags<'d>(&'d self) -> Result<Tags<'d, Self>> {
+ let tags = unsafe { ffi::notmuch_database_get_all_tags(self.handle.ptr) };
- Ok(Tags::from_ptr(tags))
+ Ok(Tags::from_ptr(tags, self))
}
}
diff --git a/src/directory.rs b/src/directory.rs
index ce219f5..9bdae2d 100644
--- a/src/directory.rs
+++ b/src/directory.rs
@@ -1,64 +1,48 @@
use std::ops::Drop;
-use std::marker::PhantomData;
-
-use utils::FromPtr;
+use supercow::Phantomcow;
+use ffi;
use Database;
use Filenames;
-use filenames::{FilenamesPtr, FilenamesOwner};
-
-use ffi;
+use FilenamesOwner;
#[derive(Debug)]
pub(crate) struct DirectoryPtr {
- pub ptr: *mut ffi::notmuch_directory_t
+ pub ptr: *mut ffi::notmuch_directory_t,
}
impl Drop for DirectoryPtr {
fn drop(&mut self) {
- unsafe {
- ffi::notmuch_directory_destroy(self.ptr)
- };
- }
-}
-
-impl DirectoryPtr {
- pub fn child_directories(self: &Self) -> FilenamesPtr{
- FilenamesPtr{
- ptr: unsafe {
- ffi::notmuch_directory_get_child_directories(self.ptr)
- }
- }
+ unsafe { ffi::notmuch_directory_destroy(self.ptr) };
}
}
-
-
#[derive(Debug)]
-pub struct Directory<'d>{
+pub struct Directory<'d> {
handle: DirectoryPtr,
- phantom: PhantomData<&'d Database>,
+ marker: Phantomcow<'d, Database>,
}
-impl<'d> FilenamesOwner for Directory<'d>{}
+impl<'d> FilenamesOwner for Directory<'d> {}
-impl<'d> Directory<'d>{
- pub fn child_directories(self: &'d Self) -> Filenames<Self>{
- Filenames{
- handle: self.handle.child_directories(),
- phantom: PhantomData
+impl<'d> Directory<'d> {
+ pub fn from_ptr<O: Into<Phantomcow<'d, Database>>>(
+ ptr: *mut ffi::notmuch_directory_t,
+ owner: O,
+ ) -> Directory<'d> {
+ Directory {
+ handle: DirectoryPtr { ptr },
+ marker: owner.into(),
}
}
-}
-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
- }
+ pub fn child_directories(&self) -> Filenames<Self> {
+ Filenames::from_ptr(
+ unsafe { ffi::notmuch_directory_get_child_directories(self.handle.ptr) },
+ self,
+ )
}
}
-unsafe impl<'d> Send for Directory<'d>{}
-unsafe impl<'d> Sync for Directory<'d>{}
+unsafe impl<'d> Send for Directory<'d> {}
+unsafe impl<'d> Sync for Directory<'d> {}
diff --git a/src/error.rs b/src/error.rs
index 6434ee3..6de4236 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,10 +1,5 @@
use std;
-use std::{
- error,
- fmt,
- io,
- result,
-};
+use std::{error, fmt, io, result};
use ffi;
@@ -36,7 +31,7 @@ impl std::error::Error for Error {
match *self {
Error::IoError(ref e) => Some(e),
Error::NotmuchError(ref e) => Some(e),
- Error::UnspecifiedError => None
+ Error::UnspecifiedError => None,
}
}
}
diff --git a/src/filenames.rs b/src/filenames.rs
index 5083742..ae90280 100644
--- a/src/filenames.rs
+++ b/src/filenames.rs
@@ -1,45 +1,43 @@
-use std::ops::Drop;
+use std::ffi::CStr;
use std::iter::Iterator;
-use std::marker::PhantomData;
+use std::ops::Drop;
use std::path::PathBuf;
-use std::ffi::CStr;
-use utils::FromPtr;
-use Database;
+use supercow::Phantomcow;
+
use ffi;
-pub trait FilenamesOwner{}
+pub trait FilenamesOwner {}
#[derive(Debug)]
pub(crate) struct FilenamesPtr {
- pub ptr: *mut ffi::notmuch_filenames_t
+ pub ptr: *mut ffi::notmuch_filenames_t,
}
impl Drop for FilenamesPtr {
fn drop(self: &mut Self) {
- let valid = unsafe {
- ffi::notmuch_filenames_valid(self.ptr)
- };
+ let valid = unsafe { ffi::notmuch_filenames_valid(self.ptr) };
if valid != 0 {
- unsafe {
- ffi::notmuch_filenames_destroy(self.ptr)
- };
+ unsafe { ffi::notmuch_filenames_destroy(self.ptr) };
}
}
}
-
+
#[derive(Debug)]
-pub struct Filenames<'o, Owner: FilenamesOwner + 'o>{
+pub struct Filenames<'o, Owner: FilenamesOwner + 'o> {
pub(crate) handle: FilenamesPtr,
- pub(crate) phantom: PhantomData<&'o Owner>
+ pub(crate) marker: Phantomcow<'o, Owner>,
}
-impl<'o, Owner: FilenamesOwner + 'o> FromPtr<*mut ffi::notmuch_filenames_t> for Filenames<'o, Owner> {
- fn from_ptr(ptr: *mut ffi::notmuch_filenames_t) -> Filenames<'o, Owner> {
- Filenames{
- handle: FilenamesPtr{ptr},
- phantom: PhantomData
+impl<'o, Owner: FilenamesOwner + 'o> Filenames<'o, Owner> {
+ pub fn from_ptr<O: Into<Phantomcow<'o, Owner>>>(
+ ptr: *mut ffi::notmuch_filenames_t,
+ owner: O,
+ ) -> Filenames<'o, Owner> {
+ Filenames {
+ handle: FilenamesPtr { ptr },
+ marker: owner.into(),
}
}
}
@@ -48,13 +46,10 @@ impl<'o, Owner: FilenamesOwner + 'o> Iterator for Filenames<'o, Owner> {
type Item = PathBuf;
fn next(self: &mut Self) -> Option<Self::Item> {
+ let valid = unsafe { ffi::notmuch_filenames_valid(self.handle.ptr) };
- let valid = unsafe {
- ffi::notmuch_filenames_valid(self.handle.ptr)
- };
-
- if valid == 0{
- return None
+ if valid == 0 {
+ return None;
}
let ctag = unsafe {
@@ -67,5 +62,5 @@ impl<'o, Owner: FilenamesOwner + 'o> Iterator for Filenames<'o, Owner> {
}
}
-unsafe impl<'o, Owner: FilenamesOwner + 'o> Send for Filenames<'o, Owner>{}
-unsafe impl<'o, Owner: FilenamesOwner + 'o> Sync for Filenames<'o, Owner>{}
+unsafe impl<'o, Owner: FilenamesOwner + 'o> Send for Filenames<'o, Owner> {}
+unsafe impl<'o, Owner: FilenamesOwner + 'o> Sync for Filenames<'o, Owner> {}
diff --git a/src/lib.rs b/src/lib.rs
index c8ab078..595088d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,34 +1,36 @@
-#![cfg_attr(feature="clippy", feature(plugin))]
-#![cfg_attr(feature="clippy", plugin(clippy))]
+#![cfg_attr(feature = "clippy", feature(plugin))]
+#![cfg_attr(feature = "clippy", plugin(clippy))]
#[macro_use]
mod macros;
extern crate libc;
+extern crate supercow;
-mod utils;
mod ffi;
+mod utils;
-mod error;
mod database;
mod directory;
-mod query;
-mod messages;
+mod error;
+mod filenames;
mod message;
+mod messages;
+mod query;
mod tags;
-mod threads;
mod thread;
-mod filenames;
+mod threads;
-pub use error::Error;
pub use database::Database;
pub use directory::Directory;
-pub use query::Query;
-pub use messages::{Messages, MessagesOwner};
+pub use error::Error;
+pub use filenames::{Filenames, FilenamesOwner};
pub use message::{Message, MessageOwner};
+pub use messages::{Messages, MessagesOwner};
+pub use query::Query;
pub use tags::{Tags, TagsOwner};
-pub use threads::{Threads, ThreadsOwner};
pub use thread::{Thread, ThreadOwner};
-pub use filenames::{Filenames, FilenamesOwner};
+pub use threads::{Threads, ThreadsOwner};
pub use ffi::{DatabaseMode, Sort};
+pub use utils::StreamingIterator;
diff --git a/src/message.rs b/src/message.rs
index af04cec..624817d 100644
--- a/src/message.rs
+++ b/src/message.rs
@@ -1,103 +1,92 @@
+use std::ffi::CString;
use std::ops::Drop;
-use std::marker::PhantomData;
use std::path::PathBuf;
-use std::ffi::CString;
+use supercow::Phantomcow;
use error::{Error, Result};
-
use ffi;
-use utils::{
- ToStr,
- FromPtr
-};
-use Query;
-use Messages;
+use utils::ToStr;
use Filenames;
+use FilenamesOwner;
+use Messages;
+use MessagesOwner;
use Tags;
-use messages::MessagesOwner;
-use filenames::FilenamesOwner;
-use tags::TagsOwner;
+use TagsOwner;
-pub trait MessageOwner{}
+pub trait MessageOwner {}
#[derive(Debug)]
pub(crate) struct MessagePtr {
- pub ptr: *mut ffi::notmuch_message_t
+ pub ptr: *mut ffi::notmuch_message_t,
}
impl Drop for MessagePtr {
fn drop(&mut self) {
- unsafe {
- ffi::notmuch_message_destroy(self.ptr)
- };
+ unsafe { ffi::notmuch_message_destroy(self.ptr) };
}
}
-
+
#[derive(Debug)]
-pub struct Message<'o, Owner: MessageOwner + 'o>{
+pub struct Message<'o, Owner: MessageOwner + 'o> {
pub(crate) handle: MessagePtr,
- phantom: PhantomData<&'o Owner>,
+ marker: Phantomcow<'o, Owner>,
}
-impl<'o, Owner: MessageOwner + 'o> MessagesOwner for Message<'o, Owner>{}
-impl<'o, Owner: MessageOwner + 'o> FilenamesOwner for Message<'o, Owner>{}
-impl<'o, Owner: MessageOwner + 'o> TagsOwner for Message<'o, Owner>{}
-
-
-impl<'o, Owner: MessageOwner + 'o> FromPtr<*mut ffi::notmuch_message_t> for Message<'o, Owner> {
- fn from_ptr(ptr: *mut ffi::notmuch_message_t) -> Message<'o, Owner> {
- Message{
- handle: MessagePtr{ptr},
- phantom: PhantomData
+impl<'o, Owner: MessageOwner + 'o> MessagesOwner for Message<'o, Owner> {}
+impl<'o, Owner: MessageOwner + 'o> FilenamesOwner for Message<'o, Owner> {}
+impl<'o, Owner: MessageOwner + 'o> TagsOwner for Message<'o, Owner> {}
+
+impl<'o, Owner: MessageOwner + 'o> Message<'o, Owner> {
+ pub fn from_ptr<O: Into<Phantomcow<'o, Owner>>>(
+ ptr: *mut ffi::notmuch_message_t,
+ owner: O,
+ ) -> Message<'o, Owner> {
+ Message {
+ handle: MessagePtr { ptr },
+ marker: owner.into(),
}
}
-}
-
-impl<'o, Owner: MessageOwner + 'o> Message<'o, Owner>{
- pub fn id(self: &Self) -> String{
- let mid = unsafe {
- ffi::notmuch_message_get_message_id(self.handle.ptr)
- };
+ pub fn id(self: &Self) -> String {
+ let mid = unsafe { 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.handle.ptr)
- };
+ pub fn thread_id(self: &Self) -> String {
+ let tid = unsafe { ffi::notmuch_message_get_thread_id(self.handle.ptr) };
tid.to_str().unwrap().to_string()
}
- pub fn replies(self: &Self) -> Messages<'o, Self>{
- Messages::from_ptr(unsafe {
- ffi::notmuch_message_get_replies(self.handle.ptr)
- })
+ pub fn replies<'s>(self: &'s Self) -> Messages<'s, Self> {
+ Messages::from_ptr(
+ unsafe { ffi::notmuch_message_get_replies(self.handle.ptr) },
+ self,
+ )
}
#[cfg(feature = "v0_26")]
- pub fn count_files(self: &Self) -> i32{
- unsafe {
- ffi::notmuch_message_count_files(self.handle.ptr)
- }
+ pub fn count_files(self: &Self) -> i32 {
+ unsafe { ffi::notmuch_message_count_files(self.handle.ptr) }
}
- pub fn filenames(self: &Self) -> Filenames<Self>{
- Filenames::from_ptr(unsafe {
- ffi::notmuch_message_get_filenames(self.handle.ptr)
- })
+ pub fn filenames(self: &Self) -> Filenames<Self> {
+ Filenames::from_ptr(
+ unsafe { ffi::notmuch_message_get_filenames(self.handle.ptr) },
+ self,
+ )
}
- pub fn filename(self: &Self) -> PathBuf{
- PathBuf::from(unsafe {
- ffi::notmuch_message_get_filename(self.handle.ptr)
- }.to_str().unwrap())
+ pub fn filename(self: &Self) -> PathBuf {
+ PathBuf::from(
+ unsafe { 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.handle.ptr,
- CString::new(name).unwrap().as_ptr())
+ ffi::notmuch_message_get_header(self.handle.ptr, CString::new(name).unwrap().as_ptr())
};
if ret.is_null() {
Err(Error::UnspecifiedError)
@@ -106,12 +95,13 @@ impl<'o, Owner: MessageOwner + 'o> Message<'o, Owner>{
}
}
- pub fn tags<'m>(self: &Self) -> Tags<'m, Self>{
- Tags::from_ptr(unsafe {
- ffi::notmuch_message_get_tags(self.handle.ptr)
- })
+ pub fn tags<'m>(&'m self) -> Tags<'m, Self> {
+ Tags::from_ptr(
+ unsafe { ffi::notmuch_message_get_tags(self.handle.ptr) },
+ self,
+ )
}
}
-unsafe impl<'o, Owner: MessageOwner + 'o> Send for Message<'o, Owner>{}
-unsafe impl<'o, Owner: MessageOwner + 'o> Sync for Message<'o, Owner>{}
+unsafe impl<'o, Owner: MessageOwner + 'o> Send for Message<'o, Owner> {}
+unsafe impl<'o, Owner: MessageOwner + 'o> Sync for Message<'o, Owner> {}
diff --git a/src/messages.rs b/src/messages.rs
index b0fd47d..08a9cf3 100644
--- a/src/messages.rs
+++ b/src/messages.rs
@@ -1,63 +1,55 @@
use std::ops::Drop;
-use std::iter::Iterator;
-use std::marker::PhantomData;
+
+use supercow::{Phantomcow, Supercow};
use ffi;
-use utils::{
- FromPtr,
-};
-use Query;
+use utils::StreamingIterator;
use Message;
+use MessageOwner;
use Tags;
-use message::MessageOwner;
-use tags::TagsOwner;
+use TagsOwner;
-pub trait MessagesOwner{
-}
+pub trait MessagesOwner {}
#[derive(Debug)]
-pub(crate) struct MessagesPtr {
- pub ptr: *mut ffi::notmuch_messages_t
+pub struct MessagesPtr {
+ pub ptr: *mut ffi::notmuch_messages_t,
}
impl Drop for MessagesPtr {
fn drop(self: &mut Self) {
- let valid = unsafe {
- ffi::notmuch_messages_valid(self.ptr)
- };
+ let valid = unsafe { ffi::notmuch_messages_valid(self.ptr) };
- if valid == 0{
+ if valid == 0 {
return;
}
- unsafe {
- ffi::notmuch_messages_destroy(self.ptr)
- };
+ unsafe { ffi::notmuch_messages_destroy(self.ptr) };
}
}
-
#[derive(Debug)]
-pub struct Messages<'o, Owner: MessagesOwner + 'o>{
+pub struct Messages<'o, Owner: MessagesOwner + 'o> {
pub(crate) handle: MessagesPtr,
- phantom: PhantomData<&'o Owner>,
+ marker: Phantomcow<'o, Owner>,
}
-impl<'o, Owner: MessagesOwner + 'o> FromPtr<*mut ffi::notmuch_messages_t> for Messages<'o, Owner> {
- fn from_ptr(ptr: *mut ffi::notmuch_messages_t) -> Messages<'o, Owner> {
- Messages{
- handle: MessagesPtr{ptr},
- phantom: PhantomData
+impl<'o, Owner: MessagesOwner + 'o> Messages<'o, Owner> {
+ pub fn from_ptr<O: Into<Phantomcow<'o, Owner>>>(
+ ptr: *mut ffi::notmuch_messages_t,
+ owner: O,
+ ) -> Messages<'o, Owner> {
+ Messages {
+ handle: MessagesPtr { ptr },
+ marker: owner.into(),
}
}
}
-impl<'o, Owner: MessagesOwner + 'o> MessageOwner for Messages<'o, Owner>{}
-impl<'o, Owner: MessagesOwner + 'o> TagsOwner for Messages<'o, Owner>{}
-
-
-impl<'o, Owner: MessagesOwner + 'o> Messages<'o, Owner>{
+impl<'o, Owner: MessagesOwner + 'o> MessageOwner for Messages<'o, Owner> {}
+impl<'o, Owner: MessagesOwner + 'o> TagsOwner for Messages<'o, Owner> {}
+impl<'o, Owner: MessagesOwner + 'o> Messages<'o, Owner> {
/**
* Return a list of tags from all messages.
*
@@ -71,26 +63,22 @@ impl<'o, Owner: MessagesOwner + 'o> Messages<'o, Owner>{
*
* The function returns NULL on error.
*/
- pub fn collect_tags<'m>(self: &'o Self) -> Tags<'m, Self>{
- Tags::from_ptr(unsafe {
- ffi::notmuch_messages_collect_tags(self.handle.ptr)
- })
+ pub fn collect_tags<'m>(self: &'o Self) -> Tags<'m, Self> {
+ Tags::from_ptr(
+ unsafe { ffi::notmuch_messages_collect_tags(self.handle.ptr) },
+ self,
+ )
}
}
+impl<'s, 'o: 's, Owner: MessagesOwner + 'o> StreamingIterator<'s, Message<'s, Self>>
+ for Messages<'o, Owner>
+{
+ fn next(&'s mut self) -> Option<Message<'s, Self>> {
+ let valid = unsafe { ffi::notmuch_messages_valid(self.handle.ptr) };
-
-impl<'o, Owner: MessagesOwner + 'o> Iterator for Messages<'o, Owner> {
- type Item = Message<'o, Self>;
-
- fn next(&mut self) -> Option<Self::Item> {
-
- let valid = unsafe {
- ffi::notmuch_messages_valid(self.handle.ptr)
- };
-
- if valid == 0{
- return None
+ if valid == 0 {
+ return None;
}
let cmsg = unsafe {
@@ -99,9 +87,9 @@ impl<'o, Owner: MessagesOwner + 'o> Iterator for Messages<'o, Owner> {
msg
};
- Some(Self::Item::from_ptr(cmsg))
+ Some(Message::from_ptr(cmsg, Supercow::borrowed(self)))
}
}
-unsafe impl<'o, Owner: MessagesOwner + 'o> Send for Messages<'o, Owner>{}
-unsafe impl<'o, Owner: MessagesOwner + 'o> Sync for Messages<'o, Owner>{}
+unsafe impl<'o, Owner: MessagesOwner + 'o> Send for Messages<'o, Owner> {}
+unsafe impl<'o, Owner: MessagesOwner + 'o> Sync for Messages<'o, Owner> {}
diff --git a/src/query.rs b/src/query.rs
index a95c9c2..a90a0fe 100644
--- a/src/query.rs
+++ b/src/query.rs
@@ -1,128 +1,95 @@
use std::ops::Drop;
use std::ptr;
-use std::marker::PhantomData;
+use supercow::Phantomcow;
use error::Result;
-
use ffi;
-use utils::FromPtr;
-
+use ffi::Sort;
use Database;
use Messages;
+use MessagesOwner;
use Threads;
-use ffi::Sort;
-use threads::ThreadsOwner;
-use messages::MessagesOwner;
+use ThreadsOwner;
#[derive(Debug)]
pub(crate) struct QueryPtr {
- pub ptr: *mut ffi::notmuch_query_t
+ pub ptr: *mut ffi::notmuch_query_t,
}
impl Drop for QueryPtr {
fn drop(&mut self) {
- unsafe {
- ffi::notmuch_query_destroy(self.ptr)
- };
+ unsafe { ffi::notmuch_query_destroy(self.ptr) };
}
}
#[derive(Debug)]
-pub struct Query<'d>{
+pub struct Query<'d> {
pub(crate) handle: QueryPtr,
- phantom: PhantomData<&'d Database>,
+ marker: Phantomcow<'d, Database>,
}
-impl<'d> ThreadsOwner for Query<'d>{}
-impl<'d> MessagesOwner for Query<'d>{}
-
+impl<'d> ThreadsOwner for Query<'d> {}
+impl<'d> MessagesOwner for Query<'d> {}
-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 from_ptr<O: Into<Phantomcow<'d, Database>>>(
+ ptr: *mut ffi::notmuch_query_t,
+ owner: O,
+ ) -> Query<'d> {
+ Query {
+ handle: QueryPtr { ptr },
+ marker: owner.into(),
}
}
-}
-impl<'d> Query<'d> {
pub fn create(db: &'d Database, query_string: &str) -> Result<Self> {
db.create_query(query_string)
}
/// Specify the sorting desired for this query.
- pub fn set_sort(self: &Self, sort: Sort)
- {
- unsafe {
- ffi::notmuch_query_set_sort(
- self.handle.ptr, sort.into(),
- )
- }
+ pub fn set_sort(self: &Self, sort: Sort) {
+ unsafe { ffi::notmuch_query_set_sort(self.handle.ptr, sort.into()) }
}
/// Return the sort specified for this query. See
/// `set_sort`.
- pub fn sort(self: &Self) -> Sort
- {
- unsafe {
- ffi::notmuch_query_get_sort(
- self.handle.ptr,
- )
- }.into()
+ pub fn sort(self: &Self) -> Sort {
+ unsafe { ffi::notmuch_query_get_sort(self.handle.ptr) }.into()
}
-
/// Filter messages according to the query and return
- pub fn search_messages<'q>(self: &'d Self) -> Result<Messages<'q, Self>>
- {
+ pub fn search_messages<'q>(self: &'d Self) -> Result<Messages<'q, Self>> {
let mut msgs = ptr::null_mut();
- try!(unsafe {
- ffi::notmuch_query_search_messages(
- self.handle.ptr, &mut msgs,
- )
- }.as_result());
+ try!(
+ unsafe { ffi::notmuch_query_search_messages(self.handle.ptr, &mut msgs,) }.as_result()
+ );
- Ok(Messages::from_ptr(msgs))
+ Ok(Messages::from_ptr(msgs, self))
}
- pub fn count_messages(self: &Self) -> Result<u32>
- {
+ pub fn count_messages(self: &Self) -> Result<u32> {
let mut cnt = 0;
- try!(unsafe {
- ffi::notmuch_query_count_messages(
- self.handle.ptr, &mut cnt,
- )
- }.as_result());
+ try!(unsafe { ffi::notmuch_query_count_messages(self.handle.ptr, &mut cnt,) }.as_result());
Ok(cnt)
}
- pub fn search_threads<'q>(self: &'d Self) -> Result<Threads<'q, Self>>
- {
+ pub fn search_threads<'q>(self: &'d Self) -> Result<Threads<'q, Self>> {
let mut thrds = ptr::null_mut();
- try!(unsafe {
- ffi::notmuch_query_search_threads(
- self.handle.ptr, &mut thrds,
- )
- }.as_result());
+ try!(
+ unsafe { ffi::notmuch_query_search_threads(self.handle.ptr, &mut thrds,) }.as_result()
+ );
- Ok(Threads::from_ptr(thrds))
+ Ok(Threads::from_ptr(thrds, self))
}
- pub fn count_threads(self: &Self) -> Result<u32>
- {
+ pub fn count_threads(self: &Self) -> Result<u32> {
let mut cnt = 0;
- try!(unsafe {
- ffi::notmuch_query_count_threads(
- self.handle.ptr, &mut cnt,
- )
- }.as_result());
+ try!(unsafe { ffi::notmuch_query_count_threads(self.handle.ptr, &mut cnt,) }.as_result());
Ok(cnt)
}
}
-
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 fa21ff7..187e26c 100644
--- a/src/tags.rs
+++ b/src/tags.rs
@@ -1,35 +1,39 @@
-use std::ops::Drop;
-use std::iter::Iterator;
-use std::marker::PhantomData;
use std::ffi::CStr;
+use std::iter::Iterator;
+use std::ops::Drop;
-use utils::{
- FromPtr,
-};
+use supercow::Phantomcow;
-use Database;
use ffi;
-pub trait TagsOwner{}
-
+pub trait TagsOwner {}
#[derive(Debug)]
-pub struct Tags<'o, Owner: TagsOwner + 'o>(
- *mut ffi::notmuch_tags_t,
- PhantomData<&'o Owner>,
-);
-
-impl<'o, Owner: TagsOwner + 'o> FromPtr<*mut ffi::notmuch_tags_t> for Tags<'o, Owner> {
- fn from_ptr(ptr: *mut ffi::notmuch_tags_t) -> Tags<'o, Owner> {
- Tags(ptr, PhantomData)
- }
+pub(crate) struct TagsPtr {
+ pub ptr: *mut ffi::notmuch_tags_t,
}
-impl<'o, Owner: TagsOwner + 'o> Drop for Tags<'o, Owner> {
+impl Drop for TagsPtr {
fn drop(&mut self) {
- unsafe {
- ffi::notmuch_tags_destroy(self.0)
- };
+ unsafe { ffi::notmuch_tags_destroy(self.ptr) };
+ }
+}
+
+#[derive(Debug)]
+pub struct Tags<'o, Owner: TagsOwner + 'o> {
+ handle: TagsPtr,
+ marker: Phantomcow<'o, Owner>,
+}
+
+impl<'o, Owner: TagsOwner + 'o> Tags<'o, Owner> {
+ pub fn from_ptr<O: Into<Phantomcow<'o, Owner>>>(
+ ptr: *mut ffi::notmuch_tags_t,
+ owner: O,
+ ) -> Tags<'o, Owner> {
+ Tags {
+ handle: TagsPtr { ptr },
+ marker: owner.into(),
+ }
}
}
@@ -37,18 +41,15 @@ impl<'o, Owner: TagsOwner + 'o> Iterator for Tags<'o, Owner> {
type Item = String;
fn next(&mut self) -> Option<Self::Item> {
+ let valid = unsafe { ffi::notmuch_tags_valid(self.handle.ptr) };
- let valid = unsafe {
- ffi::notmuch_tags_valid(self.0)
- };
-
- if valid == 0{
- return None
+ if valid == 0 {
+ return None;
}
let ctag = unsafe {
- let t = ffi::notmuch_tags_get(self.0);
- ffi::notmuch_tags_move_to_next(self.0);
+ let t = ffi::notmuch_tags_get(self.handle.ptr);
+ ffi::notmuch_tags_move_to_next(self.handle.ptr);
CStr::from_ptr(t)
};
@@ -57,5 +58,5 @@ impl<'o, Owner: TagsOwner + 'o> Iterator for Tags<'o, Owner> {
}
}
-unsafe impl<'o, Owner: TagsOwner + 'o> Send for Tags<'o, Owner>{}
-unsafe impl<'o, Owner: TagsOwner + 'o> Sync for Tags<'o, Owner>{}
+unsafe impl<'o, Owner: TagsOwner + 'o> Send for Tags<'o, Owner> {}
+unsafe impl<'o, Owner: TagsOwner + 'o> Sync for Tags<'o, Owner> {}
diff --git a/src/thread.rs b/src/thread.rs
index 55ed982..9a63c94 100644
--- a/src/thread.rs
+++ b/src/thread.rs
@@ -1,128 +1,110 @@
use std::ops::Drop;
-use std::marker::PhantomData;
+use supercow::Phantomcow;
+
use ffi;
-use utils::{
- FromPtr,
- ToStr
-};
-use Query;
+use utils::ToStr;
use Messages;
+use MessagesOwner;
use Tags;
-use messages::MessagesOwner;
-use tags::TagsOwner;
-
-pub trait ThreadOwner{}
+use TagsOwner;
+pub trait ThreadOwner {}
#[derive(Debug)]
pub(crate) struct ThreadPtr {
- pub ptr: *mut ffi::notmuch_thread_t
+ pub ptr: *mut ffi::notmuch_thread_t,
}
impl Drop for ThreadPtr {
fn drop(&mut self) {
- unsafe {
- ffi::notmuch_thread_destroy(self.ptr)
- };
+ unsafe { ffi::notmuch_thread_destroy(self.ptr) };
}
}
-
#[derive(Debug)]
-pub struct Thread<'o, Owner: ThreadOwner + 'o>{
+pub struct Thread<'o, Owner: ThreadOwner + 'o> {
pub(crate) handle: ThreadPtr,
- phantom: PhantomData<&'o Owner>,
+ marker: Phantomcow<'o, Owner>,
}
-impl<'o, Owner: ThreadOwner + 'o> MessagesOwner for Thread<'o, Owner>{}
-impl<'o, Owner: ThreadOwner + 'o> TagsOwner for Thread<'o, Owner>{}
-
-
-impl<'o, Owner: ThreadOwner + 'o> FromPtr<*mut ffi::notmuch_thread_t> for Thread<'o, Owner> {
- fn from_ptr(ptr: *mut ffi::notmuch_thread_t) -> Thread<'o, Owner> {
- Thread{
- handle: ThreadPtr{ptr},
- phantom: PhantomData
+impl<'o, Owner: ThreadOwner + 'o> MessagesOwner for Thread<'o, Owner> {}
+impl<'o, Owner: ThreadOwner + 'o> TagsOwner for Thread<'o, Owner> {}
+
+impl<'o, Owner: ThreadOwner + 'o> Thread<'o, Owner> {
+ pub fn from_ptr<O: Into<Phantomcow<'o, Owner>>>(
+ ptr: *mut ffi::notmuch_thread_t,
+ owner: O,
+ ) -> Thread<'o, Owner> {
+ Thread {
+ handle: ThreadPtr { ptr },
+ marker: owner.into(),
}
}
-}
-
-impl<'o, Owner: ThreadOwner + 'o> Thread<'o, Owner>{
- pub fn id(self: &Self) -> String{
- let tid = unsafe {
- ffi::notmuch_thread_get_thread_id(self.handle.ptr)
- };
+ pub fn id(self: &Self) -> String {
+ let tid = unsafe { ffi::notmuch_thread_get_thread_id(self.handle.ptr) };
tid.to_str().unwrap().to_string()
}
-
- pub fn total_messages(self: &Self) -> i32{
- unsafe {
- ffi::notmuch_thread_get_total_messages(self.handle.ptr)
- }
+ pub fn total_messages(self: &Self) -> i32 {
+ unsafe { 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.handle.ptr)
- }
+ pub fn total_files(self: &Self) -> i32 {
+ unsafe { ffi::notmuch_thread_get_total_files(self.handle.ptr) }
}
-
- pub fn toplevel_messages(self: &Self) -> Messages<Self>{
- Messages::from_ptr(unsafe {
- ffi::notmuch_thread_get_toplevel_messages(self.handle.ptr)
- })
+ pub fn toplevel_messages(self: &Self) -> Messages<Self> {
+ Messages::from_ptr(
+ unsafe { ffi::notmuch_thread_get_toplevel_messages(self.handle.ptr) },
+ self,
+ )
}
/// Get a `Messages` iterator for all messages in 'thread' in
/// oldest-first order.
- pub fn messages(self: &Self) -> Messages<Self>{
- Messages::from_ptr(unsafe {
- ffi::notmuch_thread_get_messages(self.handle.ptr)
- })
+ pub fn messages(self: &Self) -> Messages<Self> {
+ Messages::from_ptr(
+ unsafe { ffi::notmuch_thread_get_messages(self.handle.ptr) },
+ self,
+ )
}
-
- pub fn tags<'t>(self: &Self) -> Tags<'t, Self>{
- Tags::from_ptr(unsafe {
- ffi::notmuch_thread_get_tags(self.handle.ptr)
- })
+ pub fn tags<'t>(&'t self) -> Tags<'t, Self> {
+ Tags::from_ptr(
+ unsafe { ffi::notmuch_thread_get_tags(self.handle.ptr) },
+ self,
+ )
}
- pub fn subject(self: &Self) -> String{
- let sub = unsafe {
- ffi::notmuch_thread_get_subject(self.handle.ptr)
- };
+ pub fn subject(self: &Self) -> String {
+ let sub = unsafe { ffi::notmuch_thread_get_subject(self.handle.ptr) };
sub.to_str().unwrap().to_string()
}
- pub fn authors(self: &Self) -> Vec<String>{
- let athrs = unsafe {
- ffi::notmuch_thread_get_authors(self.handle.ptr)
- };
+ pub fn authors(self: &Self) -> Vec<String> {
+ let athrs = unsafe { ffi::notmuch_thread_get_authors(self.handle.ptr) };
- athrs.to_str().unwrap().split(',').map(|s| s.to_string()).collect()
+ athrs
+ .to_str()
+ .unwrap()
+ .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.handle.ptr)
- }
+ unsafe { 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.handle.ptr)
- }
+ unsafe { ffi::notmuch_thread_get_newest_date(self.handle.ptr) }
}
}
-
unsafe impl<'o, Owner: ThreadOwner + 'o> Send for Thread<'o, Owner> {}
unsafe impl<'o, Owner: ThreadOwner + 'o> Sync for Thread<'o, Owner> {}
diff --git a/src/threads.rs b/src/threads.rs
index a2edef8..359569e 100644
--- a/src/threads.rs
+++ b/src/threads.rs
@@ -1,57 +1,52 @@
use std::ops::Drop;
-use std::iter::Iterator;
-use std::marker::PhantomData;
-use utils::FromPtr;
-use Query;
-use Thread;
+use supercow::{Phantomcow, Supercow};
+use utils::StreamingIterator;
+
use ffi;
use thread::ThreadOwner;
+use Thread;
-pub trait ThreadsOwner{}
-
+pub trait ThreadsOwner {}
#[derive(Debug)]
pub(crate) struct ThreadsPtr {
- pub ptr: *mut ffi::notmuch_threads_t
+ pub ptr: *mut ffi::notmuch_threads_t,
}
impl Drop for ThreadsPtr {
fn drop(&mut self) {
- unsafe {
- ffi::notmuch_threads_destroy(self.ptr)
- };
+ unsafe { ffi::notmuch_threads_destroy(self.ptr) };
}
}
#[derive(Debug)]
-pub struct Threads<'o, Owner: ThreadsOwner + 'o>{
+pub struct Threads<'o, Owner: ThreadsOwner + 'o> {
handle: ThreadsPtr,
- phantom: PhantomData<&'o Owner>,
+ marker: Phantomcow<'o, Owner>,
}
-impl<'o, Owner: ThreadsOwner + 'o> ThreadOwner for Threads<'o, Owner>{}
+impl<'o, Owner: ThreadsOwner + 'o> ThreadOwner for Threads<'o, Owner> {}
-
-impl<'o, Owner: ThreadsOwner + 'o> FromPtr<*mut ffi::notmuch_threads_t> for Threads<'o, Owner> {
- fn from_ptr(ptr: *mut ffi::notmuch_threads_t) -> Threads<'o, Owner> {
- Threads{
- handle: ThreadsPtr{ptr},
- phantom: PhantomData
+impl<'o, Owner: ThreadsOwner + 'o> Threads<'o, Owner> {
+ pub fn from_ptr<O: Into<Phantomcow<'o, Owner>>>(
+ ptr: *mut ffi::notmuch_threads_t,
+ owner: O,
+ ) -> Threads<'o, Owner> {
+ Threads {
+ handle: ThreadsPtr { ptr },
+ marker: owner.into(),
}
}
}
-impl<'o, Owner: ThreadsOwner + 'o> Iterator for Threads<'o, Owner> {
- type Item = Thread<'o, Self>;
-
- fn next(self: &mut Self) -> Option<Self::Item> {
-
- let valid = unsafe {
- ffi::notmuch_threads_valid(self.handle.ptr)
- };
+impl<'s, 'o: 's, Owner: ThreadsOwner + 'o> StreamingIterator<'s, Thread<'s, Self>>
+ for Threads<'o, Owner>
+{
+ fn next(&'s mut self) -> Option<Thread<'s, Self>> {
+ let valid = unsafe { ffi::notmuch_threads_valid(self.handle.ptr) };
- if valid == 0{
+ if valid == 0 {
return None;
}
@@ -61,7 +56,7 @@ impl<'o, Owner: ThreadsOwner + 'o> Iterator for Threads<'o, Owner> {
t
};
- Some(Self::Item::from_ptr(cthread))
+ Some(Thread::from_ptr(cthread, Supercow::borrowed(self)))
}
}
diff --git a/src/utils.rs b/src/utils.rs
index 5db8957..5cce04d 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -1,16 +1,5 @@
-use std::{
- ffi,
- str,
-};
use libc;
-
-pub trait FromPtr<T> {
- fn from_ptr(ptr: T) -> Self;
-}
-
-// pub trait NewFromPtr<T, P> {
-// fn new(ptr: T, parent: Rc<P>) -> Self;
-// }
+use std::{ffi, str};
pub trait ToStr {
fn to_str<'a>(&self) -> Result<&'a str, str::Utf8Error>;
@@ -18,9 +7,7 @@ pub trait ToStr {
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())
+ str::from_utf8(unsafe { ffi::CStr::from_ptr(*self) }.to_bytes())
}
}
@@ -30,13 +17,13 @@ pub trait ToString {
impl ToString for *const libc::c_char {
fn to_string(&self) -> String {
- unsafe {
- ffi::CStr::from_ptr(*self).to_string_lossy().into_owned()
- }
+ unsafe { ffi::CStr::from_ptr(*self).to_string_lossy().into_owned() }
}
}
-
-pub struct Owner;
-
-
+/// A streaming iterator, as found in https://github.com/emk/rust-streaming
+pub trait StreamingIterator<'a, T> {
+ /// Return either the next item in the sequence, or `None` if all items
+ /// have been consumed.
+ fn next(&'a mut self) -> Option<T>;
+}
diff --git a/tests/main.rs b/tests/main.rs
index 6840dc0..d790e21 100644
--- a/tests/main.rs
+++ b/tests/main.rs
@@ -1,6 +1,8 @@
extern crate notmuch;
extern crate dirs;
+use notmuch::StreamingIterator;
+
fn main() {
let mut mail_path = dirs::home_dir().unwrap();
@@ -18,15 +20,11 @@ fn main() {
let query = db.create_query(&"".to_string()).unwrap();
let mut threads = query.search_threads().unwrap();
- loop {
- match threads.next() {
- Some(thread) => {
- println!("thread {:?} {:?}", thread.subject(), thread.authors());
- },
- None => { break }
- }
+ while let Some(thread) = threads.next() {
+ println!("thread {:?} {:?}", thread.subject(), thread.authors());
}
+
},
Err(err) =>{
println!("Got error while trying to open db: {:?}", err);