doco comments and various stuff

Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
embed
Manos Pitsidianakis 2017-09-16 13:32:56 +03:00
parent 2279476a2f
commit 655b5a6ea7
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
6 changed files with 71 additions and 7 deletions

View File

@ -22,6 +22,7 @@ memmap = "*"
base64 = "*"
crossbeam = "^0.3.0"
fnv = "1.0.3"
encoding = "0.2.33"
[dependencies.ncurses]
features = ["wide"]

View File

@ -31,3 +31,4 @@ extern crate nom;
extern crate chrono;
extern crate base64;
extern crate memmap;
extern crate encoding;

View File

@ -30,8 +30,42 @@ pub trait MailBackend {
}
/* A BackendOp manages common operations for the various mail backends. They should be created when
* needed */
/// A BackendOp manages common operations for the various mail backends. They only live for the
/// duration of the operation. They are generated by BackendOpGenerator on demand.
///
/// # Motivation
///
/// We need a way to do various operations on individual mails regardless of what backend they come
/// from (eg local or imap).
///
/// # Example
/// ```
/// use melib::mailbox::backends::{BackendOp, BackendOpGenerator};
/// use melib::error::Result;
///
/// #[derive(Debug)]
/// struct FooOp {}
///
/// impl BackendOp for FooOp {
/// fn description(&self) -> String {
/// "Foobar".to_string()
/// }
/// fn as_bytes(&mut self) -> Result<&[u8]> {
/// unimplemented!()
/// }
/// fn fetch_headers(&mut self) -> Result<&[u8]> {
/// unimplemented!()
/// }
/// fn fetch_body(&mut self) -> Result<&[u8]> {
/// unimplemented!()
/// }
/// }
///
/// let foogen = BackendOpGenerator::new(Box::new(|| Box::new(FooOp {})));
/// let operation = foogen.generate();
/// assert_eq!("Foobar", &operation.description());
///
/// ```
pub trait BackendOp: ::std::fmt::Debug + ::std::marker::Send {
fn description(&self) -> String;
fn as_bytes(&mut self) -> Result<&[u8]>;
@ -41,7 +75,11 @@ pub trait BackendOp: ::std::fmt::Debug + ::std::marker::Send {
fn fetch_body(&mut self) -> Result<&[u8]>;
}
/* BackendOpGenerator is a wrapper for a closure that returns a BackendOp object */
/// BackendOpGenerator is a wrapper for a closure that returns a BackendOp object
/// See BackendOp for details.
/*
* I know this sucks, but that's the best way I found that rustc deems safe.
* */
pub struct BackendOpGenerator(Box<Fn() -> Box<BackendOp>>);
impl BackendOpGenerator {
pub fn new(b: Box<Fn() -> Box<BackendOp>>) -> Self {
@ -55,7 +93,8 @@ unsafe impl Send for BackendOpGenerator {}
unsafe impl Sync for BackendOpGenerator {}
impl fmt::Debug for BackendOpGenerator {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "BackendOpGenerator")
let op = self.generate();
write!(f, "BackendOpGenerator: {}", op.description())
}
}

View File

@ -91,6 +91,8 @@ pub enum ContentTransferEncoding {
Other { tag: String },
}
/// TODO: Add example.
///
pub struct AttachmentBuilder {
content_type: (ContentType, ContentSubType),
content_transfer_encoding: ContentTransferEncoding,
@ -156,7 +158,12 @@ self
ContentTransferEncoding::Base64 => {
match ::base64::decode(&::std::str::from_utf8(&self.raw).unwrap().trim().lines().fold(String::with_capacity(self.raw.len()), |mut acc, x| { acc.push_str(x); acc })) {
Ok( ref v ) => {
String::from_utf8_lossy(v).into_owned()
let s = String::from_utf8_lossy(v);
if s.find("\r\n").is_some() {
s.replace("\r\n","\n")
} else {
s.into_owned()
}
},
_ => {
String::from_utf8_lossy(&self.raw).into_owned()

View File

@ -231,8 +231,16 @@ impl Mail
let new_ref = MessageID::new(new_val, slice);
match self.references {
Some(ref mut s) => {
if s.refs.contains(&new_ref) {
return;
if s.refs.contains(&new_ref) {
if s.refs[s.refs.len() - 1] != new_ref {
if let Some(index) = s.refs.iter().position(|ref x| **x == new_ref) {
s.refs.remove(index);
} else {
panic!();
}
} else {
return;
}
}
s.refs.push(new_ref);
},

View File

@ -183,7 +183,12 @@ fn build_collection(threads: &mut Vec<Thread>, id_table: &mut FnvHashMap<std::st
* Do not add a link if adding that link would introduce a loop: that is, before asserting A->B, search down the children of B to see if A is reachable, and also search down the children of A to see if B is reachable. If either is already reachable as a child of the other, don't add the link.
*/
let mut curr_ref = x_index;
let mut iasf = 0;
for &r in x.get_references().iter().rev() {
if iasf == 1 {
continue;
}
iasf += 1;
let parent_id =
if id_table.contains_key(r.get_raw()) {
let p = id_table[r.get_raw()];
@ -216,6 +221,9 @@ fn build_collection(threads: &mut Vec<Thread>, id_table: &mut FnvHashMap<std::st
indentation: 0,
show_subject: true,
});
if threads[curr_ref].parent.is_none() {
threads[curr_ref].parent = Some(idx);
}
id_table.insert(r.get_raw().to_string(), idx);
idx
};