rss2email_lib/email/
mail_cmd.rs

1//! Implementation for default `mail` command in linux.
2
3use super::{email_provider::EmailProvider, error::EmailError};
4
5#[derive(Default, Debug, Clone, Copy)]
6pub struct MailCommand {}
7
8impl EmailProvider for MailCommand {
9  fn send_email(
10    &self,
11    from_address: &str,
12    recipient_addresses: Vec<&str>,
13    subject: &str,
14    contents: &str,
15  ) -> Result<(), EmailError> {
16    send_email(from_address, &recipient_addresses, subject, contents)
17  }
18}
19
20#[cfg(not(target_os = "windows"))]
21fn send_email(
22  from_address: &str,
23  recipient_addresses: &[&str],
24  subject: &str,
25  contents: &str,
26) -> Result<(), EmailError> {
27  use crate::info;
28  use std::{fs::File, io::Write, process::Command};
29
30  const TEMPORARY_FILE_NAME: &str = "/tmp/rss2-email.txt";
31
32  let mut file = File::create(TEMPORARY_FILE_NAME).expect("Can't create temporary file");
33  file
34    .write_all(contents.as_bytes())
35    .map_err(|_e| EmailError::Io("Failed to write temporary email file".to_owned()))?;
36
37  let recipients = recipient_addresses.join(",");
38  let mail_command =
39    format!("mail -s \"{subject}\" \"{recipients}\" -aFrom:{from_address} < {TEMPORARY_FILE_NAME}");
40
41  let mut mail_sender = Command::new("sh")
42    .args(["-c", &mail_command])
43    .spawn()
44    .map_err(|_e| {
45      EmailError::Other("Could not start mail command, is it installed and configured?".to_owned())
46    })?;
47
48  let exit_status = mail_sender.wait().expect("Mail command failed");
49  info!("Mail command finished with status {exit_status}");
50
51  match std::fs::remove_file(TEMPORARY_FILE_NAME) {
52    Ok(()) => Ok(()),
53    Err(e) => Err(EmailError::Io(format!(
54      "Unable to delete {TEMPORARY_FILE_NAME} for error: {e}"
55    ))),
56  }
57}
58
59#[cfg(target_os = "windows")]
60fn send_email(
61  _from_address: &str,
62  _recipient_addresses: &[&str],
63  _subject: &str,
64  _contents: &str,
65) -> Result<(), EmailError> {
66  Err(EmailError::Config(
67    "No known mail/sendmail/smtp command for Windows OS".to_owned(),
68  ))
69}