### Install rustls-graviola crypto provider Source: https://docs.rs/lettre/latest/index.html Example of installing a custom rustls crypto provider, specifically rustls-graviola. Ensure the provider is installed before using lettre. Refer to the provider's documentation for specific setup instructions. ```rust rustls_graviola::default_provider() .install_default() .expect("Failed to install crypto provider"); ``` -------------------------------- ### Trim Start Example (Hebrew) Source: https://docs.rs/lettre/latest/lettre/message/header/struct.HeaderName.html Demonstrates trimming leading whitespace from a string containing Hebrew characters. ```rust let s = " עברית "; assert!(Some('ע') == s.trim_start().chars().next()); ``` -------------------------------- ### DKIM Signing Example Source: https://docs.rs/lettre/latest/src/lettre/message/mod.rs.html Demonstrates how to build an email message and prepare it for DKIM signing. This example includes setting sender, recipient, subject, content type, and body, then proceeds to sign it. ```rust let mut message = Message::builder() .from("Alice ".parse().unwrap()) .reply_to("Bob ".parse().unwrap()) .to("Carla ".parse().unwrap()) .subject("Hello") .header(ContentType::TEXT_PLAIN) .body("Hi there, it's a test email, with utf-8 chars ë!\n\n\n".to_owned()) .unwrap(); let key = "-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAt2gawjoybf0mAz0mSX0cq1ah5F9cPazZdCwLnFBhRufxaZB8 NLTdc9xfPIOK8l/xGrN7Nd63J4cTATqZukumczkA46O8YKHwa53pNT6NYwCNtDUL eBu+7xUW18GmDzkIFkxGO2R5kkTeWPlKvKpEiicIMfl0OmyW/fI3AbtM7e/gmqQ4 kEYIO0mTjPT+jTgWE4JIi5KUTHudUBtfMKcSFyM2HkUOExl1c9+A4epjRFQwEXMA hM5GrqZoOdUm4fIpvGpLIGIxFgHPpZYbyq6yJZzH3+5aKyCHrsHawPuPiCD45zsU re31zCE6b6k1sDiiBR4CaRHnbL7hxFp0aNLOVQIDAQABAoIBAGMK3gBrKxaIcUGo" ``` -------------------------------- ### Mailbox::new Example Source: https://docs.rs/lettre/latest/lettre/message/struct.Mailbox.html Provides an example of using the `Mailbox::new` constructor with `use` statements for Address and Mailbox. Requires the `builder` feature. ```rust use lettre::{Address, message::Mailbox}; let address = Address::new("example", "email.com")?; let mailbox = Mailbox::new(None, address); ``` -------------------------------- ### Async Tokio 1.x Sendmail Transport Example Source: https://docs.rs/lettre/latest/lettre/transport/sendmail/index.html This example demonstrates asynchronous email sending using Sendmail with the Tokio 1.x runtime. It requires the 'sendmail-transport' feature. ```rust use lettre::{ AsyncSendmailTransport, AsyncTransport, Message, SendmailTransport, Tokio1Executor, message::header::ContentType, }; let email = Message::builder() .from("NoBody ".parse()?) .reply_to("Yuin ".parse()?) .to("Hei ".parse()?) .subject("Happy new year") .header(ContentType::TEXT_PLAIN) .body(String::from("Be happy!"))?; let sender = AsyncSendmailTransport::::new(); sender.send(email).await?; ``` -------------------------------- ### Example of trim_start_matches with a character slice Source: https://docs.rs/lettre/latest/lettre/message/header/struct.HeaderName.html Demonstrates how to use `trim_start_matches` with a slice of characters to remove leading characters. ```rust let x: &[_] = &['1', '2']; assert_eq!("12foo1bar12".trim_start_matches(x), "foo1bar12"); ``` -------------------------------- ### DKIM Signing Example Source: https://docs.rs/lettre/latest/lettre/struct.Message.html Demonstrates how to build an email message and sign it using DKIM. Requires the 'builder' and 'dkim' features. ```rust use lettre::{ Message, message::{ dkim::{DkimConfig, DkimSigningAlgorithm, DkimSigningKey}, header::ContentType, }, }; let mut message = Message::builder() .from("Alice ".parse().unwrap()) .reply_to("Bob ".parse().unwrap()) .to("Carla ".parse().unwrap()) .subject("Hello") .header(ContentType::TEXT_PLAIN) .body("Hi there, it's a test email, with utf-8 chars ë!\n\n\n".to_owned()) .unwrap(); let key = "-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAt2gawjoybf0mAz0mSX0cq1ah5F9cPazZdCwLnFBhRufxaZB8 NLTdc9xfPIOK8l/xGrN7Nd63J4cTATqZukumczkA46O8YKHwa53pNT6NYwCNtDUL eBu+7xUW18GmDzkIFkxGO2R5kkTeWPlKvKpEiicIMfl0OmyW/fI3AbtM7e/gmqQ4 kEYIO0mTjPT+jTgWE4JIi5KUTHudUBtfMKcSFyM2HkUOExl1c9+A4epjRFQwEXMA hM5GrqZoOdUm4fIpvGpLIGIxFgHPpZYbyq6yJZzH3+5aKyCHrsHawPuPiCD45zsU re31zCE6b6k1sDiiBR4CaRHnbL7hxFp0aNLOVQIDAQABAoIBAGMK3gBrKxaIcUGo gQeIf7XrJ6vK72YC9L8uleqI4a9Hy++E7f4MedZ6eBeWta8jrnEL4Yp6xg+beuDc A24+Mhng+6Dyp+TLLqj+8pQlPnbrMprRVms7GIXFrrs+wO1RkBNyhy7FmH0roaMM pJZzoGW2pE9QdbqjL3rdlWTi/60xRX9eZ42nNxYnbc+RK03SBd46c3UBha6Y9iQX 562yWilDnB5WCX2tBoSN39bEhJvuZDzMwOuGw68Q96Hdz82Iz1xVBnRhH+uNStjR VnAssSHVxPSpwWrm3sHlhjBHWPnNIaOKIKl1lbL+qWfVQCj/6a5DquC+vYAeYR6L 3mA0z0ECgYEA5YkNYcILSXyE0hZ8eA/t58h8eWvYI5iqt3nT4fznCoYJJ74Vukeg 6BTlq/CsanwT1lDtvDKrOaJbA7DPTES/bqT0HoeIdOvAw9w/AZI5DAqYp61i6RMK xfAQL/Ik5MDFN8gEMLLXRVMe/aR27f6JFZpShJOK/KCzHqikKfYVJ+UCgYEAzI2F ZlTyittWSyUSl5UKyfSnFOx2+6vNy+lu5DeMJu8Wh9rqBk388Bxq98CfkCseWESN pTCGdYltz9DvVNBdBLwSMdLuYJAI6U+Zd70MWyuNdHFPyWVHUNqMUBvbUtj2w74q Hzu0GI0OrRjdX6C63S17PggmT/N2R9X7P4STxbECgYA+AZAD4I98Ao8+0aQ+Ks9x 1c8KXf+9XfiAKAD9A3zGcv72JXtpHwBwsXR5xkJNYcdaFfKi7G0k3J8JmDHnwIqW MSlhNeu+6hDg2BaNLhsLDbG/Wi9mFybJ4df9m8Qrp4efUgEPxsAwkgvFKTCXijMu CspP1iutoxvAJH50d22voQKBgDIsSFtIXNGYaTs3Va8enK3at5zXP3wNsQXiNRP/ V/44yNL77EktmewfXFF2yuym1uOZtRCerWxpEClYO0wXa6l8pA3aiiPfUIBByQfo s/4s2Z6FKKfikrKPWLlRi+NvWl+65kQQ9eTLvJzSq4IIP61+uWsGvrb/pbSLFPyI fWKRAoGBALFCStBXvdMptjq4APUzAdJ0vytZzXkOZHxgmc+R0fQn22OiW0huW6iX JcaBbL6ZSBIMA3AdaIjtvNRiomueHqh0GspTgOeCE2585TSFnw6vEOJ8RlR4A0Mw I45fbR4l+3D/30WMfZlM6bzZbwPXEnr2s1mirmuQpjumY9wLhK25 -----END RSA PRIVATE KEY----- as DkimSigningKey::new( key, DkimSigningAlgorithm::Rsa, ).unwrap(); message.sign(&DkimConfig::default_config( "dkimtest".to_owned(), "example.org".to_owned(), signing_key, )); println!( "message: {}", std::str::from_utf8(&message.formatted()).unwrap() ); ``` -------------------------------- ### Example of Creating a SinglePart Source: https://docs.rs/lettre/latest/src/lettre/message/mimebody.rs.html Demonstrates how to construct a `SinglePart` with a `ContentType` of `TEXT_PLAIN` and a Unicode string body using the `SinglePart::builder()`. ```rust let part = SinglePart::builder() .header(header::ContentType::TEXT_PLAIN) .body(String::from("Текст письма в уникоде")); ``` -------------------------------- ### Install Custom Rustls Crypto Provider Source: https://docs.rs/lettre/latest/src/lettre/lib.rs.html Demonstrates how to install a custom crypto provider for Rustls, such as rustls-graviola. This is necessary when the 'rustls-no-provider' feature is enabled. ```rust # mod rustls_graviola { # pub struct FakeProvider; # impl FakeProvider { # pub fn install_default(self) -> Result<(), String> { Ok(()) } # } # pub fn default_provider() -> FakeProvider { FakeProvider } # } // Example using the `rustls-graviola` crypto provider crate. // Refer to your provider's documentation for the correct setup. rustls_graviola::default_provider() .install_default() .expect("Failed to install crypto provider"); ``` -------------------------------- ### StubTransport Example Source: https://docs.rs/lettre/latest/src/lettre/transport/stub/mod.rs.html Demonstrates how to create and use the StubTransport to send an email and assert the logged message. Requires the 'builder' feature. ```rust use lettre::{ Message, Transport, message::header::ContentType, transport::stub::StubTransport, }; # use std::error::Error; # fn try_main() -> Result<(), Box> { let email = Message::builder() .from("NoBody ".parse()?) .reply_to("Yuin ".parse()?) .to("Hei ".parse()?) .subject("Happy new year") .header(ContentType::TEXT_PLAIN) .body(String::from("Be happy!"))?; let mut sender = StubTransport::new_ok(); sender.send(&email)?; assert_eq!( sender.messages(), vec![ (email.envelope().clone(), String::from_utf8(email.formatted()).unwrap()) ], ); # Ok(()) # } # try_main().unwrap(); ``` -------------------------------- ### Sync Sendmail Example Source: https://docs.rs/lettre/latest/src/lettre/transport/sendmail/mod.rs.html Demonstrates sending an email synchronously using the SendmailTransport. Ensure the 'sendmail-transport' and 'builder' features are enabled. ```rust use lettre::{Message, SendmailTransport, Transport, message::header::ContentType}; let email = Message::builder() .from("NoBody ".parse()?) .reply_to("Yuin ".parse()?) .to("Hei ".parse()?) .subject("Happy new year") .header(ContentType::TEXT_PLAIN) .body(String::from("Be happy!"))?; let sender = SendmailTransport::new(); sender.send(&email)?; ``` -------------------------------- ### Sync File Transport Example Source: https://docs.rs/lettre/latest/src/lettre/transport/file/mod.rs.html Demonstrates sending an email using the synchronous FileTransport, writing the message to the local temporary directory. ```rust use std::error::Error; #[cfg(all(feature = "file-transport", feature = "builder"))] fn main() -> Result<(), Box> { use std::env::temp_dir; use lettre::{FileTransport, Message, Transport, message::header::ContentType}; // Write to the local temp directory let sender = FileTransport::new(temp_dir()); let email = Message::builder() .from("NoBody ".parse()?) .reply_to("Yuin ".parse()?) .to("Hei ".parse()?) .subject("Happy new year") .header(ContentType::TEXT_PLAIN) .body(String::from("Be happy!"))?; sender.send(&email)?; Ok(()) } #[cfg(not(all(feature = "file-transport", feature = "builder")))] fn main() {} ``` -------------------------------- ### starts_with() Source: https://docs.rs/lettre/latest/lettre/message/header/struct.HeaderName.html Checks if the string slice starts with a given pattern. ```APIDOC ## starts_with() ### Description Returns `true` if the given pattern matches a prefix of this string slice, and `false` otherwise. The pattern can be a `&str`, `char`, a slice of `char`s, or a function or closure that determines if a character matches. ### Method `starts_with(pat)` ### Parameters - **pat**: The pattern to check for at the beginning of the string. Can be `&str`, `char`, `&[char]`, or a closure `Fn(char) -> bool`. ### Response - `bool`: `true` if the string starts with the pattern, `false` otherwise. ``` -------------------------------- ### Creating a Sender Header Source: https://docs.rs/lettre/latest/lettre/message/header/struct.Sender.html Example of how to create a Sender header using the header! macro with a Mailbox. This requires the 'builder' feature. ```rust header::Sender("Mr. Sender ".parse().unwrap()) ``` -------------------------------- ### Sync FileTransport Example Source: https://docs.rs/lettre/latest/lettre/transport/file/index.html Writes emails to the local temporary directory. Ensure the `file-transport` feature is enabled. ```rust use std::env::temp_dir; use lettre::{FileTransport, Message, Transport, message::header::ContentType}; // Write to the local temp directory let sender = FileTransport::new(temp_dir()); let email = Message::builder() .from("NoBody ".parse()?) .reply_to("Yuin ".parse()?) .to("Hei ".parse()?) .subject("Happy new year") .header(ContentType::TEXT_PLAIN) .body(String::from("Be happy!"))?; sender.send(&email)?; ``` -------------------------------- ### DKIM Signing Example Source: https://docs.rs/lettre/latest/lettre/message/struct.Message.html Demonstrates how to build an email message, sign it with DKIM using a provided private key, and then format it for SMTP. Requires `builder` and `dkim` features. ```rust use lettre::{ Message, message::{ dkim::{DkimConfig, DkimSigningAlgorithm, DkimSigningKey}, header::ContentType, }, }; let mut message = Message::builder() .from("Alice ".parse().unwrap()) .reply_to("Bob ".parse().unwrap()) .to("Carla ".parse().unwrap()) .subject("Hello") .header(ContentType::TEXT_PLAIN) .body("Hi there, it's a test email, with utf-8 chars ë!\n\n\n".to_owned()) .unwrap(); let key = "-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAt2gawjoybf0mAz0mSX0cq1ah5F9cPazZdCwLnFBhRufxaZB8 NLTdc9xfPIOK8l/xGrN7Nd63J4cTATqZukumczkA46O8YKHwa53pNT6NYwCNtDUL eBu+7xUW18GmDzkIFkxGO2R5kkTeWPlKvKpEiicIMfl0OmyW/fI3AbtM7e/gmqQ4 kEYIO0mTjPT+jTgWE4JIi5KUTHudUBtfMKcSFyM2HkUOExl1c9+A4epjRFQwEXMA hM5GrqZoOdUm4fIpvGpLIGIxFgHPpZYbyq6yJZzH3+5aKyCHrsHawPuPiCD45zsU re31zCE6b6k1sDiiBR4CaRHnbL7hxFp0aNLOVQIDAQABAoIBAGMK3gBrKxaIcUGo gQeIf7XrJ6vK72YC9L8uleqI4a9Hy++E7f4MedZ6eBeWta8jrnEL4Yp6xg+beuDc A24+Mhng+6Dyp+TLLqj+8pQlPnbrMprRVms7GIXFrrs+wO1RkBNyhy7FmH0roaMM pJZzoGW2pE9QdbqjL3rdlWTi/60xRX9eZ42nNxYnbc+RK03SBd46c3UBha6Y9iQX 562yWilDnB5WCX2tBoSN39bEhJvuZDzMwOuGw68Q96Hdz82Iz1xVBnRhH+uNStjR VnAssSHVxPSpwWrm3sHlhjBHWPnNIaOKIKl1lbL+qWfVQCj/6a5DquC+vYAeYR6L 3mA0z0ECgYEA5YkNYcILSXyE0hZ8eA/t58h8eWvYI5iqt3nT4fznCoYJJ74Vukeg 6BTlq/CsanwT1lDtvDKrOaJbA7DPTES/bqT0HoeIdOvAw9w/AZI5DAqYp61i6RMK xfAQL/Ik5MDFN8gEMLLXRVMe/aR27f6JFZpShJOK/KCzHqikKfYVJ+UCgYEAzI2F ZlTyittWSyUSl5UKyfSnFOx2+6vNy+lu5DeMJu8Wh9rqBk388Bxq98CfkCseWESN pTCGdYltz9DvVNBdBLwSMdLuYJAI6U+Zd70MWyuNdHFPyWVHUNqMUBvbUtj2w74q Hzu0GI0OrRjdX6C63S17PggmT/N2R9X7P4STxbECgYA+AZAD4I98Ao8+0aQ+Ks9x 1c8KXf+9XfiAKAD9A3zGcv72JXtpHwBwsXR5xkJNYcdaFfKi7G0k3J8JmDHnwIqW MSlhNeu+6hDg2BaNLhsLDbG/Wi9mFybJ4df9m8Qrp4efUgEPxsAwkgvFKTCXijMu CspP1iutoxvAJH50d22voQKBgDIsSFtIXNGYaTs3Va8enK3at5zXP3wNsQXiNRP/ V/44yNL77EktmewfXFF2yuym1uOZtRCerWxpEClYO0wXa6l8pA3aiiPfUIBByQfo s/4s2Z6FKKfikrKPWLlRi+NvWl+65kQQ9eTLvJzSq4IIP61+uWsGvrb/pbSLFPyI fWKRAoGBALFCStBXvdMptjq4APUzAdJ0vytZzXkOZHxgmc+R0fQn22OiW0huW6iX JcaBbL6ZSBIMA3AdaIjtvNRiomueHqh0GspTgOeCE2585TSFnw6vEOJ8RlR4A0Mw I45fbR4l+3D/30WMfZlM6bzZbwPXEnr2s1mirmuQpjumY9wLhK25 -----END RSA PRIVATE KEY----- ``` -------------------------------- ### Create an Address with validation Source: https://docs.rs/lettre/latest/lettre/address/struct.Address.html This example demonstrates creating an Address using the `new` method, which includes validation. It ensures the provided user and domain are in a valid format. ```rust use lettre::Address; let address = Address::new("user", "email.com")?; let expected = "user@email.com".parse::
()?; assert_eq!(expected, address); ``` -------------------------------- ### Slice Length Example Source: https://docs.rs/lettre/latest/lettre/message/enum.MaybeString.html Demonstrates how to get the number of elements in a slice. This is a fundamental operation for understanding the size of data structures. ```rust let a = [1, 2, 3]; assert_eq!(a.len(), 3); ``` -------------------------------- ### Trim ASCII Start Example Source: https://docs.rs/lettre/latest/lettre/message/enum.MaybeString.html Removes leading ASCII whitespace from a byte slice. Whitespace is defined by `u8::is_ascii_whitespace`, excluding the `\0x0B` byte. ```rust assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n"); assert_eq!(b" ".trim_ascii_start(), b""); assert_eq!(b"".trim_ascii_start(), b""); ``` -------------------------------- ### Getting the index of an element reference Source: https://docs.rs/lettre/latest/lettre/message/enum.MaybeString.html Use `element_offset` to find the index of a given element reference within a slice. Returns `None` if the reference is not aligned to an element's start. ```Rust let nums: &[u32] = &[1, 7, 1, 1]; let num = &nums[2]; assert_eq!(num, &1); assert_eq!(nums.element_offset(num), Some(2)); ``` ```Rust let arr: &[[u32; 2]] = &[[0, 1], [2, 3]]; let flat_arr: &[u32] = arr.as_flattened(); let ok_elm: &[u32; 2] = flat_arr[0..2].try_into().unwrap(); let weird_elm: &[u32; 2] = flat_arr[1..3].try_into().unwrap(); assert_eq!(ok_elm, &[0, 1]); assert_eq!(weird_elm, &[1, 2]); assert_eq!(arr.element_offset(ok_elm), Some(0)); // Points to element 0 assert_eq!(arr.element_offset(weird_elm), None); // Points between element 0 and 1 ``` -------------------------------- ### Example of connecting with Tokio1 and TLS Source: https://docs.rs/lettre/latest/lettre/transport/smtp/client/struct.AsyncSmtpConnection.html Demonstrates how to establish an SMTP connection using Tokio1, including specifying server details, timeout, client ID, TLS parameters, and local address. ```rust let connection = AsyncSmtpConnection::connect_tokio1( ("example.com", 465), Some(Duration::from_secs(60)), &ClientId::default(), Some(TlsParameters::new("example.com".to_owned())?), None, ) .await?; ``` -------------------------------- ### Removing a prefix with strip_prefix Source: https://docs.rs/lettre/latest/lettre/message/enum.MaybeString.html Use `strip_prefix` to get a subslice with the prefix removed. Returns `None` if the slice does not start with the specified prefix. An empty prefix returns the original slice. ```rust let v = &[10, 40, 30]; assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..])); assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..])); assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..])); assert_eq!(v.strip_prefix(&[50]), None); assert_eq!(v.strip_prefix(&[10, 50]), None) ``` ```rust let prefix : &str = "he"; assert_eq!(b"hello".strip_prefix(prefix.as_bytes()), Some(b"llo".as_ref())) ``` -------------------------------- ### Format HELP Command Source: https://docs.rs/lettre/latest/src/lettre/transport/smtp/commands.rs.html Demonstrates formatting the HELP command, both with and without a specific argument. ```rust assert_eq!(format!("{}", Help::new(None)), "HELP\r\n"); ``` ```rust assert_eq!( format!("{}", Help::new(Some("test".to_owned()))), "HELP test\r\n" ); ``` -------------------------------- ### Iterate slice chunks from the end Source: https://docs.rs/lettre/latest/lettre/message/enum.MaybeString.html Use `rchunks` to get an iterator over slices of a specified size, starting from the end. The last chunk may be smaller if the slice size is not divisible by `chunk_size`. Panics if `chunk_size` is zero. ```rust let slice = ['l', 'o', 'r', 'e', 'm']; let mut iter = slice.rchunks(2); assert_eq!(iter.next().unwrap(), &['e', 'm']); assert_eq!(iter.next().unwrap(), &['o', 'r']); assert_eq!(iter.next().unwrap(), &['l']); assert!(iter.next().is_none()); ``` -------------------------------- ### Start TLS Encryption Source: https://docs.rs/lettre/latest/lettre/transport/smtp/client/struct.SmtpConnection.html Initiates a TLS handshake to encrypt the connection. Requires TLS parameters and a client ID. ```rust pub fn starttls( &mut self, tls_parameters: &TlsParameters, hello_name: &ClientId, ) -> Result<(), Error> ``` -------------------------------- ### Trim Prefix from Slice (Nightly) Source: https://docs.rs/lettre/latest/lettre/message/enum.MaybeString.html Use the experimental `trim_prefix` method to get a subslice with the prefix removed. If the slice does not start with the prefix, the original slice is returned. Handles empty prefixes and prefixes equal to the entire slice. ```rust #![feature(trim_prefix_suffix)] let v = &[10, 40, 30]; // Prefix present - removes it assert_eq!(v.trim_prefix(&[10]), &[40, 30][..]); assert_eq!(v.trim_prefix(&[10, 40]), &[30][..]); assert_eq!(v.trim_prefix(&[10, 40, 30]), &[][..]); // Prefix absent - returns original slice assert_eq!(v.trim_prefix(&[50]), &[10, 40, 30][..]); assert_eq!(v.trim_prefix(&[10, 50]), &[10, 40, 30][..]); let prefix : &str = "he"; assert_eq!(b"hello".trim_prefix(prefix.as_bytes()), b"llo".as_ref()); ``` -------------------------------- ### Example Email Content Source: https://docs.rs/lettre/latest/src/lettre/transport/file/mod.rs.html This is an example of the content of an email file generated by the FileTransport. ```eml From: NoBody Reply-To: Yuin To: Hei Subject: Happy new year Content-Type: text/plain; charset=utf-8 Date: Tue, 18 Aug 2020 22:50:17 GMT Be happy! ``` -------------------------------- ### Example Envelope Content Source: https://docs.rs/lettre/latest/src/lettre/transport/file/mod.rs.html This is an example of the JSON content for the envelope when using the FileTransport with envelope support. ```json {"forward_path":["hei@domain.tld"],"reverse_path":"nobody@domain.tld"} ``` -------------------------------- ### Async Tokio 1.x File Transport Example Source: https://docs.rs/lettre/latest/src/lettre/transport/file/mod.rs.html Demonstrates asynchronous email sending using `AsyncFileTransport` with the Tokio 1.x runtime, writing messages to the local temporary directory. ```rust use std::error::Error; #[cfg(all(feature = "tokio1", feature = "file-transport", feature = "builder"))] async fn run() -> Result<(), Box> { use std::env::temp_dir; use lettre::{ AsyncFileTransport, AsyncTransport, Message, Tokio1Executor, message::header::ContentType, }; // Write to the local temp directory let sender = AsyncFileTransport::::new(temp_dir()); let email = Message::builder() .from("NoBody ".parse()?) .reply_to("Yuin ".parse()?) .to("Hei ".parse()?) .subject("Happy new year") .header(ContentType::TEXT_PLAIN) .body(String::from("Be happy!"))?; sender.send(email).await?; Ok(()) } ``` -------------------------------- ### Create and Format Standard Attachment Source: https://docs.rs/lettre/latest/src/lettre/message/attachment.rs.html Demonstrates creating a standard email attachment with a filename and body content, then asserts its formatted output. ```rust let part = super::Attachment::new(String::from("test.txt")).body( String::from("Hello world!"), ContentType::parse("text/plain").unwrap(), ); assert_eq!( &String::from_utf8_lossy(&part.formatted()), concat!( "Content-Disposition: attachment; filename=\"test.txt\" ", "Content-Type: text/plain ", "Content-Transfer-Encoding: 7bit ", "Hello world!\r " ) ); ``` -------------------------------- ### Get a typed Header Source: https://docs.rs/lettre/latest/lettre/message/header/struct.Headers.html Use `get()` to retrieve a copy of a specific `Header` type from the `Headers` collection. Returns `None` if the header is not present. ```rust pub fn get(&self) -> Option ``` -------------------------------- ### Get Pooled SMTP Connection Source: https://docs.rs/lettre/latest/src/lettre/transport/smtp/pool/async_impl.rs.html Retrieves a connection from the pool, either by reusing an existing one or creating a new one if the pool is empty. Handles broken connections by discarding them and attempting to get another. ```rust pub(crate) async fn connection(self: &Arc) -> Result, Error> { loop { let conn = { let mut connections = self.connections.lock().await; let Some(connections) = connections.as_mut() else { // The transport was shut down return Err(error::transport_shutdown()); }; connections.pop() }; match conn { Some(conn) => { let mut conn = conn.unpark(); // TODO: handle the client try another connection if this one isn't good if !conn.test_connected().await { #[cfg(feature = "tracing")] tracing::debug!("dropping a broken connection"); conn.abort().await; continue; } #[cfg(feature = "tracing")] tracing::debug!("reusing a pooled connection"); return Ok(PooledConnection::wrap(conn, Arc::clone(self))); } None => { #[cfg(feature = "tracing")] tracing::debug!("creating a new connection"); let conn = self.client.connection().await?; return Ok(PooledConnection::wrap(conn, Arc::clone(self))); } } } } ``` -------------------------------- ### Create Help Command Source: https://docs.rs/lettre/latest/lettre/transport/smtp/commands/struct.Help.html Creates an instance of the HELP command, optionally with an argument. This function is part of the `Help` struct's implementation. ```rust pub fn new(argument: Option) -> Help ``` -------------------------------- ### Any::type_id Source: https://docs.rs/lettre/latest/lettre/transport/smtp/struct.SmtpTransportBuilder.html Gets the `TypeId` of the SmtpTransportBuilder. ```APIDOC ## fn type_id(&self) -> TypeId ### Description Gets the `TypeId` of `self`. ### Method type_id ### Returns TypeId - The unique identifier for the type of `self`. ``` -------------------------------- ### AsyncSmtpConnection::server_info Source: https://docs.rs/lettre/latest/lettre/transport/smtp/client/struct.AsyncSmtpConnection.html Get information about the server. ```APIDOC ## AsyncSmtpConnection::server_info ### Description Get information about the server. ### Method `&self` ### Returns `&ServerInfo` - Information about the SMTP server. ``` -------------------------------- ### Build and Send Email via SMTP Source: https://docs.rs/lettre/latest/lettre/transport/index.html Demonstrates building an email using the `Message` API and sending it through an SMTP relay server. Requires SMTP credentials and server details. Ensure the `smtp` feature is enabled. ```rust use lettre::{ Message, SmtpTransport, Transport, message::header::ContentType, transport::smtp::authentication::Credentials, }; let email = Message::builder() .from("NoBody \".parse()?) .reply_to("Yuin \".parse()?) .to("Hei \".parse()?) .subject("Happy new year") .header(ContentType::TEXT_PLAIN) .body(String::from("Be happy!"))?; let creds = Credentials::new("smtp_username".to_owned(), "smtp_password".to_owned()); // Open a remote connection to the SMTP relay server let mailer = SmtpTransport::relay("smtp.gmail.com")? .credentials(creds) .build(); // Send the email match mailer.send(&email) { Ok(_) => println!("Email sent successfully!"), Err(e) => panic!("Could not send email: {e:?}"), } ``` -------------------------------- ### T::type_id Source: https://docs.rs/lettre/latest/lettre/message/struct.Message.html Gets the TypeId of a type T. ```APIDOC ## T::type_id ### Description Gets the `TypeId` of `self`. ### Signature `fn type_id(&self) -> TypeId` ``` -------------------------------- ### AsyncSmtpConnection::read_response Source: https://docs.rs/lettre/latest/lettre/transport/smtp/client/struct.AsyncSmtpConnection.html Gets the SMTP response from the server. ```APIDOC ## AsyncSmtpConnection::read_response ### Description Gets the SMTP response from the server. ### Method `&mut self` ### Returns `Result` - The server's response or an error. ``` -------------------------------- ### Format RCPT TO Command Source: https://docs.rs/lettre/latest/src/lettre/transport/smtp/commands.rs.html Shows how to format the RCPT TO command, with and without parameters. ```rust assert_eq!( format!("{}", Rcpt::new(email.clone(), vec![])), "RCPT TO:\r\n" ); ``` ```rust assert_eq!( format!("{}", Rcpt::new(email, vec![rcpt_parameter])), "RCPT TO: TEST=value\r\n" ); ``` -------------------------------- ### Credentials Creation from Tuple Source: https://docs.rs/lettre/latest/src/lettre/transport/smtp/authentication.rs.html Demonstrates creating a `Credentials` struct from a tuple of string slices, providing a convenient way to initialize credentials. ```rust assert_eq!( Credentials::new("alice".to_owned(), "wonderland".to_owned()), Credentials::from(("alice", "wonderland")) ); ``` -------------------------------- ### Address::domain Source: https://docs.rs/lettre/latest/lettre/address/struct.Address.html Gets the domain portion of the Address. ```APIDOC ## Address::domain ### Description Gets the domain portion of the `Address`. ### Method ``` pub fn domain(&self) -> &str ``` ### Returns A string slice representing the domain part of the email address. ### Examples ```rust use lettre::Address; let address = Address::new("user", "email.com")?; assert_eq!(address.domain(), "email.com"); ``` ``` -------------------------------- ### Create and Add Mailbox to Mailboxes Source: https://docs.rs/lettre/latest/src/lettre/message/mailbox/types.rs.html Demonstrates creating a new Mailboxes instance and adding a Mailbox to it using the `with` method. This is useful for building a list of recipients. ```rust use lettre::message::{Mailbox, Mailboxes}; use std::error::Error; fn main() -> Result<(), Box> { let address = Address::new("example", "email.com")?; let mut mailboxes = Mailboxes::new().with(Mailbox::new(None, address)); Ok(()) } ``` -------------------------------- ### Address::user Source: https://docs.rs/lettre/latest/lettre/address/struct.Address.html Gets the user portion of the Address. ```APIDOC ## Address::user ### Description Gets the user portion of the `Address`. ### Method ``` pub fn user(&self) -> &str ``` ### Returns A string slice representing the user part of the email address. ### Examples ```rust use lettre::Address; let address = Address::new("user", "email.com")?; assert_eq!(address.user(), "user"); ``` ``` -------------------------------- ### PartialEq Implementation for Help Source: https://docs.rs/lettre/latest/lettre/transport/smtp/commands/struct.Help.html Tests for equality between two Help command instances. Used by the `==` operator. ```rust fn eq(&self, other: &Help) -> bool ``` ```rust fn ne(&self, other: &Rhs) -> bool ``` -------------------------------- ### Get Headers Source: https://docs.rs/lettre/latest/src/lettre/message/mimebody.rs.html Returns a reference to the headers of the multipart message. ```APIDOC ## headers ### Description Get the headers from the multipart. ### Signature pub fn headers(&self) -> &Headers ``` -------------------------------- ### Format ServerInfo with Features Source: https://docs.rs/lettre/latest/src/lettre/transport/smtp/extension.rs.html Illustrates the string representation of ServerInfo, including cases with and without supported features. ```rust assert_eq!( format!("{}", ServerInfo { name: "name".to_owned(), features: eightbitmime, } ), "name with {EightBitMime}".to_owned() ); assert_eq!( format!("{}", ServerInfo { name: "name".to_owned(), features: empty, } ), "name with no supported features".to_owned() ); assert_eq!( format!("{}", ServerInfo { name: "name".to_owned(), features: plain, } ), "name with {Authentication(Plain)}".to_owned() ); ``` -------------------------------- ### Format ClientId and Localhost Source: https://docs.rs/lettre/latest/src/lettre/transport/smtp/extension.rs.html Demonstrates the string formatting for ClientId and a localhost constant. ```rust assert_eq!( format!("{}", ClientId::Domain("test".to_owned())), "test".to_owned() ); assert_eq!(format!("{}", LOCALHOST_CLIENT), "[127.0.0.1]".to_owned()); ``` -------------------------------- ### strip_prefix Source: https://docs.rs/lettre/latest/lettre/message/enum.MaybeString.html Returns a subslice with the prefix removed. If the slice starts with `prefix`, returns the subslice after the prefix, wrapped in `Some`. If `prefix` is empty, simply returns the original slice. If `prefix` is equal to the original slice, returns an empty slice. If the slice does not start with `prefix`, returns `None`. ```APIDOC ## pub fn strip_prefix

(&self, prefix: &P) -> Option<&[T]> where P: SlicePattern + ?Sized, T: PartialEq, ### Description Returns a subslice with the prefix removed. If the slice starts with `prefix`, returns the subslice after the prefix, wrapped in `Some`. If `prefix` is empty, simply returns the original slice. If `prefix` is equal to the original slice, returns an empty slice. If the slice does not start with `prefix`, returns `None`. ### Parameters #### Path Parameters - **prefix** (&P) - Required - The prefix to remove. ### Examples ```rust let v = &[10, 40, 30]; assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..])); assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..])); assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..])); assert_eq!(v.strip_prefix(&[50]), None); assert_eq!(v.strip_prefix(&[10, 50]), None); ``` ``` -------------------------------- ### Create Mailbox from Address Source: https://docs.rs/lettre/latest/lettre/message/struct.Mailbox.html Demonstrates creating a Mailbox instance using an Address object and an optional name. Requires the `builder` feature. ```rust let address = Address::new("example", "email.com")?; let mailbox = Mailbox::new(None, address); ``` -------------------------------- ### Reverse Splitting of a Slice by a Predicate Source: https://docs.rs/lettre/latest/lettre/message/enum.MaybeString.html Returns an iterator over subslices separated by elements that match a predicate, starting from the end of the slice and working backwards. The matched element is not included in the subslices. Handles edge cases like delimiters at the start or end, producing empty slices. ```rust let slice = [11, 22, 33, 0, 44, 55]; let mut iter = slice.rsplit(|num| *num == 0); assert_eq!(iter.next().unwrap(), &[44, 55]); assert_eq!(iter.next().unwrap(), &[11, 22, 33]); assert_eq!(iter.next(), None); ``` ```rust let v = &[0, 1, 1, 2, 3, 5, 8]; let mut it = v.rsplit(|n| *n % 2 == 0); assert_eq!(it.next().unwrap(), &[]); assert_eq!(it.next().unwrap(), &[3, 5]); assert_eq!(it.next().unwrap(), &[1, 1]); assert_eq!(it.next().unwrap(), &[]); assert_eq!(it.next(), None); ``` -------------------------------- ### SmtpConnection Usage Source: https://docs.rs/lettre/latest/lettre/transport/smtp/client/index.html Demonstrates how to establish an SMTP connection and send basic commands like MAIL, RCPT, DATA, MESSAGE, and QUIT. ```APIDOC ## SmtpConnection Usage ### Description This example shows how to create an `SmtpConnection`, send a `Mail` command, add a `Rcpt` recipient, send the `Data` and `Message`, and finally close the connection with `Quit`. ### Method Not applicable (SDK usage) ### Endpoint Not applicable (SDK usage) ### Parameters Not applicable (SDK usage) ### Request Example ```rust use lettre::transport::smtp::{ SMTP_PORT, client::SmtpConnection, commands::*, extension::ClientId, }; let hello = ClientId::Domain("my_hostname".to_owned()); let mut client = SmtpConnection::connect(&("localhost", SMTP_PORT), None, &hello, None, None)?; 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)?; ``` ### Response Not applicable (SDK usage) ``` -------------------------------- ### ServerInfo::get_auth_mechanism Source: https://docs.rs/lettre/latest/lettre/transport/smtp/extension/struct.ServerInfo.html Gets a compatible authentication mechanism from a provided list. ```APIDOC ### `pub fn get_auth_mechanism(&self, mechanisms: &[Mechanism]) -> Option` Gets a compatible mechanism from a list. ``` -------------------------------- ### Upgrade to TLS Connection Source: https://docs.rs/lettre/latest/src/lettre/transport/smtp/client/connection.rs.html Handles the STARTTLS command to upgrade the connection to TLS. Requires a TLS feature to be enabled. If STARTTLS is not supported by the server, it returns an error. ```rust if self.server_info.supports_feature(Extension::StartTls) { #[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))] { try_smtp!(self.command(Starttls), self); self.stream.get_mut().upgrade_tls(tls_parameters)?; #[cfg(feature = "tracing")] tracing::debug!("connection encrypted"); // Send EHLO again try_smtp!(self.ehlo(hello_name), self); Ok(()) } #[cfg(not(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))] // This should never happen as `Tls` can only be created when a TLS library is enabled unreachable!("TLS support required but not supported"); } else { Err(error::client("STARTTLS is not supported on this server")) } ``` -------------------------------- ### Implement Any for T Source: https://docs.rs/lettre/latest/lettre/transport/smtp/commands/struct.Noop.html Gets the TypeId of a type, useful for runtime type identification. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Get Body Encoding Type Source: https://docs.rs/lettre/latest/lettre/message/struct.Body.html Returns the ContentTransferEncoding used for this body. ```rust pub fn encoding(&self) -> ContentTransferEncoding ``` -------------------------------- ### Async Tokio 1.x Sendmail Example Source: https://docs.rs/lettre/latest/src/lettre/transport/sendmail/mod.rs.html Shows how to send an email asynchronously using SendmailTransport with the Tokio 1.x runtime. Requires 'tokio1', 'sendmail-transport', and 'builder' features. ```rust use lettre::{ AsyncSendmailTransport, AsyncTransport, Message, SendmailTransport, Tokio1Executor, message::header::ContentType, }; let email = Message::builder() .from("NoBody ".parse()?) .reply_to("Yuin ".parse()?) .to("Hei ".parse()?) .subject("Happy new year") .header(ContentType::TEXT_PLAIN) .body(String::from("Be happy!"))?; let sender = AsyncSendmailTransport::::new(); sender.send(email).await?; ```