1use std::panic::{catch_unwind, resume_unwind, UnwindSafe};
2
3use crate::config::Config;
4use lettre::{transport::smtp::authentication::Credentials, Message, SmtpTransport, Transport};
5
6pub struct EmailNotifier {
9 config: Config,
10 tag: String,
11}
12
13impl EmailNotifier {
14 pub fn new(tag: impl ToString) -> Self {
25 EmailNotifier {
26 config: Config::load(),
27 tag: tag.to_string(),
28 }
29 }
30
31 fn send_email(&self, subject: String, body: String) {
34 let email = Message::builder()
35 .from(self.config.sender_email.parse().unwrap())
36 .to(self.config.recipient_email.parse().unwrap())
37 .subject(subject)
38 .body(body)
39 .unwrap();
40
41 let creds = Credentials::new(
42 self.config.sender_email.clone(),
43 self.config.password.clone(),
44 );
45 let mailer = SmtpTransport::relay(&self.config.smtp_server)
46 .unwrap()
47 .credentials(creds)
48 .build();
49
50 match mailer.send(&email) {
51 Ok(_) => (),
52 Err(e) => panic!("Could not send email: {:?}", e),
53 }
54 }
55
56 pub fn send_update(&self, body: String) {
58 self.send_email(format!("{} Update", self.tag), body);
59 }
60
61 pub fn send_success(&self) {
63 self.send_email(
64 format!("{} Complete", self.tag),
65 format!("{} has completed successfully.", self.tag),
66 );
67 }
68
69 pub fn send_error(&self) {
71 self.send_email(
72 format!("{} Error!", self.tag),
73 format!("{} has encountered a error and has panicked.", self.tag),
74 );
75 }
76
77 pub fn capture<F>(self, f: F)
93 where
94 F: UnwindSafe + FnOnce(&EmailNotifier) -> (),
95 {
96 match catch_unwind(|| {
97 f(&self);
98 }) {
99 Ok(_) => self.send_success(),
100 Err(e) => {
101 self.send_error();
102 resume_unwind(e);
103 }
104 };
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 #[test]
113 fn test_send_mail() {
114 let em = EmailNotifier::new("Test1");
115 em.send_email("Test".to_string(), "<b>test</b>".to_string());
116 }
117
118 #[test]
119 fn test_capture() {
120 EmailNotifier::new("Test2").capture(|_| {});
121 }
122
123 #[test]
124 #[should_panic]
125 fn test_capture_error() {
126 EmailNotifier::new("Test3").capture(|_| panic!("foo"));
127 }
128}