use anyhow::Result;
use atty::Stream;
use imap::types::Flag;
use std::{
convert::{TryFrom, TryInto},
io::{self, BufRead},
};
use crate::{
config::Account,
domain::{
imap::ImapServiceInterface,
msg::{Msg, TplOverride},
Flags, Mbox, SmtpServiceInterface,
},
output::PrinterService,
};
pub fn new<'a, Printer: PrinterService>(
opts: TplOverride<'a>,
account: &'a Account,
printer: &'a mut Printer,
) -> Result<()> {
let tpl = Msg::default().to_tpl(opts, account);
printer.print(tpl)
}
pub fn reply<'a, Printer: PrinterService, ImapService: ImapServiceInterface<'a>>(
seq: &str,
all: bool,
opts: TplOverride<'a>,
account: &'a Account,
printer: &'a mut Printer,
imap: &'a mut ImapService,
) -> Result<()> {
let tpl = imap
.find_msg(seq)?
.into_reply(all, account)?
.to_tpl(opts, account);
printer.print(tpl)
}
pub fn forward<'a, Printer: PrinterService, ImapService: ImapServiceInterface<'a>>(
seq: &str,
opts: TplOverride<'a>,
account: &'a Account,
printer: &'a mut Printer,
imap: &'a mut ImapService,
) -> Result<()> {
let tpl = imap
.find_msg(seq)?
.into_forward(account)?
.to_tpl(opts, account);
printer.print(tpl)
}
pub fn save<'a, Printer: PrinterService, ImapService: ImapServiceInterface<'a>>(
mbox: &Mbox,
attachments_paths: Vec<&str>,
tpl: &str,
printer: &mut Printer,
imap: &mut ImapService,
) -> Result<()> {
let tpl = if atty::is(Stream::Stdin) || printer.is_json() {
tpl.replace("\r", "")
} else {
io::stdin()
.lock()
.lines()
.filter_map(Result::ok)
.collect::<Vec<String>>()
.join("\n")
};
let msg = Msg::from_tpl(&tpl)?.add_attachments(attachments_paths)?;
let raw_msg: Vec<u8> = TryInto::try_into(&msg)?;
let flags = Flags::try_from(vec![Flag::Seen])?;
imap.append_raw_msg_with_flags(mbox, &raw_msg, flags)?;
printer.print("Template successfully saved")
}
pub fn send<
'a,
Printer: PrinterService,
ImapService: ImapServiceInterface<'a>,
SmtpService: SmtpServiceInterface,
>(
mbox: &Mbox,
attachments_paths: Vec<&str>,
tpl: &str,
printer: &mut Printer,
imap: &mut ImapService,
smtp: &mut SmtpService,
) -> Result<()> {
let tpl = if atty::is(Stream::Stdin) || printer.is_json() {
tpl.replace("\r", "")
} else {
io::stdin()
.lock()
.lines()
.filter_map(Result::ok)
.collect::<Vec<String>>()
.join("\n")
};
let msg = Msg::from_tpl(&tpl)?.add_attachments(attachments_paths)?;
let sent_msg = smtp.send_msg(&msg)?;
let flags = Flags::try_from(vec![Flag::Seen])?;
imap.append_raw_msg_with_flags(mbox, &sent_msg.formatted(), flags)?;
printer.print("Template successfully sent")
}