diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2aaa531..4324eb3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ env: jobs: rustfmt: - name: rustfmt / stable + name: rustfmt / nightly-2022-02-11 runs-on: ubuntu-latest steps: @@ -22,7 +22,7 @@ jobs: - name: Install rust run: | - rustup update --no-self-update stable + rustup default nightly-2022-02-11 rustup component add rustfmt - name: cargo fmt diff --git a/examples/tokio1_smtp_starttls.rs b/examples/tokio1_smtp_starttls.rs index 81b2c21..19431d5 100644 --- a/examples/tokio1_smtp_starttls.rs +++ b/examples/tokio1_smtp_starttls.rs @@ -1,12 +1,11 @@ // This line is only to make it compile from lettre's examples folder, // since it uses Rust 2018 crate renaming to import tokio. // Won't be needed in user's code. -use tokio1_crate as tokio; - use lettre::{ transport::smtp::authentication::Credentials, AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor, }; +use tokio1_crate as tokio; #[tokio::main] async fn main() { diff --git a/examples/tokio1_smtp_tls.rs b/examples/tokio1_smtp_tls.rs index 564d087..5c86953 100644 --- a/examples/tokio1_smtp_tls.rs +++ b/examples/tokio1_smtp_tls.rs @@ -1,12 +1,11 @@ // This line is only to make it compile from lettre's examples folder, // since it uses Rust 2018 crate renaming to import tokio. // Won't be needed in user's code. -use tokio1_crate as tokio; - use lettre::{ transport::smtp::authentication::Credentials, AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor, }; +use tokio1_crate as tokio; #[tokio::main] async fn main() { diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..cc7e7de --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,3 @@ +format_code_in_doc_comments = true +imports_granularity = "Crate" +group_imports = "StdExternalCrate" diff --git a/src/address/types.rs b/src/address/types.rs index 3006388..36c9d4a 100644 --- a/src/address/types.rs +++ b/src/address/types.rs @@ -1,8 +1,5 @@ //! Representation of an email address -use idna::domain_to_ascii; -use once_cell::sync::Lazy; -use regex::Regex; use std::{ convert::{TryFrom, TryInto}, error::Error, @@ -12,6 +9,10 @@ use std::{ str::FromStr, }; +use idna::domain_to_ascii; +use once_cell::sync::Lazy; +use regex::Regex; + /// Represents an email address with a user and a domain name. /// /// This type contains email in canonical form (_user@domain.tld_). diff --git a/src/executor.rs b/src/executor.rs index be00192..672503e 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -1,7 +1,3 @@ -use async_trait::async_trait; -#[cfg(all(feature = "smtp-transport", feature = "async-std1"))] -use futures_util::future::BoxFuture; - use std::fmt::Debug; #[cfg(feature = "smtp-transport")] use std::future::Future; @@ -12,6 +8,10 @@ use std::path::Path; #[cfg(feature = "smtp-transport")] use std::time::Duration; +use async_trait::async_trait; +#[cfg(all(feature = "smtp-transport", feature = "async-std1"))] +use futures_util::future::BoxFuture; + #[cfg(all( feature = "smtp-transport", any(feature = "tokio1", feature = "async-std1") diff --git a/src/lib.rs b/src/lib.rs index 0fa1d3b..d5223df 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -175,6 +175,8 @@ mod executor; pub mod message; pub mod transport; +use std::error::Error as StdError; + #[cfg(feature = "async-std1")] pub use self::executor::AsyncStd1Executor; #[cfg(all(any(feature = "tokio1", feature = "async-std1")))] @@ -211,14 +213,12 @@ pub use crate::transport::sendmail::SendmailTransport; any(feature = "tokio1", feature = "async-std1") ))] pub use crate::transport::smtp::AsyncSmtpTransport; +#[cfg(feature = "smtp-transport")] +pub use crate::transport::smtp::SmtpTransport; #[doc(inline)] pub use crate::transport::Transport; use crate::{address::Envelope, error::Error}; -#[cfg(feature = "smtp-transport")] -pub use crate::transport::smtp::SmtpTransport; -use std::error::Error as StdError; - pub(crate) type BoxError = Box; #[cfg(test)] diff --git a/src/message/attachment.rs b/src/message/attachment.rs index ddd62a1..f6d25a6 100644 --- a/src/message/attachment.rs +++ b/src/message/attachment.rs @@ -29,7 +29,7 @@ impl Attachment { /// # use std::error::Error; /// use std::fs; /// - /// use lettre::message::{Attachment, header::ContentType}; + /// use lettre::message::{header::ContentType, Attachment}; /// /// # fn main() -> Result<(), Box> { /// let filename = String::from("invoice.pdf"); @@ -64,7 +64,7 @@ impl Attachment { /// # use std::error::Error; /// use std::fs; /// - /// use lettre::message::{Attachment, header::ContentType}; + /// use lettre::message::{header::ContentType, Attachment}; /// /// # fn main() -> Result<(), Box> { /// let content_id = String::from("123"); diff --git a/src/message/dkim.rs b/src/message/dkim.rs index edb9411..3cae12c 100644 --- a/src/message/dkim.rs +++ b/src/message/dkim.rs @@ -1,17 +1,21 @@ -use crate::message::{ - header::{HeaderName, HeaderValue}, - Headers, Message, +use std::{ + borrow::Cow, + error::Error as StdError, + fmt::{self, Display, Write}, + iter::IntoIterator, + time::SystemTime, }; + use ed25519_dalek::Signer; use once_cell::sync::Lazy; use regex::{bytes::Regex as BRegex, Regex}; use rsa::{pkcs1::FromRsaPrivateKey, Hash, PaddingScheme, RsaPrivateKey}; use sha2::{Digest, Sha256}; -use std::borrow::Cow; -use std::error::Error as StdError; -use std::fmt::{self, Display, Write}; -use std::iter::IntoIterator; -use std::time::SystemTime; + +use crate::message::{ + header::{HeaderName, HeaderValue}, + Headers, Message, +}; /// Describe Dkim Canonicalization to apply to either body or headers #[derive(Copy, Clone, Debug)] @@ -381,15 +385,20 @@ pub(super) fn dkim_sign(message: &mut Message, dkim_config: &DkimConfig) { #[cfg(test)] mod test { + use std::{ + io::Write, + process::{Command, Stdio}, + }; + use super::{ - super::header::{HeaderName, HeaderValue}, - super::{Header, Message}, + super::{ + header::{HeaderName, HeaderValue}, + Header, Message, + }, dkim_canonicalize_body, dkim_canonicalize_header_value, dkim_canonicalize_headers, DkimCanonicalizationType, DkimConfig, DkimSigningAlgorithm, DkimSigningKey, }; use crate::StdError; - use std::io::Write; - use std::process::{Command, Stdio}; #[derive(Clone)] struct TestHeader(String); diff --git a/src/message/header/content_type.rs b/src/message/header/content_type.rs index c57de25..5a588db 100644 --- a/src/message/header/content_type.rs +++ b/src/message/header/content_type.rs @@ -94,11 +94,13 @@ impl Display for ContentTypeErr { // -- Serialization and Deserialization -- #[cfg(feature = "serde")] mod serde { - use serde::de::{self, Deserialize, Deserializer, Visitor}; - use serde::ser::{Serialize, Serializer}; - use std::fmt; + use serde::{ + de::{self, Deserialize, Deserializer, Visitor}, + ser::{Serialize, Serializer}, + }; + use super::ContentType; impl Serialize for ContentType { diff --git a/src/message/mailbox/serde.rs b/src/message/mailbox/serde.rs index 5ab61ff..64868c3 100644 --- a/src/message/mailbox/serde.rs +++ b/src/message/mailbox/serde.rs @@ -1,10 +1,12 @@ -use crate::message::{Mailbox, Mailboxes}; +use std::fmt::{Formatter, Result as FmtResult}; + use serde::{ de::{Deserializer, Error as DeError, MapAccess, SeqAccess, Visitor}, ser::Serializer, Deserialize, Serialize, }; -use std::fmt::{Formatter, Result as FmtResult}; + +use crate::message::{Mailbox, Mailboxes}; impl Serialize for Mailbox { fn serialize(&self, serializer: S) -> Result @@ -152,9 +154,10 @@ impl<'de> Deserialize<'de> for Mailboxes { #[cfg(test)] mod test { + use serde_json::from_str; + use super::*; use crate::address::Address; - use serde_json::from_str; #[test] fn parse_address_string() { diff --git a/src/message/mailbox/types.rs b/src/message/mailbox/types.rs index 939fd45..74b4acb 100644 --- a/src/message/mailbox/types.rs +++ b/src/message/mailbox/types.rs @@ -1,4 +1,3 @@ -use crate::address::{Address, AddressError}; use std::{ convert::TryFrom, fmt::{Display, Formatter, Result as FmtResult, Write}, @@ -6,6 +5,8 @@ use std::{ str::FromStr, }; +use crate::address::{Address, AddressError}; + /// Represents an email address with an optional name for the sender/recipient. /// /// This type contains email address and the sender/recipient name (_Some Name \_ or _withoutname@domain.tld_). @@ -410,9 +411,10 @@ fn write_quoted_string_char(f: &mut Formatter<'_>, c: u8) -> FmtResult { #[cfg(test)] mod test { - use super::Mailbox; use std::convert::TryInto; + use super::Mailbox; + #[test] fn mailbox_format_address_only() { assert_eq!( diff --git a/src/message/mimebody.rs b/src/message/mimebody.rs index b9e22ca..3ab5620 100644 --- a/src/message/mimebody.rs +++ b/src/message/mimebody.rs @@ -1,11 +1,11 @@ -use std::io::Write; +use std::{io::Write, iter::repeat_with}; + +use mime::Mime; use crate::message::{ header::{self, ContentTransferEncoding, ContentType, Header, Headers}, EmailFormat, IntoBody, }; -use mime::Mime; -use std::iter::repeat_with; /// MIME part variants #[derive(Debug, Clone)] diff --git a/src/message/mod.rs b/src/message/mod.rs index 4a5e3da..6608abf 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -106,9 +106,10 @@ //! //! ```rust //! # use std::error::Error; -//! use lettre::message::{header, Attachment, Body, Message, MultiPart, SinglePart}; //! use std::fs; //! +//! use lettre::message::{header, Attachment, Body, Message, MultiPart, SinglePart}; +//! //! # fn main() -> Result<(), Box> { //! let image = fs::read("docs/lettre.png")?; //! // this image_body can be cloned and reused between emails. @@ -510,16 +511,18 @@ impl Message { /// /// Example: /// ```rust - /// use lettre::Message; - /// use lettre::message::dkim::{DkimConfig, DkimSigningAlgorithm, DkimSigningKey}; + /// use lettre::{ + /// message::dkim::{DkimConfig, DkimSigningAlgorithm, DkimSigningKey}, + /// Message, + /// }; /// /// let mut message = Message::builder() - /// .from("Alice ".parse().unwrap()) - /// .reply_to("Bob ".parse().unwrap()) - /// .to("Carla ".parse().unwrap()) - /// .subject("Hello") - /// .body("Hi there, it's a test email, with utf-8 chars ë!\n\n\n".to_string()) - /// .unwrap(); + /// .from("Alice ".parse().unwrap()) + /// .reply_to("Bob ".parse().unwrap()) + /// .to("Carla ".parse().unwrap()) + /// .subject("Hello") + /// .body("Hi there, it's a test email, with utf-8 chars ë!\n\n\n".to_string()) + /// .unwrap(); /// let key = "-----BEGIN RSA PRIVATE KEY----- /// MIIEowIBAAKCAQEAt2gawjoybf0mAz0mSX0cq1ah5F9cPazZdCwLnFBhRufxaZB8 /// NLTdc9xfPIOK8l/xGrN7Nd63J4cTATqZukumczkA46O8YKHwa53pNT6NYwCNtDUL @@ -548,8 +551,15 @@ impl Message { /// I45fbR4l+3D/30WMfZlM6bzZbwPXEnr2s1mirmuQpjumY9wLhK25 /// -----END RSA PRIVATE KEY-----"; /// let signing_key = DkimSigningKey::new(key.to_string(), DkimSigningAlgorithm::Rsa).unwrap(); - /// message.sign(&DkimConfig::default_config("dkimtest".to_string(),"example.org".to_string(),signing_key)); - /// println!("message: {}", std::str::from_utf8(&message.formatted()).unwrap()); + /// message.sign(&DkimConfig::default_config( + /// "dkimtest".to_string(), + /// "example.org".to_string(), + /// signing_key, + /// )); + /// println!( + /// "message: {}", + /// std::str::from_utf8(&message.formatted()).unwrap() + /// ); /// ``` #[cfg(feature = "dkim")] pub fn sign(&mut self, dkim_config: &DkimConfig) { diff --git a/src/transport/file/error.rs b/src/transport/file/error.rs index cd84e9e..bbc6f0c 100644 --- a/src/transport/file/error.rs +++ b/src/transport/file/error.rs @@ -1,8 +1,9 @@ //! Error and result type for file transport -use crate::BoxError; use std::{error::Error as StdError, fmt}; +use crate::BoxError; + /// The Errors that may occur when sending an email over SMTP pub struct Error { inner: Box, diff --git a/src/transport/file/mod.rs b/src/transport/file/mod.rs index ef73522..27db775 100644 --- a/src/transport/file/mod.rs +++ b/src/transport/file/mod.rs @@ -9,9 +9,10 @@ //! # //! # #[cfg(all(feature = "file-transport", feature = "builder"))] //! # fn main() -> Result<(), Box> { -//! use lettre::{FileTransport, Message, Transport}; //! use std::env::temp_dir; //! +//! use lettre::{FileTransport, Message, Transport}; +//! //! // Write to the local temp directory //! let sender = FileTransport::new(temp_dir()); //! let email = Message::builder() @@ -41,9 +42,10 @@ //! # //! # #[cfg(all(feature = "file-transport-envelope", feature = "builder"))] //! # fn main() -> Result<(), Box> { -//! use lettre::{FileTransport, Message, Transport}; //! use std::env::temp_dir; //! +//! use lettre::{FileTransport, Message, Transport}; +//! //! // Write to the local temp directory //! let sender = FileTransport::with_envelope(temp_dir()); //! let email = Message::builder() @@ -70,7 +72,8 @@ //! # #[cfg(all(feature = "tokio1", feature = "file-transport", feature = "builder"))] //! # async fn run() -> Result<(), Box> { //! use std::env::temp_dir; -//! use lettre::{AsyncTransport, Tokio1Executor, Message, AsyncFileTransport}; +//! +//! use lettre::{AsyncFileTransport, AsyncTransport, Message, Tokio1Executor}; //! //! // Write to the local temp directory //! let sender = AsyncFileTransport::::new(temp_dir()); @@ -95,7 +98,8 @@ //! # #[cfg(all(feature = "async-std1", feature = "file-transport", feature = "builder"))] //! # async fn run() -> Result<(), Box> { //! use std::env::temp_dir; -//! use lettre::{AsyncTransport, AsyncStd1Executor, Message, AsyncFileTransport}; +//! +//! use lettre::{AsyncFileTransport, AsyncStd1Executor, AsyncTransport, Message}; //! //! // Write to the local temp directory //! let sender = AsyncFileTransport::::new(temp_dir()); @@ -132,20 +136,22 @@ //! {"forward_path":["hei@domain.tld"],"reverse_path":"nobody@domain.tld"} //! ``` -pub use self::error::Error; -use crate::{address::Envelope, Transport}; -#[cfg(any(feature = "async-std1", feature = "tokio1"))] -use crate::{AsyncTransport, Executor}; -#[cfg(any(feature = "async-std1", feature = "tokio1"))] -use async_trait::async_trait; #[cfg(any(feature = "async-std1", feature = "tokio1"))] use std::marker::PhantomData; use std::{ path::{Path, PathBuf}, str, }; + +#[cfg(any(feature = "async-std1", feature = "tokio1"))] +use async_trait::async_trait; use uuid::Uuid; +pub use self::error::Error; +use crate::{address::Envelope, Transport}; +#[cfg(any(feature = "async-std1", feature = "tokio1"))] +use crate::{AsyncTransport, Executor}; + mod error; type Id = String; diff --git a/src/transport/mod.rs b/src/transport/mod.rs index cb27a4d..9cde231 100644 --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -56,8 +56,7 @@ //! # //! # #[cfg(all(feature = "builder", feature = "smtp-transport"))] //! # fn main() -> Result<(), Box> { -//! use lettre::transport::smtp::authentication::Credentials; -//! use lettre::{Message, SmtpTransport, Transport}; +//! use lettre::{transport::smtp::authentication::Credentials, Message, SmtpTransport, Transport}; //! //! let email = Message::builder() //! .from("NoBody ".parse()?) diff --git a/src/transport/sendmail/error.rs b/src/transport/sendmail/error.rs index a2d80ee..ea613df 100644 --- a/src/transport/sendmail/error.rs +++ b/src/transport/sendmail/error.rs @@ -1,8 +1,9 @@ //! Error and result type for sendmail transport -use crate::BoxError; use std::{error::Error as StdError, fmt}; +use crate::BoxError; + /// The Errors that may occur when sending an email over sendmail pub struct Error { inner: Box, diff --git a/src/transport/sendmail/mod.rs b/src/transport/sendmail/mod.rs index 1c35b35..7916b52 100644 --- a/src/transport/sendmail/mod.rs +++ b/src/transport/sendmail/mod.rs @@ -33,7 +33,9 @@ //! # //! # #[cfg(all(feature = "tokio1", feature = "sendmail-transport", feature = "builder"))] //! # async fn run() -> Result<(), Box> { -//! use lettre::{Message, AsyncTransport, Tokio1Executor, AsyncSendmailTransport, SendmailTransport}; +//! use lettre::{ +//! AsyncSendmailTransport, AsyncTransport, Message, SendmailTransport, Tokio1Executor, +//! }; //! //! let email = Message::builder() //! .from("NoBody ".parse()?) @@ -72,6 +74,17 @@ //! # } //! ``` +#[cfg(any(feature = "async-std1", feature = "tokio1"))] +use std::marker::PhantomData; +use std::{ + ffi::OsString, + io::Write, + process::{Command, Stdio}, +}; + +#[cfg(any(feature = "async-std1", feature = "tokio1"))] +use async_trait::async_trait; + pub use self::error::Error; #[cfg(feature = "async-std1")] use crate::AsyncStd1Executor; @@ -80,15 +93,6 @@ use crate::Tokio1Executor; use crate::{address::Envelope, Transport}; #[cfg(any(feature = "async-std1", feature = "tokio1"))] use crate::{AsyncTransport, Executor}; -#[cfg(any(feature = "async-std1", feature = "tokio1"))] -use async_trait::async_trait; -#[cfg(any(feature = "async-std1", feature = "tokio1"))] -use std::marker::PhantomData; -use std::{ - ffi::OsString, - io::Write, - process::{Command, Stdio}, -}; mod error; diff --git a/src/transport/smtp/authentication.rs b/src/transport/smtp/authentication.rs index 0a3799b..63967e1 100644 --- a/src/transport/smtp/authentication.rs +++ b/src/transport/smtp/authentication.rs @@ -1,8 +1,9 @@ //! Provides limited SASL authentication mechanisms -use crate::transport::smtp::error::{self, Error}; use std::fmt::{self, Debug, Display, Formatter}; +use crate::transport::smtp::error::{self, Error}; + /// Accepted authentication mechanisms /// /// Trying LOGIN last as it is deprecated. diff --git a/src/transport/smtp/client/async_connection.rs b/src/transport/smtp/client/async_connection.rs index 45bb1e3..b3cd03b 100644 --- a/src/transport/smtp/client/async_connection.rs +++ b/src/transport/smtp/client/async_connection.rs @@ -1,3 +1,9 @@ +use std::{fmt::Display, time::Duration}; + +use futures_util::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; + +#[cfg(feature = "tracing")] +use super::escape_crlf; use super::{AsyncNetworkStream, ClientCodec, TlsParameters}; use crate::{ transport::smtp::{ @@ -10,11 +16,6 @@ use crate::{ }, Envelope, }; -use futures_util::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; -use std::{fmt::Display, time::Duration}; - -#[cfg(feature = "tracing")] -use super::escape_crlf; macro_rules! try_smtp ( ($err: expr, $client: ident) => ({ diff --git a/src/transport/smtp/client/async_net.rs b/src/transport/smtp/client/async_net.rs index 1c1f3c6..bf4e201 100644 --- a/src/transport/smtp/client/async_net.rs +++ b/src/transport/smtp/client/async_net.rs @@ -6,25 +6,22 @@ use std::{ time::Duration, }; +#[cfg(feature = "async-std1-native-tls")] +use async_native_tls::TlsStream as AsyncStd1TlsStream; +#[cfg(feature = "async-std1")] +use async_std::net::{TcpStream as AsyncStd1TcpStream, ToSocketAddrs as AsyncStd1ToSocketAddrs}; use futures_io::{ AsyncRead as FuturesAsyncRead, AsyncWrite as FuturesAsyncWrite, Error as IoError, ErrorKind, Result as IoResult, }; -#[cfg(feature = "tokio1")] -use tokio1_crate::io::{AsyncRead as _, AsyncWrite as _, ReadBuf as Tokio1ReadBuf}; - -#[cfg(feature = "async-std1")] -use async_std::net::{TcpStream as AsyncStd1TcpStream, ToSocketAddrs as AsyncStd1ToSocketAddrs}; -#[cfg(feature = "tokio1")] -use tokio1_crate::net::{TcpStream as Tokio1TcpStream, ToSocketAddrs as Tokio1ToSocketAddrs}; - -#[cfg(feature = "async-std1-native-tls")] -use async_native_tls::TlsStream as AsyncStd1TlsStream; -#[cfg(feature = "tokio1-native-tls")] -use tokio1_native_tls_crate::TlsStream as Tokio1TlsStream; - #[cfg(feature = "async-std1-rustls-tls")] use futures_rustls::client::TlsStream as AsyncStd1RustlsTlsStream; +#[cfg(feature = "tokio1")] +use tokio1_crate::io::{AsyncRead as _, AsyncWrite as _, ReadBuf as Tokio1ReadBuf}; +#[cfg(feature = "tokio1")] +use tokio1_crate::net::{TcpStream as Tokio1TcpStream, ToSocketAddrs as Tokio1ToSocketAddrs}; +#[cfg(feature = "tokio1-native-tls")] +use tokio1_native_tls_crate::TlsStream as Tokio1TlsStream; #[cfg(feature = "tokio1-rustls-tls")] use tokio1_rustls::client::TlsStream as Tokio1RustlsTlsStream; diff --git a/src/transport/smtp/client/connection.rs b/src/transport/smtp/client/connection.rs index 2e36a0f..45e1b73 100644 --- a/src/transport/smtp/client/connection.rs +++ b/src/transport/smtp/client/connection.rs @@ -5,6 +5,8 @@ use std::{ time::Duration, }; +#[cfg(feature = "tracing")] +use super::escape_crlf; use super::{ClientCodec, NetworkStream, TlsParameters}; use crate::{ address::Envelope, @@ -18,9 +20,6 @@ use crate::{ }, }; -#[cfg(feature = "tracing")] -use super::escape_crlf; - macro_rules! try_smtp ( ($err: expr, $client: ident) => ({ match $err { diff --git a/src/transport/smtp/client/mod.rs b/src/transport/smtp/client/mod.rs index 71fb3ae..68b750f 100644 --- a/src/transport/smtp/client/mod.rs +++ b/src/transport/smtp/client/mod.rs @@ -7,16 +7,14 @@ //! //! # #[cfg(feature = "smtp-transport")] //! # fn main() -> Result<(), Box> { -//! use lettre::transport::smtp::{SMTP_PORT, extension::ClientId, commands::*, client::SmtpConnection}; +//! use lettre::transport::smtp::{ +//! client::SmtpConnection, commands::*, extension::ClientId, SMTP_PORT, +//! }; //! //! let hello = ClientId::Domain("my_hostname".to_string()); //! let mut client = SmtpConnection::connect(&("localhost", SMTP_PORT), None, &hello, None)?; -//! client.command( -//! Mail::new(Some("user@example.com".parse()?), vec![]) -//! )?; -//! client.command( -//! Rcpt::new("user@example.org".parse()?, vec![]) -//! )?; +//! client.command(Mail::new(Some("user@example.com".parse()?), vec![]))?; +//! client.command(Rcpt::new("user@example.org".parse()?, vec![]))?; //! client.command(Data)?; //! client.message("Test email".as_bytes())?; //! client.command(Quit)?; diff --git a/src/transport/smtp/client/net.rs b/src/transport/smtp/client/net.rs index b03863c..d6bed0e 100644 --- a/src/transport/smtp/client/net.rs +++ b/src/transport/smtp/client/net.rs @@ -9,7 +9,6 @@ use std::{ #[cfg(feature = "native-tls")] use native_tls::TlsStream; - #[cfg(feature = "rustls-tls")] use rustls::{ClientConnection, ServerName, StreamOwned}; diff --git a/src/transport/smtp/client/tls.rs b/src/transport/smtp/client/tls.rs index 4777808..0b33f4f 100644 --- a/src/transport/smtp/client/tls.rs +++ b/src/transport/smtp/client/tls.rs @@ -1,5 +1,7 @@ -#[cfg(any(feature = "native-tls", feature = "rustls-tls"))] -use crate::transport::smtp::{error, Error}; +use std::fmt::{self, Debug}; +#[cfg(feature = "rustls-tls")] +use std::{sync::Arc, time::SystemTime}; + #[cfg(feature = "native-tls")] use native_tls::{Protocol, TlsConnector}; #[cfg(feature = "rustls-tls")] @@ -7,9 +9,9 @@ use rustls::{ client::{ServerCertVerified, ServerCertVerifier, WebPkiVerifier}, ClientConfig, Error as TlsError, OwnedTrustAnchor, RootCertStore, ServerName, }; -use std::fmt::{self, Debug}; -#[cfg(feature = "rustls-tls")] -use std::{sync::Arc, time::SystemTime}; + +#[cfg(any(feature = "native-tls", feature = "rustls-tls"))] +use crate::transport::smtp::{error, Error}; /// Accepted protocols by default. /// This removes TLS 1.0 and 1.1 compared to tls-native defaults. diff --git a/src/transport/smtp/commands.rs b/src/transport/smtp/commands.rs index 56e31f9..f5d06b2 100644 --- a/src/transport/smtp/commands.rs +++ b/src/transport/smtp/commands.rs @@ -1,5 +1,7 @@ //! SMTP commands +use std::fmt::{self, Display, Formatter}; + use crate::{ address::Address, transport::smtp::{ @@ -9,7 +11,6 @@ use crate::{ response::Response, }, }; -use std::fmt::{self, Display, Formatter}; /// EHLO command #[derive(PartialEq, Clone, Debug)] @@ -288,9 +289,10 @@ impl Auth { #[cfg(test)] mod test { + use std::str::FromStr; + use super::*; use crate::transport::smtp::extension::MailBodyParameter; - use std::str::FromStr; #[test] fn test_display() { diff --git a/src/transport/smtp/error.rs b/src/transport/smtp/error.rs index 555cb42..375c03a 100644 --- a/src/transport/smtp/error.rs +++ b/src/transport/smtp/error.rs @@ -1,10 +1,11 @@ //! Error and result type for SMTP clients +use std::{error::Error as StdError, fmt}; + use crate::{ transport::smtp::response::{Code, Severity}, BoxError, }; -use std::{error::Error as StdError, fmt}; // Inspired by https://github.com/seanmonstar/reqwest/blob/a8566383168c0ef06c21f38cbc9213af6ff6db31/src/error.rs diff --git a/src/transport/smtp/extension.rs b/src/transport/smtp/extension.rs index 2c88126..8af14cf 100644 --- a/src/transport/smtp/extension.rs +++ b/src/transport/smtp/extension.rs @@ -1,17 +1,18 @@ //! ESMTP features +use std::{ + collections::HashSet, + fmt::{self, Display, Formatter}, + net::{Ipv4Addr, Ipv6Addr}, + result::Result, +}; + use crate::transport::smtp::{ authentication::Mechanism, error::{self, Error}, response::Response, util::XText, }; -use std::{ - collections::HashSet, - fmt::{self, Display, Formatter}, - net::{Ipv4Addr, Ipv6Addr}, - result::Result, -}; /// Client identifier, the parameter to `EHLO` #[derive(PartialEq, Eq, Clone, Debug)] @@ -292,12 +293,13 @@ impl Display for RcptParameter { #[cfg(test)] mod test { + use std::collections::HashSet; + use super::*; use crate::transport::smtp::{ authentication::Mechanism, response::{Category, Code, Detail, Response, Severity}, }; - use std::collections::HashSet; #[test] fn test_clientid_fmt() { diff --git a/src/transport/smtp/mod.rs b/src/transport/smtp/mod.rs index c2cac3e..16b7f5f 100644 --- a/src/transport/smtp/mod.rs +++ b/src/transport/smtp/mod.rs @@ -33,7 +33,7 @@ //! ```rust,no_run //! # #[cfg(all(feature = "builder", any(feature = "native-tls", feature = "rustls-tls")))] //! # fn test() -> Result<(), Box> { -//! use lettre::{Message, Transport, SmtpTransport}; +//! use lettre::{Message, SmtpTransport, Transport}; //! //! let email = Message::builder() //! .from("NoBody ".parse()?) @@ -43,8 +43,7 @@ //! .body(String::from("Be happy!"))?; //! //! // Create TLS transport on port 465 -//! let sender = SmtpTransport::relay("smtp.example.com")? -//! .build(); +//! let sender = SmtpTransport::relay("smtp.example.com")?.build(); //! // Send the email via remote relay //! let result = sender.send(&email); //! assert!(result.is_ok()); @@ -59,7 +58,13 @@ //! ```rust,no_run //! # #[cfg(all(feature = "builder", any(feature = "native-tls", feature = "rustls-tls")))] //! # fn test() -> Result<(), Box> { -//! use lettre::{Message, Transport, SmtpTransport, transport::smtp::{PoolConfig, authentication::{Credentials, Mechanism}}}; +//! use lettre::{ +//! transport::smtp::{ +//! authentication::{Credentials, Mechanism}, +//! PoolConfig, +//! }, +//! Message, SmtpTransport, Transport, +//! }; //! //! let email = Message::builder() //! .from("NoBody ".parse()?) @@ -71,11 +76,14 @@ //! // Create TLS transport on port 587 with STARTTLS //! let sender = SmtpTransport::starttls_relay("smtp.example.com")? //! // Add credentials for authentication -//! .credentials(Credentials::new("username".to_string(), "password".to_string())) +//! .credentials(Credentials::new( +//! "username".to_string(), +//! "password".to_string(), +//! )) //! // Configure expected authentication mechanism //! .authentication(vec![Mechanism::Plain]) //! // Connection pool settings -//! .pool_config( PoolConfig::new().max_size(20)) +//! .pool_config(PoolConfig::new().max_size(20)) //! .build(); //! //! // Send the email via remote relay @@ -90,7 +98,10 @@ //! ```rust,no_run //! # #[cfg(all(feature = "builder", any(feature = "native-tls", feature = "rustls-tls")))] //! # fn test() -> Result<(), Box> { -//! use lettre::{Message, Transport, SmtpTransport, transport::smtp::client::{TlsParameters, Tls}}; +//! use lettre::{ +//! transport::smtp::client::{Tls, TlsParameters}, +//! Message, SmtpTransport, Transport, +//! }; //! //! let email = Message::builder() //! .from("NoBody ".parse()?) @@ -101,7 +112,8 @@ //! //! // Custom TLS configuration //! let tls = TlsParameters::builder("smtp.example.com".to_string()) -//! .dangerous_accept_invalid_certs(true).build()?; +//! .dangerous_accept_invalid_certs(true) +//! .build()?; //! //! // Create TLS transport on port 465 //! let sender = SmtpTransport::relay("smtp.example.com")? @@ -116,6 +128,10 @@ //! # } //! ``` +use std::time::Duration; + +use client::Tls; + #[cfg(any(feature = "tokio1", feature = "async-std1"))] pub use self::async_transport::{AsyncSmtpTransport, AsyncSmtpTransportBuilder}; #[cfg(feature = "pool")] @@ -132,8 +148,6 @@ use crate::transport::smtp::{ extension::ClientId, response::Response, }; -use client::Tls; -use std::time::Duration; #[cfg(any(feature = "tokio1", feature = "async-std1"))] mod async_transport; diff --git a/src/transport/smtp/pool/async_impl.rs b/src/transport/smtp/pool/async_impl.rs index b947a25..f771762 100644 --- a/src/transport/smtp/pool/async_impl.rs +++ b/src/transport/smtp/pool/async_impl.rs @@ -1,20 +1,22 @@ -use std::fmt::{self, Debug}; -use std::mem; -use std::ops::{Deref, DerefMut}; -use std::sync::Arc; -use std::time::{Duration, Instant}; +use std::{ + fmt::{self, Debug}, + mem, + ops::{Deref, DerefMut}, + sync::Arc, + time::{Duration, Instant}, +}; -use futures_util::lock::Mutex; -use futures_util::stream::{self, StreamExt}; +use futures_util::{ + lock::Mutex, + stream::{self, StreamExt}, +}; use once_cell::sync::OnceCell; -use crate::executor::SpawnHandle; -use crate::transport::smtp::async_transport::AsyncSmtpClient; -use crate::Executor; - -use super::super::client::AsyncSmtpConnection; -use super::super::Error; -use super::PoolConfig; +use super::{ + super::{client::AsyncSmtpConnection, Error}, + PoolConfig, +}; +use crate::{executor::SpawnHandle, transport::smtp::async_transport::AsyncSmtpClient, Executor}; pub struct Pool { config: PoolConfig, diff --git a/src/transport/smtp/pool/sync_impl.rs b/src/transport/smtp/pool/sync_impl.rs index 40e0253..aea8350 100644 --- a/src/transport/smtp/pool/sync_impl.rs +++ b/src/transport/smtp/pool/sync_impl.rs @@ -1,15 +1,18 @@ -use std::fmt::{self, Debug}; -use std::ops::{Deref, DerefMut}; -use std::sync::{Arc, Mutex, TryLockError}; -use std::time::{Duration, Instant}; -use std::{mem, thread}; +use std::{ + fmt::{self, Debug}, + mem, + ops::{Deref, DerefMut}, + sync::{Arc, Mutex, TryLockError}, + thread, + time::{Duration, Instant}, +}; +use super::{ + super::{client::SmtpConnection, Error}, + PoolConfig, +}; use crate::transport::smtp::transport::SmtpClient; -use super::super::client::SmtpConnection; -use super::super::Error; -use super::PoolConfig; - pub struct Pool { config: PoolConfig, connections: Mutex>, diff --git a/src/transport/smtp/response.rs b/src/transport/smtp/response.rs index a780aae..73ce167 100644 --- a/src/transport/smtp/response.rs +++ b/src/transport/smtp/response.rs @@ -1,7 +1,13 @@ //! SMTP response, containing a mandatory return code and an optional text //! message -use crate::transport::smtp::{error, Error}; +use std::{ + fmt::{Display, Formatter, Result}, + result, + str::FromStr, + string::ToString, +}; + use nom::{ branch::alt, bytes::streaming::{tag, take_until}, @@ -10,12 +16,8 @@ use nom::{ sequence::{preceded, tuple}, IResult, }; -use std::{ - fmt::{Display, Formatter, Result}, - result, - str::FromStr, - string::ToString, -}; + +use crate::transport::smtp::{error, Error}; /// First digit indicates severity #[derive(PartialEq, Eq, Copy, Clone, Debug)] diff --git a/src/transport/stub/mod.rs b/src/transport/stub/mod.rs index 533f007..7b0a13f 100644 --- a/src/transport/stub/mod.rs +++ b/src/transport/stub/mod.rs @@ -28,12 +28,14 @@ //! # } //! ``` +use std::{error::Error as StdError, fmt}; + +#[cfg(any(feature = "tokio1", feature = "async-std1"))] +use async_trait::async_trait; + #[cfg(any(feature = "tokio1", feature = "async-std1"))] use crate::AsyncTransport; use crate::{address::Envelope, Transport}; -#[cfg(any(feature = "tokio1", feature = "async-std1"))] -use async_trait::async_trait; -use std::{error::Error as StdError, fmt}; #[derive(Debug, Copy, Clone)] pub struct Error; diff --git a/tests/transport_file.rs b/tests/transport_file.rs index db74301..76267fa 100644 --- a/tests/transport_file.rs +++ b/tests/transport_file.rs @@ -9,13 +9,15 @@ fn default_date() -> std::time::SystemTime { #[cfg(test)] #[cfg(all(feature = "file-transport", feature = "builder"))] mod sync { - use crate::default_date; - use lettre::{FileTransport, Message, Transport}; use std::{ env::temp_dir, fs::{read_to_string, remove_file}, }; + use lettre::{FileTransport, Message, Transport}; + + use crate::default_date; + #[test] fn file_transport() { let sender = FileTransport::new(temp_dir()); @@ -104,15 +106,16 @@ mod sync { #[cfg(test)] #[cfg(all(feature = "file-transport", feature = "builder", feature = "tokio1"))] mod tokio_1 { - use crate::default_date; - use lettre::{AsyncFileTransport, AsyncTransport, Message, Tokio1Executor}; use std::{ env::temp_dir, fs::{read_to_string, remove_file}, }; + use lettre::{AsyncFileTransport, AsyncTransport, Message, Tokio1Executor}; use tokio1_crate as tokio; + use crate::default_date; + #[tokio::test] async fn file_transport_tokio1() { let sender = AsyncFileTransport::::new(temp_dir()); @@ -155,13 +158,15 @@ mod tokio_1 { feature = "async-std1" ))] mod asyncstd_1 { - use crate::default_date; - use lettre::{AsyncFileTransport, AsyncStd1Executor, AsyncTransport, Message}; use std::{ env::temp_dir, fs::{read_to_string, remove_file}, }; + use lettre::{AsyncFileTransport, AsyncStd1Executor, AsyncTransport, Message}; + + use crate::default_date; + #[async_std::test] async fn file_transport_asyncstd1() { let sender = AsyncFileTransport::::new(temp_dir()); diff --git a/tests/transport_smtp.rs b/tests/transport_smtp.rs index d639f11..548d142 100644 --- a/tests/transport_smtp.rs +++ b/tests/transport_smtp.rs @@ -24,7 +24,6 @@ mod sync { #[cfg(all(feature = "smtp-transport", feature = "builder", feature = "tokio1"))] mod tokio_1 { use lettre::{AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor}; - use tokio1_crate as tokio; #[tokio::test] diff --git a/tests/transport_smtp_pool.rs b/tests/transport_smtp_pool.rs index d0ea3e9..d6eb07b 100644 --- a/tests/transport_smtp_pool.rs +++ b/tests/transport_smtp_pool.rs @@ -1,8 +1,9 @@ #[cfg(all(test, feature = "smtp-transport", feature = "pool"))] mod sync { - use lettre::{address::Envelope, SmtpTransport, Transport}; use std::{sync::mpsc, thread}; + use lettre::{address::Envelope, SmtpTransport, Transport}; + fn envelope() -> Envelope { Envelope::new( Some("user@localhost".parse().unwrap()), diff --git a/tests/transport_stub.rs b/tests/transport_stub.rs index 32a624a..01b7119 100644 --- a/tests/transport_stub.rs +++ b/tests/transport_stub.rs @@ -24,7 +24,6 @@ mod sync { #[cfg(all(feature = "builder", feature = "tokio1"))] mod tokio_1 { use lettre::{transport::stub::StubTransport, AsyncTransport, Message}; - use tokio1_crate as tokio; #[tokio::test]