use std::ops::Deref; use std::path::PathBuf; use std::iter::FromIterator; use anyhow::Result; use maildir::Maildir; use maildir::MailEntry; use mailparse::ParsedMail; pub struct MailStore { new: Vec, cur: Vec, } impl MailStore { pub fn build_from_path(path: PathBuf) -> MailStoreBuilder { let md = Maildir::from(path); MailStoreBuilder { cur: Box::new(md.list_cur().map(|m| Mail::cur_from(m?))), new: Box::new(md.list_new().map(|m| Mail::new_from(m?))), } } pub fn new_mail(&self) -> &Vec { &self.new } pub fn cur_mail(&self) -> &Vec { &self.cur } } impl FromIterator for MailStore { fn from_iter(iter: T) -> Self where T: IntoIterator { let mut new = vec![]; let mut cur = vec![]; for mail in iter { if mail.is_new() { new.push(mail) } else if mail.is_cur() { cur.push(mail) } else { unreachable!("Not implemented yet, should not be reachable in current implementation") } } MailStore { new, cur } } } pub struct MailStoreBuilder { cur: Box>>, new: Box>>, } impl Iterator for MailStoreBuilder { type Item = Result; fn next(&mut self) -> Option { if let Some(next) = self.cur.next() { return Some(next) } self.new.next() } } #[derive(Clone, Debug)] pub struct Mail { entry: MailEntry, parsed: ParsedMail, mailtype: MailType, } #[derive(Debug, Clone, Eq, PartialEq)] enum MailType { Cur, New, } impl Mail { fn cur_from(mut entry: MailEntry) -> Result { Ok(Mail { parsed: entry.parsed()?, entry, mailtype: MailType::Cur, }) } fn new_from(mut entry: MailEntry) -> Result { Ok(Mail { parsed: entry.parsed()?, entry, mailtype: MailType::New, }) } pub fn parsed(&self) -> &ParsedMail { &self.parsed } pub fn is_new(&self) -> bool { self.mailtype == MailType::New } pub fn is_cur(&self) -> bool { self.mailtype == MailType::Cur } } impl Deref for Mail { type Target = MailEntry; fn deref(&self) -> &Self::Target { &self.entry } }