fix(all): Fix doc tests in website (#375)
This commit is contained in:
7
.github/workflows/test.yml
vendored
7
.github/workflows/test.yml
vendored
@@ -24,7 +24,8 @@ jobs:
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: --no-default-features --features=native-tls
|
||||
args: --no-default-features --features=native-tls,builder,r2d2,smtp-transport,file-transport,sendmail-transport
|
||||
- run: rm target/debug/deps/liblettre-*
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
@@ -85,8 +86,8 @@ jobs:
|
||||
command: test
|
||||
args: --no-fail-fast
|
||||
env:
|
||||
CARGO_INCREMENTAL: '0'
|
||||
RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads'
|
||||
CARGO_INCREMENTAL: "0"
|
||||
RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads"
|
||||
- id: coverage
|
||||
uses: actions-rs/grcov@v0.1
|
||||
- name: Coveralls upload
|
||||
|
||||
@@ -38,6 +38,7 @@ webpki = { version = "^0.21", optional = true }
|
||||
criterion = "^0.3"
|
||||
env_logger = "^0.7"
|
||||
glob = "^0.3"
|
||||
walkdir = "^2"
|
||||
|
||||
[[bench]]
|
||||
harness = false
|
||||
@@ -46,12 +47,11 @@ name = "transport_smtp"
|
||||
[features]
|
||||
builder = ["email", "mime", "time", "base64", "uuid"]
|
||||
connection-pool = ["r2d2"]
|
||||
default = ["file-transport", "smtp-transport", "sendmail-transport", "ssl-rustls", "builder"]
|
||||
default = ["file-transport", "smtp-transport", "sendmail-transport", "rustls-tls", "builder"]
|
||||
file-transport = ["serde", "serde_json"]
|
||||
rustls-tls = ["webpki", "rustls"]
|
||||
sendmail-transport = []
|
||||
smtp-transport = ["bufstream", "base64", "nom", "hostname"]
|
||||
ssl-native = ["native-tls"]
|
||||
ssl-rustls = ["rustls", "webpki"]
|
||||
unstable = []
|
||||
|
||||
[[example]]
|
||||
|
||||
@@ -44,7 +44,7 @@ lettre = "0.9"
|
||||
```rust,no_run
|
||||
extern crate lettre;
|
||||
|
||||
use lettre::{SmtpClient, Transport, Email, mime::TEXT_PLAIN};
|
||||
use lettre::{SmtpClient, Transport, Email, builder::mime::TEXT_PLAIN};
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::{error::Error as LettreError, EmailAddress, Envelope, SendableEmail};
|
||||
pub use email::{Address, Header, Mailbox, MimeMessage, MimeMultipartType};
|
||||
use error::Error;
|
||||
pub use mime;
|
||||
use mime::Mime;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
|
||||
@@ -24,6 +24,8 @@ pub mod sendmail;
|
||||
pub mod smtp;
|
||||
pub mod stub;
|
||||
|
||||
#[cfg(feature = "builder")]
|
||||
pub use crate::builder::Email;
|
||||
use crate::error::EmailResult;
|
||||
use crate::error::Error;
|
||||
#[cfg(feature = "file-transport")]
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
use crate::smtp::client::mock::MockStream;
|
||||
use crate::smtp::error::Error;
|
||||
#[cfg(feature = "native-tls")]
|
||||
use native_tls::{Protocol, TlsConnector, TlsStream};
|
||||
use native_tls::{TlsConnector, TlsStream};
|
||||
#[cfg(feature = "rustls")]
|
||||
use rustls::{ClientConfig, ClientSession};
|
||||
#[cfg(feature = "native-tls")]
|
||||
use std::io::ErrorKind;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::net::{Ipv4Addr, Shutdown, SocketAddr, SocketAddrV4, TcpStream};
|
||||
#[cfg(feature = "rustls")]
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -45,12 +46,6 @@ impl ClientTlsParameters {
|
||||
}
|
||||
}
|
||||
|
||||
/// Accepted protocols by default.
|
||||
/// This removes TLS 1.0 and 1.1 compared to tls-native defaults.
|
||||
/// This is also rustls' default behavior
|
||||
#[cfg(feature = "native-tls")]
|
||||
const DEFAULT_TLS_MIN_PROTOCOL: Protocol = Protocol::Tlsv12;
|
||||
|
||||
/// Represents the different types of underlying network streams
|
||||
pub enum NetworkStream {
|
||||
/// Plain TCP stream
|
||||
@@ -161,7 +156,7 @@ impl Connector for NetworkStream {
|
||||
.connector
|
||||
.connect(context.domain.as_ref(), tcp_stream)
|
||||
.map(|tls| NetworkStream::Tls(Box::new(tls)))
|
||||
.map_err(|e| io::Error::new(ErrorKind::Other, e)),
|
||||
.map_err(|e| Error::Io(io::Error::new(ErrorKind::Other, e))),
|
||||
#[cfg(feature = "rustls")]
|
||||
Some(context) => {
|
||||
let domain = webpki::DNSNameRef::try_from_ascii_str(&context.domain)?;
|
||||
@@ -183,7 +178,7 @@ impl Connector for NetworkStream {
|
||||
.connect(tls_parameters.domain.as_ref(), stream.try_clone().unwrap())
|
||||
{
|
||||
Ok(tls_stream) => NetworkStream::Tls(Box::new(tls_stream)),
|
||||
Err(err) => return Err(io::Error::new(ErrorKind::Other, err)),
|
||||
Err(err) => return Err(Error::Io(io::Error::new(ErrorKind::Other, err))),
|
||||
},
|
||||
#[cfg(feature = "rustls")]
|
||||
NetworkStream::Tcp(ref mut stream) => {
|
||||
|
||||
@@ -41,6 +41,7 @@ pub enum Error {
|
||||
/// Parsing error
|
||||
Parsing(nom::error::ErrorKind),
|
||||
/// Invalid hostname
|
||||
#[cfg(feature = "rustls-tls")]
|
||||
InvalidDNSName(webpki::InvalidDNSNameError),
|
||||
}
|
||||
|
||||
@@ -73,6 +74,7 @@ impl StdError for Error {
|
||||
#[cfg(feature = "native-tls")]
|
||||
Tls(ref err) => err.description(),
|
||||
Parsing(ref err) => err.description(),
|
||||
#[cfg(feature = "rustls-tls")]
|
||||
InvalidDNSName(ref err) => err.description(),
|
||||
}
|
||||
}
|
||||
@@ -124,6 +126,7 @@ impl From<FromUtf8Error> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls-tls")]
|
||||
impl From<webpki::InvalidDNSNameError> for Error {
|
||||
fn from(err: webpki::InvalidDNSNameError) -> Error {
|
||||
InvalidDNSName(err)
|
||||
|
||||
@@ -17,8 +17,6 @@ use crate::smtp::authentication::{
|
||||
Credentials, Mechanism, DEFAULT_ENCRYPTED_MECHANISMS, DEFAULT_UNENCRYPTED_MECHANISMS,
|
||||
};
|
||||
use crate::smtp::client::net::ClientTlsParameters;
|
||||
#[cfg(feature = "native-tls")]
|
||||
use crate::smtp::client::net::DEFAULT_TLS_MIN_PROTOCOL;
|
||||
use crate::smtp::client::InnerClient;
|
||||
use crate::smtp::commands::*;
|
||||
use crate::smtp::error::{Error, SmtpResult};
|
||||
@@ -26,7 +24,9 @@ use crate::smtp::extension::{ClientId, Extension, MailBodyParameter, MailParamet
|
||||
use crate::{SendableEmail, Transport};
|
||||
use log::{debug, info};
|
||||
#[cfg(feature = "native-tls")]
|
||||
use native_tls::TlsConnector;
|
||||
use native_tls::{Protocol, TlsConnector};
|
||||
#[cfg(feature = "rustls")]
|
||||
use rustls::ClientConfig;
|
||||
use std::net::{SocketAddr, ToSocketAddrs};
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -51,6 +51,12 @@ pub const SUBMISSION_PORT: u16 = 587;
|
||||
/// Default submission over TLS port
|
||||
pub const SUBMISSIONS_PORT: u16 = 465;
|
||||
|
||||
/// Accepted protocols by default.
|
||||
/// This removes TLS 1.0 and 1.1 compared to tls-native defaults.
|
||||
/// This is also rustls' default behavior
|
||||
#[cfg(feature = "native-tls")]
|
||||
const DEFAULT_TLS_MIN_PROTOCOL: Protocol = Protocol::Tlsv12;
|
||||
|
||||
/// How to apply TLS to a client connection
|
||||
#[derive(Clone)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
@@ -150,6 +156,16 @@ impl SmtpClient {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
pub fn new_simple(domain: &str) -> Result<SmtpClient, Error> {
|
||||
let tls_parameters = ClientTlsParameters::new(domain.to_string(), ClientConfig::new());
|
||||
|
||||
SmtpClient::new(
|
||||
(domain, SUBMISSIONS_PORT),
|
||||
ClientSecurity::Wrapper(tls_parameters),
|
||||
)
|
||||
}
|
||||
|
||||
/// Creates a new local SMTP client to port 25
|
||||
pub fn new_unencrypted_localhost() -> Result<SmtpClient, Error> {
|
||||
SmtpClient::new(("localhost", SMTP_PORT), ClientSecurity::None)
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
use glob::glob;
|
||||
use std::env;
|
||||
use std::env::consts::EXE_EXTENSION;
|
||||
use std::env::{self, consts::EXE_EXTENSION};
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
#[test]
|
||||
fn book_test() {
|
||||
let mut book_path = env::current_dir().unwrap();
|
||||
book_path.push(
|
||||
Path::new(file!())
|
||||
.parent()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("../website/content/sending-messages"),
|
||||
); // For some reasons, calling .parent() once more gives us None...
|
||||
skeptic_test(Path::new("README.md"));
|
||||
|
||||
for md in glob(&format!("{}/*.md", book_path.to_str().unwrap())).unwrap() {
|
||||
skeptic_test(&md.unwrap());
|
||||
for entry in WalkDir::new("website").into_iter().filter(|e| {
|
||||
e.as_ref()
|
||||
.unwrap()
|
||||
.path()
|
||||
.extension()
|
||||
.map(|ex| ex == "md")
|
||||
.unwrap_or(false)
|
||||
}) {
|
||||
skeptic_test(entry.unwrap().path());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,11 @@ The `email` part builds email messages. For now, it does not support attachments
|
||||
An email is built using an `EmailBuilder`. The simplest email could be:
|
||||
|
||||
```rust
|
||||
extern crate lettre_email;
|
||||
# #[cfg(feature = "builder")]
|
||||
# {
|
||||
extern crate lettre;
|
||||
|
||||
use lettre_email::Email;
|
||||
use lettre::Email;
|
||||
|
||||
fn main() {
|
||||
// Create an email
|
||||
@@ -25,6 +27,7 @@ fn main() {
|
||||
|
||||
assert!(email.is_ok());
|
||||
}
|
||||
# }
|
||||
```
|
||||
|
||||
When the `build` method is called, the `EmailBuilder` will add the missing headers (like
|
||||
|
||||
@@ -5,6 +5,8 @@ The file transport writes the emails to the given directory. The name of the fil
|
||||
It can be useful for testing purposes, or if you want to keep track of sent messages.
|
||||
|
||||
```rust
|
||||
# #[cfg(feature = "file-transport")]
|
||||
# {
|
||||
extern crate lettre;
|
||||
|
||||
use std::env::temp_dir;
|
||||
@@ -27,6 +29,7 @@ fn main() {
|
||||
let result = sender.send(email);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
# }
|
||||
```
|
||||
|
||||
Example result in `/tmp/b7c211bc-9811-45ce-8cd9-68eab575d695.txt`:
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
The sendmail transport sends the email using the local sendmail command.
|
||||
|
||||
```rust,no_run
|
||||
# #[cfg(feature = "sendmail-transport")]
|
||||
# {
|
||||
extern crate lettre;
|
||||
|
||||
use lettre::sendmail::SendmailTransport;
|
||||
@@ -22,4 +24,5 @@ fn main() {
|
||||
let result = sender.send(email);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
# }
|
||||
```
|
||||
|
||||
@@ -18,6 +18,8 @@ The relay server can be the local email server, a specific host or a third-party
|
||||
This is the most basic example of usage:
|
||||
|
||||
```rust,no_run
|
||||
# #[cfg(feature = "smtp-transport")]
|
||||
# {
|
||||
extern crate lettre;
|
||||
|
||||
use lettre::{SendableEmail, EmailAddress, Transport, Envelope, SmtpClient};
|
||||
@@ -40,11 +42,14 @@ fn main() {
|
||||
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
# }
|
||||
```
|
||||
|
||||
#### Complete example
|
||||
|
||||
```rust,no_run
|
||||
# #[cfg(feature = "smtp-transport")]
|
||||
# {
|
||||
extern crate lettre;
|
||||
|
||||
use lettre::smtp::authentication::{Credentials, Mechanism};
|
||||
@@ -94,11 +99,14 @@ fn main() {
|
||||
// Explicitly close the SMTP transaction as we enabled connection reuse
|
||||
mailer.close();
|
||||
}
|
||||
# }
|
||||
```
|
||||
|
||||
You can specify custom TLS settings:
|
||||
|
||||
```rust,no_run
|
||||
# #[cfg(feature = "native-tls")]
|
||||
# {
|
||||
extern crate native_tls;
|
||||
extern crate lettre;
|
||||
|
||||
@@ -144,6 +152,7 @@ fn main() {
|
||||
|
||||
mailer.close();
|
||||
}
|
||||
# }
|
||||
```
|
||||
|
||||
#### Lower level
|
||||
@@ -152,6 +161,8 @@ You can also send commands, here is a simple email transaction without
|
||||
error handling:
|
||||
|
||||
```rust,no_run
|
||||
# #[cfg(feature = "smtp-transport")]
|
||||
# {
|
||||
extern crate lettre;
|
||||
|
||||
use lettre::EmailAddress;
|
||||
@@ -175,5 +186,5 @@ fn main() {
|
||||
let _ = email_client.message(Box::new("Test email".as_bytes()));
|
||||
let _ = email_client.command(QuitCommand);
|
||||
}
|
||||
# }
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user