From c9c82495ce350bcf144b52e0eab342ba0828eb7a Mon Sep 17 00:00:00 2001 From: Alexis Mousset Date: Thu, 31 May 2018 00:09:57 +0200 Subject: [PATCH] feat(email): Improve attachment methods --- .travis.yml | 2 +- lettre/src/file/mod.rs | 6 +-- lettre/src/lib.rs | 6 ++- lettre/src/sendmail/mod.rs | 8 ++-- lettre/src/smtp/commands.rs | 2 +- lettre/src/smtp/mod.rs | 2 +- lettre/src/smtp/response.rs | 2 +- lettre/tests/transport_file.rs | 2 +- lettre_email/examples/smtp.rs | 2 +- lettre_email/src/lib.rs | 75 +++++++++------------------------- 10 files changed, 37 insertions(+), 70 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4ff8d20..059f04b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ rust: - stable - beta - nightly -- 1.20.0 +- 1.26.0 matrix: allow_failures: - rust: nightly diff --git a/lettre/src/file/mod.rs b/lettre/src/file/mod.rs index cbe7688..664b660 100644 --- a/lettre/src/file/mod.rs +++ b/lettre/src/file/mod.rs @@ -3,14 +3,14 @@ //! It can be useful for testing purposes, or if you want to keep track of sent messages. //! -use Envelope; -use SendableEmail; -use Transport; use file::error::FileResult; use serde_json; use std::fs::File; use std::io::prelude::*; use std::path::{Path, PathBuf}; +use Envelope; +use SendableEmail; +use Transport; pub mod error; diff --git a/lettre/src/lib.rs b/lettre/src/lib.rs index 1d84210..de5abc6 100644 --- a/lettre/src/lib.rs +++ b/lettre/src/lib.rs @@ -4,8 +4,10 @@ //! #![doc(html_root_url = "https://docs.rs/lettre/0.9.0")] -#![deny(missing_copy_implementations, trivial_casts, trivial_numeric_casts, unsafe_code, - unstable_features, unused_import_braces, unused_qualifications)] +#![deny( + missing_copy_implementations, trivial_casts, trivial_numeric_casts, unsafe_code, + unstable_features, unused_import_braces, unused_qualifications +)] #[cfg(feature = "smtp-transport")] extern crate base64; #[cfg(feature = "smtp-transport")] diff --git a/lettre/src/sendmail/mod.rs b/lettre/src/sendmail/mod.rs index c1a6a38..b33dabb 100644 --- a/lettre/src/sendmail/mod.rs +++ b/lettre/src/sendmail/mod.rs @@ -1,12 +1,12 @@ //! The sendmail transport sends the email using the local sendmail command. //! +use sendmail::error::SendmailResult; +use std::io::prelude::*; +use std::io::Read; +use std::process::{Command, Stdio}; use SendableEmail; use Transport; -use sendmail::error::SendmailResult; -use std::io::Read; -use std::io::prelude::*; -use std::process::{Command, Stdio}; pub mod error; diff --git a/lettre/src/smtp/commands.rs b/lettre/src/smtp/commands.rs index 7360312..87ec272 100644 --- a/lettre/src/smtp/commands.rs +++ b/lettre/src/smtp/commands.rs @@ -1,6 +1,5 @@ //! SMTP commands -use EmailAddress; use base64; use smtp::authentication::{Credentials, Mechanism}; use smtp::error::Error; @@ -8,6 +7,7 @@ use smtp::extension::ClientId; use smtp::extension::{MailParameter, RcptParameter}; use smtp::response::Response; use std::fmt::{self, Display, Formatter}; +use EmailAddress; /// EHLO command #[derive(PartialEq, Clone, Debug)] diff --git a/lettre/src/smtp/mod.rs b/lettre/src/smtp/mod.rs index 398eb7f..cf3f13c 100644 --- a/lettre/src/smtp/mod.rs +++ b/lettre/src/smtp/mod.rs @@ -16,9 +16,9 @@ use native_tls::TlsConnector; use smtp::authentication::{Credentials, Mechanism, DEFAULT_ENCRYPTED_MECHANISMS, DEFAULT_UNENCRYPTED_MECHANISMS}; -use smtp::client::InnerClient; use smtp::client::net::ClientTlsParameters; use smtp::client::net::DEFAULT_TLS_PROTOCOLS; +use smtp::client::InnerClient; use smtp::commands::*; use smtp::error::{Error, SmtpResult}; use smtp::extension::{ClientId, Extension, MailBodyParameter, MailParameter, ServerInfo}; diff --git a/lettre/src/smtp/response.rs b/lettre/src/smtp/response.rs index 3fb2110..a935b06 100644 --- a/lettre/src/smtp/response.rs +++ b/lettre/src/smtp/response.rs @@ -5,7 +5,7 @@ use nom::simple_errors::Err as NomError; use nom::{crlf, ErrorKind as NomErrorKind, IResult as NomResult}; use std::fmt::{Display, Formatter, Result}; use std::result; -use std::str::{FromStr, from_utf8}; +use std::str::{from_utf8, FromStr}; /// First digit indicates severity #[derive(PartialEq, Eq, Copy, Clone, Debug)] diff --git a/lettre/tests/transport_file.rs b/lettre/tests/transport_file.rs index e231e43..2f1bb12 100644 --- a/lettre/tests/transport_file.rs +++ b/lettre/tests/transport_file.rs @@ -7,8 +7,8 @@ mod test { use lettre::file::FileTransport; use lettre::{EmailAddress, Envelope, SendableEmail, Transport}; use std::env::temp_dir; - use std::fs::File; use std::fs::remove_file; + use std::fs::File; use std::io::Read; #[test] diff --git a/lettre_email/examples/smtp.rs b/lettre_email/examples/smtp.rs index bd3b879..cb97a80 100644 --- a/lettre_email/examples/smtp.rs +++ b/lettre_email/examples/smtp.rs @@ -14,7 +14,7 @@ fn main() { .from("user@example.com") .subject("Hi, Hello world") .text("Hello world.") - .attachment(Path::new("Cargo.toml"), None, &mime::TEXT_PLAIN).unwrap() + .attachment_from_file(Path::new("Cargo.toml"), None, &mime::TEXT_PLAIN).unwrap() .build() .unwrap(); diff --git a/lettre_email/src/lib.rs b/lettre_email/src/lib.rs index 497783b..6229765 100644 --- a/lettre_email/src/lib.rs +++ b/lettre_email/src/lib.rs @@ -2,9 +2,11 @@ //! #![doc(html_root_url = "https://docs.rs/lettre_email/0.9.0")] -#![deny(missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts, - trivial_numeric_casts, unsafe_code, unstable_features, unused_import_braces, - unused_qualifications)] +#![deny( + missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts, + trivial_numeric_casts, unsafe_code, unstable_features, unused_import_braces, + unused_qualifications +)] extern crate base64; extern crate email as email_format; @@ -19,8 +21,7 @@ pub use email_format::{Address, Header, Mailbox, MimeMessage, MimeMultipartType} use error::Error; use lettre::{EmailAddress, Envelope, Error as EmailError, SendableEmail}; use mime::Mime; -use std::fs::File; -use std::io::Read; +use std::fs; use std::path::Path; use std::str::FromStr; use time::{now, Tm}; @@ -218,72 +219,36 @@ impl EmailBuilder { } /// Adds an attachment to the email from a file - pub fn attachment( + /// + /// If not specified, the filename will be extracted from the file path. + pub fn attachment_from_file( self, path: &Path, filename: Option<&str>, content_type: &Mime, ) -> Result { - let file = File::open(path); - let body = match file { - Ok(mut f) => { - let mut data = Vec::new(); - let read = f.read_to_end(&mut data); - match read { - Ok(_) => data, - Err(e) => { - return Err(From::from(e)); - } - } - } - Err(e) => { - return Err(From::from(e)); - } - }; - - let actual_filename = match filename { - Some(name) => name, - None => match path.file_name() { - Some(name) => match name.to_str() { - Some(name) => name, - None => return Err(Error::CannotParseFilename), - }, - None => return Err(Error::CannotParseFilename), - }, - }; - - let encoded_body = base64::encode(&body); - let content = PartBuilder::new() - .body(encoded_body) - .header(( - "Content-Disposition", - format!("attachment; filename=\"{}\"", actual_filename), - )) - .header(("Content-Type", content_type.to_string())) - .header(("Content-Transfer-Encoding", "base64")) - .build(); - - Ok(self.message_type(MimeMultipartType::Mixed).child(content)) + self.attachment( + fs::read(path)?.as_slice(), + filename.unwrap_or(path.file_name() + .and_then(|x| x.to_str()) + .ok_or(Error::CannotParseFilename)?), + content_type, + ) } /// Adds an attachment to the email from a vector of bytes. - /// This is usefull when your attachment is actually not a file, but a sequence of bytes. - pub fn attach_from_vec( + pub fn attachment( self, - bytes_vec: &Vec, + body: &[u8], filename: &str, content_type: &Mime, - ) -> Result { - let body = bytes_vec; - - let actual_filename = filename; - + ) -> Result { let encoded_body = base64::encode(&body); let content = PartBuilder::new() .body(encoded_body) .header(( "Content-Disposition", - format!("attachment; filename=\"{}\"", actual_filename), + format!("attachment; filename=\"{}\"", filename), )) .header(("Content-Type", content_type.to_string())) .header(("Content-Transfer-Encoding", "base64"))