use std::{
io::{BufWriter, Write},
process::{Command, Stdio},
};
#[derive(Clone, Copy, Debug)]
pub enum Status<'a> {
Finished,
Aborted,
Custom {
subject: &'a str,
message: &'a str,
},
}
pub fn notify(to: &[impl ToString], status: Status) -> std::io::Result<()> {
let (subject, message) = match status {
Status::Finished => (
"Completed",
"The decellularization run has completed as scheduled.",
),
Status::Aborted => (
"Aborted",
"The decellularization run has been aborted manually.",
),
Status::Custom { subject, message } => (subject, message),
};
mail(to, subject, message)
}
pub fn mail(
to: &[impl ToString],
subject: impl ToString,
message: impl ToString,
) -> std::io::Result<()> {
let mut child = Command::new("sendmail")
.arg("-t")
.stdin(Stdio::piped())
.spawn()?;
{
let mut buf = BufWriter::new(child.stdin.as_mut().unwrap());
writeln!(
&mut buf,
"\
Subject: {subject}
From: deoxy@hmltn.me",
subject = subject.to_string()
)?;
for recipient in to {
writeln!(&mut buf, "To: {}", recipient.to_string())?;
}
writeln!(&mut buf)?;
writeln!(&mut buf, "{}", message.to_string())?;
writeln!(&mut buf, ".")?;
}
let status = child.wait()?;
if status.success() {
Ok(())
} else {
Err(match status.code() {
None => {
std::io::Error::new(std::io::ErrorKind::Interrupted, "Email sending interrupted")
}
Some(_) => std::io::Error::new(std::io::ErrorKind::Other, status.to_string()),
})
}
}