use std::io::ErrorKind as IOErrKind; use std::path::PathBuf; use maildir::Maildir; use serde::Serialize as _; use serde::Serializer as _; mod count; mod folders; mod list; mod raw; use crate::error::Result; use crate::rfc822::{MIMEHeader, Mail, TopMailHeader}; pub use count::{count, CountInfo}; pub use folders::folders; pub use list::list; pub use raw::raw; pub enum Return { Read(Mail), Raw(MIMEHeader, Vec), List(Vec), Folders(Vec), Count(CountInfo), Search(Vec), Move, } pub fn serialize_to(res: Result, mut write: W) -> std::io::Result<()> where W: std::io::Write + Copy, { let ser = &mut serde_json::Serializer::new(write); match res { Err(e) => { e.serialize(ser)?; std::process::exit(3) } Ok(r) => { match r { Return::Folders(fs) => fs.serialize(ser), Return::Count(ci) => ci.serialize(ser), Return::List(tmhs) => tmhs.serialize(ser), Return::Search(ms) => ms.serialize(ser), Return::Read(m) => m.serialize(ser), Return::Raw(mh, b) => { let r = match mh.serialize(ser) { Ok(x) => x, Err(e) => return Err(e.into()), }; write.write_all(b"\n")?; write.write_all(&b)?; Ok(r) } Return::Move => ser.serialize_unit(), }?; Ok(()) } } } pub fn open_submaildir(mut path: PathBuf, sub: &str) -> Maildir { if sub != "" { path.push(String::from(".") + sub); } Maildir::from(path) } pub fn read(md: &Maildir, mid: &str) -> Result { md.add_flags(mid, "S")?; let mut mail = md.find(mid).ok_or_else(|| { std::io::Error::new(IOErrKind::NotFound, format!("mail {} not found", mid)) })?; Ok(mail.parsed()?.try_into()?) } pub fn move_mail(p: PathBuf, mid: &str, from_f: &str, to_f: &str) -> Result<()> { let from = open_submaildir(p.clone(), from_f); let to = open_submaildir(p, to_f); from.move_to(mid, &to).map_err(|e| e.into()) } pub fn search(_md: &Maildir, _pattern: &str) -> Result> { todo!() }