esm 0.1.4

easy send email with two steps
Documentation
//!
//! "esm" is a crate base on lettre,it can send email with anycontent easily
use lettre::message::header::ContentType;
use lettre::message::Attachment;

use lettre::message::MultiPart;
use lettre::message::SinglePart;
use lettre::transport::smtp::authentication::Credentials;
use lettre::transport::smtp::Error;
use lettre::{Message, SmtpTransport, Transport};

///a mail sender can produce transmitter and send_email
///
/// #Example
///
/// ```
/// //send with string
/// let rt = tokio::runtime::Runtime::new().unwrap();
/// rt.block_on(async {
/// //MailerSender params
/// //from:senderAccoun
/// //smtp_site:use which website to send email
/// //password:senderPassword(it can be origin password)
///     let mailer = MailerSender {
///         from: "<sender@qq.com>".to_string(),
///         password: "<senderPassword>".to_string(),
///        smtp_site: "smtp.qq.com".to_string(),
///     };
/// //send_mail params
/// //send_email(&self,reciever,email_topic,content(it can be string and html),attachment_name,attachment_path)
/// //if dont send attachment,attachment_name and attachment_path fill None
///     let _send_result = MailerSender::send_email(
///         &mailer,
///         "1984850802@qq.com".to_string(),
///         "hell".to_string(),
///         "hello,surprise".to_string(),
///         None,
///         None,
///     )
///     .await;
/// });
///
/// ```
///
///
/// #Example
///
/// ```
/// //send with html
/// let rt = tokio::runtime::Runtime::new().unwrap();
/// rt.block_on(async {
///     let mailer = MailerSender {
///         from: "<sender@qq.com>".to_string(),
///         password: "<senderPassword>".to_string(),
///        smtp_site: "smtp.qq.com".to_string(),
///     };
///     let _send_result = MailerSender::send_email(
///         &mailer,
///         "1984850802@qq.com".to_string(),
///         "hell".to_string(),
///         "<h1 style='color:red'>hello,surprisess</h1>".to_string(),
///         None,
///         None,
///     )
///     .await;
/// });
///
/// ```
///
///
/// #Example
///
/// ```
/// //send content and  attachment
///let rt = tokio::runtime::Runtime::new().unwrap();
///rt.block_on(async {
///    let mailer = MailerSender {
///        from: "1984850802@qq.com".to_string(),
///        password: "sfckoixahcpodcbb".to_string(),
///        smtp_site: "smtp.qq.com".to_string(),
///    };
///    let _send_result = MailerSender::send_email(
///        &mailer,
///        "3502728398@qq.com".to_string(),
///        "邮件".to_string(),
///        "<h1 style='color:red'>hello,surprise</h1>".to_string(),
///        Some("1.pdf".to_string()),
///        Some("resume.pdf".to_string()),
///    )
///    .await;
///});
///
/// ```
pub struct MailerSender {
    pub from: String,
    pub password: String,
    pub smtp_site: String,
}
// new的方法接收剩余的三个参数,创建对象实例,send_email,两个函数 new,send_email,可以多态(string,html,files)
impl MailerSender {
    pub fn new(&self) -> SmtpTransport {
        let creds = Credentials::new(self.from.clone(), self.password.clone());
        SmtpTransport::relay(self.smtp_site.as_str())
            .unwrap()
            .credentials(creds)
            .build()
    }
    pub async fn send_email(
        &self,
        to: String,
        topic: String,
        content: String,
        filename: Option<String>,
        filepath: Option<String>,
    ) -> Result<bool, Error> {
        // let file_path = "../../files/resume.pdf";
        let filebody;
        let content_type;
        let mut attachment: Option<SinglePart> = None;
        let message;
        //判断需不需要传附件
        if let Some(_) = filename {
            filebody = std::fs::read(filepath.unwrap()).unwrap();
            content_type = ContentType::parse("application/pdf").unwrap();
            attachment = Some(Attachment::new(filename.unwrap()).body(filebody, content_type));
        }
        match attachment {
            Some(v) => {
                message = Message::builder()
                    .from(self.from.parse().unwrap())
                    .to(to.parse().unwrap())
                    .subject(topic)
                    .header(ContentType::TEXT_PLAIN)
                    .multipart(
                        MultiPart::mixed()
                            .singlepart(v)
                            .singlepart(SinglePart::plain(content.to_string())), //测试一下
                    )
                    .unwrap();

                match self.new().send(&message) {
                    Ok(_) => Ok(true),
                    Err(e) => Err(e),
                }
            }
            None => {
                message = Message::builder()
                    .from(self.from.parse().unwrap())
                    .to(to.parse().unwrap())
                    .subject(topic)
                    .header(ContentType::TEXT_PLAIN)
                    .multipart(
                        MultiPart::mixed().singlepart(SinglePart::plain(content.to_string())), //测试一下
                    )
                    .unwrap();

                match self.new().send(&message) {
                    Ok(_) => Ok(true),
                    Err(e) => Err(e),
                }
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::MailerSender;
    // 测试不带附件
    #[test]
    fn test_send_plain_attachment_email() {
        let rt = tokio::runtime::Runtime::new().unwrap();
        rt.block_on(async {
            let mailer = MailerSender {
                from: "1984850802@qq.com".to_string(),
                password: "sfckoixahcpodcbb".to_string(),
                smtp_site: "smtp.qq.com".to_string(),
            };
            let _send_result = MailerSender::send_email(
                &mailer,
                "1984850802@qq.com".to_string(),
                "hell".to_string(),
                "hello,surprise".to_string(),
                None,
                None,
            )
            .await;
        });
    }
    // 测试内容发送Html
    #[test]
    fn test_send_html_email() {
        let rt = tokio::runtime::Runtime::new().unwrap();
        rt.block_on(async {
            let mailer = MailerSender {
                from: "1984850802@qq.com".to_string(),
                password: "sfckoixahcpodcbb".to_string(),
                smtp_site: "smtp.qq.com".to_string(),
            };
            let _send_result = MailerSender::send_email(
                &mailer,
                "1984850802@qq.com".to_string(),
                "hell".to_string(),
                "<h1 style='color:red'>hello,surprisess</h1>".to_string(),
                None,
                None,
            )
            .await;
        });
    }

    //测试发送带附件
    #[test]
    fn send_plain_files_email() {
        let rt = tokio::runtime::Runtime::new().unwrap();
        rt.block_on(async {
            let mailer = MailerSender {
                from: "1984850802@qq.com".to_string(),
                password: "sfckoixahcpodcbb".to_string(),
                smtp_site: "smtp.qq.com".to_string(),
            };
            let _send_result = MailerSender::send_email(
                &mailer,
                "3502728398@qq.com".to_string(),
                "邮件".to_string(),
                "<h1 style='color:red'>hello,surprise</h1>".to_string(),
                Some("1.pdf".to_string()),
                Some("resume.pdf".to_string()),
            )
            .await;
        });
    }
}