Improve documentation
This commit is contained in:
committed by
Alexis Mousset
parent
ce957ee346
commit
3cf89935af
@@ -169,7 +169,7 @@ impl Display for AddressError {
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
pub mod serde {
|
||||
mod serde {
|
||||
use crate::address::Address;
|
||||
use serde::{
|
||||
de::{Deserializer, Error as DeError, MapAccess, Visitor},
|
||||
|
||||
19
src/lib.rs
19
src/lib.rs
@@ -15,6 +15,10 @@
|
||||
//! * **sendmail-transport**: Transport over SMTP
|
||||
//! * **rustls-tls**: TLS support with the `rustls` crate
|
||||
//! * **native-tls**: TLS support with the `native-tls` crate
|
||||
//! * **tokio02**: Allow to asyncronously send emails using tokio 0.2.x
|
||||
//! * **tokio02-rustls-tls**: Async TLS support with the `rustls` crate using tokio 0.2
|
||||
//! * **tokio02-native-tls**: Async TLS support with the `native-tls` crate using tokio 0.2
|
||||
//! * **async-std1**: Allow to asyncronously send emails using async-std 1.x (SMTP isn't supported yet)
|
||||
//! * **r2d2**: Connection pool for SMTP transport
|
||||
//! * **tracing**: Logging using the `tracing` crate
|
||||
//! * **serde**: Serialization/Deserialization of entities
|
||||
@@ -203,8 +207,10 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn envelope_from_headers() {
|
||||
let from = Mailboxes::new().with("kayo@example.com".parse().unwrap());
|
||||
let to = Mailboxes::new().with("amousset@example.com".parse().unwrap());
|
||||
let mut from = Mailboxes::new();
|
||||
from.push("kayo@example.com".parse().unwrap());
|
||||
let mut to = Mailboxes::new();
|
||||
to.push("amousset@example.com".parse().unwrap());
|
||||
|
||||
let mut headers = Headers::new();
|
||||
headers.set(header::From(from));
|
||||
@@ -222,9 +228,11 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn envelope_from_headers_sender() {
|
||||
let from = Mailboxes::new().with("kayo@example.com".parse().unwrap());
|
||||
let mut from = Mailboxes::new();
|
||||
from.push("kayo@example.com".parse().unwrap());
|
||||
let sender = Mailbox::new(None, "kayo2@example.com".parse().unwrap());
|
||||
let to = Mailboxes::new().with("amousset@example.com".parse().unwrap());
|
||||
let mut to = Mailboxes::new();
|
||||
to.push("amousset@example.com".parse().unwrap());
|
||||
|
||||
let mut headers = Headers::new();
|
||||
headers.set(header::From(from));
|
||||
@@ -243,7 +251,8 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn envelope_from_headers_no_to() {
|
||||
let from = Mailboxes::new().with("kayo@example.com".parse().unwrap());
|
||||
let mut from = Mailboxes::new();
|
||||
from.push("kayo@example.com".parse().unwrap());
|
||||
let sender = Mailbox::new(None, "kayo2@example.com".parse().unwrap());
|
||||
|
||||
let mut headers = Headers::new();
|
||||
|
||||
@@ -169,7 +169,8 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn format_single_without_name() {
|
||||
let from = Mailboxes::new().with("kayo@example.com".parse().unwrap());
|
||||
let mut from = Mailboxes::new();
|
||||
from.push("kayo@example.com".parse().unwrap());
|
||||
|
||||
let mut headers = Headers::new();
|
||||
headers.set(From(from));
|
||||
@@ -179,7 +180,8 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn format_single_with_name() {
|
||||
let from = Mailboxes::new().with("K. <kayo@example.com>".parse().unwrap());
|
||||
let mut from = Mailboxes::new();
|
||||
from.push("K. <kayo@example.com>".parse().unwrap());
|
||||
|
||||
let mut headers = Headers::new();
|
||||
headers.set(From(from));
|
||||
@@ -189,9 +191,9 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn format_multi_without_name() {
|
||||
let from = Mailboxes::new()
|
||||
.with("kayo@example.com".parse().unwrap())
|
||||
.with("pony@domain.tld".parse().unwrap());
|
||||
let mut from = Mailboxes::new();
|
||||
from.push("kayo@example.com".parse().unwrap());
|
||||
from.push("pony@domain.tld".parse().unwrap());
|
||||
|
||||
let mut headers = Headers::new();
|
||||
headers.set(From(from));
|
||||
|
||||
@@ -113,12 +113,6 @@ impl Mailboxes {
|
||||
Mailboxes(Vec::new())
|
||||
}
|
||||
|
||||
/// Add mailbox to a list
|
||||
pub fn with(mut self, mbox: Mailbox) -> Self {
|
||||
self.0.push(mbox);
|
||||
self
|
||||
}
|
||||
|
||||
/// Add mailbox to a list
|
||||
pub fn push(&mut self, mbox: Mailbox) {
|
||||
self.0.push(mbox);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
//!
|
||||
//! The easiest way how we can create email message with simple string.
|
||||
//!
|
||||
//! ```rust
|
||||
//! ```rust,no_run
|
||||
//! # extern crate lettre;
|
||||
//! use lettre::message::Message;
|
||||
//!
|
||||
@@ -44,7 +44,7 @@
|
||||
//!
|
||||
//! The more complex way is using MIME contents.
|
||||
//!
|
||||
//! ```rust
|
||||
//! ```rust,no_run
|
||||
//! # extern crate lettre;
|
||||
//! use lettre::message::{header, Message, SinglePart, Part};
|
||||
//!
|
||||
@@ -82,7 +82,7 @@
|
||||
//!
|
||||
//! And more advanced way of building message by using multipart MIME contents.
|
||||
//!
|
||||
//! ```rust
|
||||
//! ```rust,no_run
|
||||
//! # extern crate lettre;
|
||||
//! use lettre::message::{header, Message, MultiPart, SinglePart, Part};
|
||||
//!
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
//! The file transport writes the emails to the given directory. The name of the file will be
|
||||
//! `message_id.txt`.
|
||||
//! It can be useful for testing purposes, or if you want to keep track of sent messages.
|
||||
//!
|
||||
//! #### File Transport
|
||||
//!
|
||||
//! The file transport writes the emails to the given directory. The name of the file will be
|
||||
//! `message_id.json`.
|
||||
//! It can be useful for testing purposes, or if you want to keep track of sent messages.
|
||||
//!
|
||||
//! ```rust
|
||||
//! # #[cfg(feature = "file-transport")]
|
||||
//! # {
|
||||
//! ## Sync example
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use std::env::temp_dir;
|
||||
//! use lettre::{Transport, Envelope, Message, FileTransport};
|
||||
//!
|
||||
@@ -26,20 +20,77 @@
|
||||
//!
|
||||
//! let result = sender.send(&email);
|
||||
//! assert!(result.is_ok());
|
||||
//! ```
|
||||
//!
|
||||
//! ## Async tokio 0.2
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! # #[cfg(feature = "tokio02")]
|
||||
//! # async fn run() {
|
||||
//! use std::env::temp_dir;
|
||||
//! use lettre::{Tokio02Transport, Envelope, Message, FileTransport};
|
||||
//!
|
||||
//! // Write to the local temp directory
|
||||
//! let sender = FileTransport::new(temp_dir());
|
||||
//! let email = Message::builder()
|
||||
//! .from("NoBody <nobody@domain.tld>".parse().unwrap())
|
||||
//! .reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
|
||||
//! .to("Hei <hei@domain.tld>".parse().unwrap())
|
||||
//! .subject("Happy new year")
|
||||
//! .body("Be happy!")
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let result = sender.send(email).await;
|
||||
//! assert!(result.is_ok());
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! Example result in `/tmp/b7c211bc-9811-45ce-8cd9-68eab575d695.json`:
|
||||
//! ## Async async-std 1.x
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! # #[cfg(feature = "async-std1")]
|
||||
//! # async fn run() {
|
||||
//! use std::env::temp_dir;
|
||||
//! use lettre::{AsyncStd1Transport, Envelope, Message, FileTransport};
|
||||
//!
|
||||
//! // Write to the local temp directory
|
||||
//! let sender = FileTransport::new(temp_dir());
|
||||
//! let email = Message::builder()
|
||||
//! .from("NoBody <nobody@domain.tld>".parse().unwrap())
|
||||
//! .reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
|
||||
//! .to("Hei <hei@domain.tld>".parse().unwrap())
|
||||
//! .subject("Happy new year")
|
||||
//! .body("Be happy!")
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let result = sender.send(email).await;
|
||||
//! assert!(result.is_ok());
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ---
|
||||
//!
|
||||
//! Example result
|
||||
//!
|
||||
//! ```json
|
||||
//! TODO
|
||||
//! {
|
||||
//! "envelope": {
|
||||
//! "forward_path": [
|
||||
//! "hei@domain.tld"
|
||||
//! ],
|
||||
//! "reverse_path": "nobody@domain.tld"
|
||||
//! },
|
||||
//! "raw_message": null,
|
||||
//! "message": "From: NoBody <nobody@domain.tld>\r\nReply-To: Yuin <yuin@domain.tld>\r\nTo: Hei <hei@domain.tld>\r\nSubject: Happy new year\r\nDate: Tue, 18 Aug 2020 22:50:17 GMT\r\n\r\nBe happy!"
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
pub use self::error::Error;
|
||||
#[cfg(feature = "async-std1")]
|
||||
use crate::AsyncStd1Transport;
|
||||
#[cfg(feature = "tokio02")]
|
||||
use crate::Tokio02Transport;
|
||||
use crate::{transport::file::error::Error, Envelope, Transport};
|
||||
use crate::{Envelope, Transport};
|
||||
#[cfg(any(feature = "async-std1", feature = "tokio02"))]
|
||||
use async_trait::async_trait;
|
||||
use std::{
|
||||
@@ -48,7 +99,7 @@ use std::{
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub mod error;
|
||||
mod error;
|
||||
|
||||
type Id = String;
|
||||
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
//! The sendmail transport sends the email using the local sendmail command.
|
||||
//!
|
||||
//! #### Sendmail Transport
|
||||
//!
|
||||
//! The sendmail transport sends the email using the local sendmail command.
|
||||
//! ## Sync example
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! # #[cfg(feature = "sendmail-transport")]
|
||||
//! # {
|
||||
//! use lettre::{Message, Envelope, Transport, SendmailTransport};
|
||||
//!
|
||||
//! let email = Message::builder()
|
||||
@@ -20,14 +16,56 @@
|
||||
//! let sender = SendmailTransport::new();
|
||||
//! let result = sender.send(&email);
|
||||
//! assert!(result.is_ok());
|
||||
//! ```
|
||||
//!
|
||||
//! ## Async tokio 0.2 example
|
||||
//!
|
||||
//!```rust,no_run
|
||||
//! # #[cfg(feature = "tokio02")]
|
||||
//! # async fn run() {
|
||||
//! use lettre::{Message, Envelope, Tokio02Transport, SendmailTransport};
|
||||
//!
|
||||
//! let email = Message::builder()
|
||||
//! .from("NoBody <nobody@domain.tld>".parse().unwrap())
|
||||
//! .reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
|
||||
//! .to("Hei <hei@domain.tld>".parse().unwrap())
|
||||
//! .subject("Happy new year")
|
||||
//! .body("Be happy!")
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let sender = SendmailTransport::new();
|
||||
//! let result = sender.send(email).await;
|
||||
//! assert!(result.is_ok());
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Async async-std 1.x example
|
||||
//!
|
||||
//!```rust,no_run
|
||||
//! # #[cfg(feature = "async-std1")]
|
||||
//! # async fn run() {
|
||||
//! use lettre::{Message, Envelope, AsyncStd1Transport, SendmailTransport};
|
||||
//!
|
||||
//! let email = Message::builder()
|
||||
//! .from("NoBody <nobody@domain.tld>".parse().unwrap())
|
||||
//! .reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
|
||||
//! .to("Hei <hei@domain.tld>".parse().unwrap())
|
||||
//! .subject("Happy new year")
|
||||
//! .body("Be happy!")
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let sender = SendmailTransport::new();
|
||||
//! let result = sender.send(email).await;
|
||||
//! assert!(result.is_ok());
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
pub use self::error::Error;
|
||||
#[cfg(feature = "async-std1")]
|
||||
use crate::AsyncStd1Transport;
|
||||
#[cfg(feature = "tokio02")]
|
||||
use crate::Tokio02Transport;
|
||||
use crate::{transport::sendmail::error::Error, Envelope, Transport};
|
||||
use crate::{Envelope, Transport};
|
||||
#[cfg(any(feature = "async-std1", feature = "tokio02"))]
|
||||
use async_trait::async_trait;
|
||||
use std::{
|
||||
@@ -37,7 +75,7 @@ use std::{
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
|
||||
pub mod error;
|
||||
mod error;
|
||||
|
||||
const DEFAUT_SENDMAIL: &str = "/usr/sbin/sendmail";
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
//! It implements the following extensions:
|
||||
//!
|
||||
//! * 8BITMIME ([RFC 6152](https://tools.ietf.org/html/rfc6152))
|
||||
//! * AUTH ([RFC 4954](http://tools.ietf.org/html/rfc4954)) with PLAIN, LOGIN and XOAUTH2 mechanisms
|
||||
//! * STARTTLS ([RFC 2487](http://tools.ietf.org/html/rfc2487))
|
||||
//! * AUTH ([RFC 4954](https://tools.ietf.org/html/rfc4954)) with PLAIN, LOGIN and XOAUTH2 mechanisms
|
||||
//! * STARTTLS ([RFC 2487](https://tools.ietf.org/html/rfc2487))
|
||||
//!
|
||||
//! #### SMTP Transport
|
||||
//!
|
||||
@@ -17,12 +17,12 @@
|
||||
//!
|
||||
//! It is designed to be:
|
||||
//!
|
||||
//! * Secured: email are encrypted by default
|
||||
//! * Modern: unicode support for email content and sender/recipient addresses when compatible
|
||||
//! * Secured: emails are encrypted by default
|
||||
//! * Modern: unicode support for email contents and sender/recipient addresses when compatible
|
||||
//! * Fast: supports connection reuse and pooling
|
||||
//!
|
||||
//! This client is designed to send emails to a relay server, and should *not* be used to send
|
||||
//! emails directly to the destination.
|
||||
//! emails directly to the destination server.
|
||||
//!
|
||||
//! The relay server can be the local email server, a specific host or a third-party service.
|
||||
//!
|
||||
@@ -31,7 +31,7 @@
|
||||
//! This is the most basic example of usage:
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! # #[cfg(feature = "smtp-transport")]
|
||||
//! # #[cfg(any(feature = "native-tls", feature = "rustls-tls"))]
|
||||
//! # {
|
||||
//! use lettre::{Message, Transport, SmtpTransport};
|
||||
//!
|
||||
@@ -43,138 +43,15 @@
|
||||
//! .body("Be happy!")
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! // Create local transport on port 25
|
||||
//! let sender = SmtpTransport::unencrypted_localhost();
|
||||
//! // Send the email on local relay
|
||||
//! // Create TLS transport on port 465
|
||||
//! let sender = SmtpTransport::relay("smtp.example.com")
|
||||
//! .expect("relay valid")
|
||||
//! .build();
|
||||
//! // Send the email via remote relay
|
||||
//! let result = sender.send(&email);
|
||||
//!
|
||||
//! assert!(result.is_ok());
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! #### Complete example
|
||||
//!
|
||||
//! ```todo
|
||||
//! # #[cfg(feature = "smtp-transport")]
|
||||
//! # {
|
||||
//! use lettre::transport::smtp::authentication::{Credentials, Mechanism};
|
||||
//! use lettre::{Email, Envelope, Transport, SmtpClient};
|
||||
//! use lettre::transport::smtp::extension::ClientId;
|
||||
//!
|
||||
//! let email_1 = Email::new(
|
||||
//! Envelope::new(
|
||||
//! Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
|
||||
//! vec![EmailAddress::new("root@localhost".to_string()).unwrap()],
|
||||
//! ).unwrap(),
|
||||
//! "id1".to_string(),
|
||||
//! "Hello world".to_string().into_bytes(),
|
||||
//! );
|
||||
//!
|
||||
//! let email_2 = Email::new(
|
||||
//! Envelope::new(
|
||||
//! Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
|
||||
//! vec![EmailAddress::new("root@localhost".to_string()).unwrap()],
|
||||
//! ).unwrap(),
|
||||
//! "id2".to_string(),
|
||||
//! "Hello world a second time".to_string().into_bytes(),
|
||||
//! );
|
||||
//!
|
||||
//! // Connect to a remote server on a custom port
|
||||
//! let mut mailer = SmtpClient::new_simple("server.tld").unwrap()
|
||||
//! // Set the name sent during EHLO/HELO, default is `localhost`
|
||||
//! .hello_name(ClientId::Domain("my.hostname.tld".to_string()))
|
||||
//! // Add credentials for authentication
|
||||
//! .credentials(Credentials::new("username".to_string(), "password".to_string()))
|
||||
//! // Enable SMTPUTF8 if the server supports it
|
||||
//! .smtp_utf8(true)
|
||||
//! // Configure expected authentication mechanism
|
||||
//! .authentication_mechanism(Mechanism::Plain)
|
||||
//! // Enable connection reuse
|
||||
//! .connection_reuse(ConnectionReuseParameters::ReuseUnlimited).transport();
|
||||
//!
|
||||
//! let result_1 = mailer.send(&email_1);
|
||||
//! assert!(result_1.is_ok());
|
||||
//!
|
||||
//! // The second email will use the same connection
|
||||
//! let result_2 = mailer.send(&email_2);
|
||||
//! assert!(result_2.is_ok());
|
||||
//!
|
||||
//! // Explicitly close the SMTP transaction as we enabled connection reuse
|
||||
//! mailer.close();
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! You can specify custom TLS settings:
|
||||
//!
|
||||
//! ```todo
|
||||
//! # #[cfg(feature = "native-tls")]
|
||||
//! # {
|
||||
//! use lettre::{
|
||||
//! ClientSecurity, ClientTlsParameters, EmailAddress, Envelope,
|
||||
//! Email, SmtpClient, Transport,
|
||||
//! };
|
||||
//! use lettre::transport::smtp::authentication::{Credentials, Mechanism};
|
||||
//! use lettre::transport::smtp::ConnectionReuseParameters;
|
||||
//! use native_tls::{Protocol, TlsConnector};
|
||||
//!
|
||||
//! let email = Email::new(
|
||||
//! Envelope::new(
|
||||
//! Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
|
||||
//! vec![EmailAddress::new("root@localhost".to_string()).unwrap()],
|
||||
//! ).unwrap(),
|
||||
//! "message_id".to_string(),
|
||||
//! "Hello world".to_string().into_bytes(),
|
||||
//! );
|
||||
//!
|
||||
//! let mut tls_builder = TlsConnector::builder();
|
||||
//! tls_builder.min_protocol_version(Some(Protocol::Tlsv10));
|
||||
//! let tls_parameters =
|
||||
//! ClientTlsParameters::new(
|
||||
//! "smtp.example.com".to_string(),
|
||||
//! tls_builder.build().unwrap()
|
||||
//! );
|
||||
//!
|
||||
//! let mut mailer = SmtpClient::new(
|
||||
//! ("smtp.example.com", 465), ClientSecurity::Wrapper(tls_parameters)
|
||||
//! ).unwrap()
|
||||
//! .authentication_mechanism(Mechanism::Login)
|
||||
//! .credentials(Credentials::new(
|
||||
//! "example_username".to_string(), "example_password".to_string()
|
||||
//! ))
|
||||
//! .connection_reuse(ConnectionReuseParameters::ReuseUnlimited)
|
||||
//! .transport();
|
||||
//!
|
||||
//! let result = mailer.send(&email);
|
||||
//!
|
||||
//! assert!(result.is_ok());
|
||||
//!
|
||||
//! mailer.close();
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! #### Lower level
|
||||
//!
|
||||
//! You can also send commands, here is a simple email transaction without
|
||||
//! error handling:
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! # #[cfg(feature = "smtp-transport")]
|
||||
//! # {
|
||||
//! use lettre::transport::smtp::{SMTP_PORT, extension::ClientId, commands::*, client::SmtpConnection};
|
||||
//!
|
||||
//! let hello = ClientId::Domain("my_hostname".to_string());
|
||||
//! let mut client = SmtpConnection::connect(&("localhost", SMTP_PORT), None, &hello, None).unwrap();
|
||||
//! client.command(
|
||||
//! Mail::new(Some("user@example.com".parse().unwrap()), vec![])
|
||||
//! ).unwrap();
|
||||
//! client.command(
|
||||
//! Rcpt::new("user@example.org".parse().unwrap(), vec![])
|
||||
//! ).unwrap();
|
||||
//! client.command(Data).unwrap();
|
||||
//! client.message("Test email".as_bytes()).unwrap();
|
||||
//! client.command(Quit).unwrap();
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -189,7 +66,6 @@ use crate::transport::smtp::client::TlsParameters;
|
||||
use crate::transport::smtp::{
|
||||
authentication::{Credentials, Mechanism, DEFAULT_MECHANISMS},
|
||||
client::SmtpConnection,
|
||||
error::Error,
|
||||
extension::ClientId,
|
||||
response::Response,
|
||||
};
|
||||
@@ -200,7 +76,7 @@ mod async_transport;
|
||||
pub mod authentication;
|
||||
pub mod client;
|
||||
pub mod commands;
|
||||
pub mod error;
|
||||
mod error;
|
||||
pub mod extension;
|
||||
#[cfg(feature = "r2d2")]
|
||||
pub mod pool;
|
||||
|
||||
Reference in New Issue
Block a user