#![doc(html_root_url = "https://docs.rs/crate/lettre/0.11.9")]
#![doc(html_favicon_url = "https://lettre.rs/favicon.ico")]
#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/15113230?v=4")]
#![forbid(unsafe_code)]
#![deny(
missing_copy_implementations,
trivial_casts,
trivial_numeric_casts,
unstable_features,
unused_import_braces,
rust_2018_idioms,
clippy::string_add,
clippy::string_add_assign,
clippy::clone_on_ref_ptr,
clippy::verbose_file_reads,
clippy::unnecessary_self_imports,
clippy::string_to_string,
clippy::mem_forget,
clippy::cast_lossless,
clippy::inefficient_to_string,
clippy::inline_always,
clippy::linkedlist,
clippy::macro_use_imports,
clippy::manual_assert,
clippy::unnecessary_join,
clippy::wildcard_imports,
clippy::str_to_string,
clippy::empty_structs_with_brackets,
clippy::zero_sized_map_values
)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(not(lettre_ignore_tls_mismatch))]
mod compiletime_checks {
#[cfg(all(feature = "native-tls", feature = "boring-tls"))]
compile_error!("feature \"native-tls\" and feature \"boring-tls\" cannot be enabled at the same time, otherwise
the executable will fail to link.");
#[cfg(all(
feature = "tokio1",
feature = "native-tls",
not(feature = "tokio1-native-tls")
))]
compile_error!("Lettre is being built with the `tokio1` and the `native-tls` features, but the `tokio1-native-tls` feature hasn't been turned on.
If you were trying to opt into `rustls-tls` and did not activate `native-tls`, disable the default-features of lettre in `Cargo.toml` and manually add the required features.
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
#[cfg(all(
feature = "tokio1",
feature = "rustls-tls",
not(feature = "tokio1-rustls-tls")
))]
compile_error!("Lettre is being built with the `tokio1` and the `rustls-tls` features, but the `tokio1-rustls-tls` feature hasn't been turned on.
If you'd like to use `native-tls` make sure that the `rustls-tls` feature hasn't been enabled by mistake.
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
#[cfg(all(
feature = "tokio1",
feature = "boring-tls",
not(feature = "tokio1-boring-tls")
))]
compile_error!("Lettre is being built with the `tokio1` and the `boring-tls` features, but the `tokio1-boring-tls` feature hasn't been turned on.
If you'd like to use `boring-tls` make sure that the `rustls-tls` feature hasn't been enabled by mistake.
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
#[cfg(all(feature = "async-std1", feature = "native-tls",))]
compile_error!("Lettre is being built with the `async-std1` and the `native-tls` features, but the async-std integration doesn't support native-tls yet.
If you'd like to work on the issue please take a look at https://github.com/lettre/lettre/issues/576.
If you were trying to opt into `rustls-tls` and did not activate `native-tls`, disable the default-features of lettre in `Cargo.toml` and manually add the required features.
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
#[cfg(all(
feature = "async-std1",
feature = "rustls-tls",
not(feature = "async-std1-rustls-tls")
))]
compile_error!("Lettre is being built with the `async-std1` and the `rustls-tls` features, but the `async-std1-rustls-tls` feature hasn't been turned on.
If you'd like to use `native-tls` make sure that the `rustls-tls` hasn't been enabled by mistake.
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
}
pub mod address;
#[cfg(any(feature = "smtp-transport", feature = "dkim"))]
mod base64;
pub mod error;
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
mod executor;
#[cfg(feature = "builder")]
#[cfg_attr(docsrs, doc(cfg(feature = "builder")))]
pub mod message;
pub mod transport;
use std::error::Error as StdError;
#[cfg(feature = "async-std1")]
pub use self::executor::AsyncStd1Executor;
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
pub use self::executor::Executor;
#[cfg(feature = "tokio1")]
pub use self::executor::Tokio1Executor;
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
#[doc(inline)]
pub use self::transport::AsyncTransport;
pub use crate::address::Address;
#[cfg(feature = "builder")]
#[doc(inline)]
pub use crate::message::Message;
#[cfg(all(
feature = "file-transport",
any(feature = "tokio1", feature = "async-std1")
))]
#[doc(inline)]
pub use crate::transport::file::AsyncFileTransport;
#[cfg(feature = "file-transport")]
#[doc(inline)]
pub use crate::transport::file::FileTransport;
#[cfg(all(
feature = "sendmail-transport",
any(feature = "tokio1", feature = "async-std1")
))]
#[doc(inline)]
pub use crate::transport::sendmail::AsyncSendmailTransport;
#[cfg(feature = "sendmail-transport")]
#[doc(inline)]
pub use crate::transport::sendmail::SendmailTransport;
#[cfg(all(
feature = "smtp-transport",
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};
pub(crate) type BoxError = Box<dyn StdError + Send + Sync>;
#[cfg(test)]
#[cfg(feature = "builder")]
mod test {
use super::*;
use crate::message::{header, header::Headers, Mailbox, Mailboxes};
#[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 headers = Headers::new();
headers.set(header::From(from));
headers.set(header::To(to));
assert_eq!(
Envelope::try_from(&headers).unwrap(),
Envelope::new(
Some(Address::new("kayo", "example.com").unwrap()),
vec![Address::new("amousset", "example.com").unwrap()]
)
.unwrap()
);
}
#[test]
fn envelope_from_headers_sender() {
let from = Mailboxes::new().with("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 headers = Headers::new();
headers.set(header::From::from(from));
headers.set(header::Sender::from(sender));
headers.set(header::To::from(to));
assert_eq!(
Envelope::try_from(&headers).unwrap(),
Envelope::new(
Some(Address::new("kayo2", "example.com").unwrap()),
vec![Address::new("amousset", "example.com").unwrap()]
)
.unwrap()
);
}
#[test]
fn envelope_from_headers_no_to() {
let from = Mailboxes::new().with("kayo@example.com".parse().unwrap());
let sender = Mailbox::new(None, "kayo2@example.com".parse().unwrap());
let mut headers = Headers::new();
headers.set(header::From::from(from));
headers.set(header::Sender::from(sender));
assert!(Envelope::try_from(&headers).is_err(),);
}
}