From 227da8ac09667ab1725f306361cc4c7083f2d47f Mon Sep 17 00:00:00 2001 From: RotationMatrix <52428419+RotationMatrix@users.noreply.github.com> Date: Sun, 22 Nov 2020 11:29:09 -0500 Subject: [PATCH] Add HTML examples (#496) * Add HTML email example * Add comment about creating `SmtpTransportBuilder` Add similar comment to `AsyncSmtpTransportBuilder` * Improve wording and fix typos * Add file_html example to Cargo.toml * Update examples/README.md Co-authored-by: Paolo Barbolini * Use intra-doc links * Rename file_html example to basic_html * Add maud HTML example * Make CI happy * Fix CSS * Fix maud version Co-authored-by: Paolo Barbolini --- Cargo.toml | 9 ++++ examples/README.md | 2 + examples/basic_html.rs | 51 +++++++++++++++++++++++ examples/maud_html.rs | 60 +++++++++++++++++++++++++++ src/transport/smtp/async_transport.rs | 3 +- src/transport/smtp/transport.rs | 3 +- 6 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 examples/basic_html.rs create mode 100644 examples/maud_html.rs diff --git a/Cargo.toml b/Cargo.toml index 605df2a..e45f1aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,6 +70,7 @@ walkdir = "2" tokio02_crate = { package = "tokio", version = "0.2.7", features = ["macros", "rt-threaded"] } tokio03_crate = { package = "tokio", version = "0.3", features = ["macros", "rt-multi-thread"] } serde_json = "1" +maud = "0.22.1" [[bench]] harness = false @@ -100,6 +101,14 @@ tokio03-rustls-tls = ["tokio03", "rustls-tls", "tokio03_rustls"] all-features = true rustdoc-args = ["--cfg", "docsrs"] +[[example]] +name = "basic_html" +required-features = ["file-transport", "builder"] + +[[example]] +name = "maud_html" +required-features = ["file-transport", "builder"] + [[example]] name = "smtp" required-features = ["smtp-transport", "builder"] diff --git a/examples/README.md b/examples/README.md index 18462b3..02e4b96 100644 --- a/examples/README.md +++ b/examples/README.md @@ -3,6 +3,7 @@ This folder contains examples showing how to use lettre in your own projects. ## Examples +- [file_html.rs] - Create an HTML email. - [smtp.rs] - Send an email using a local SMTP daemon on port 25 as a relay. - [smtp_tls.rs] - Send an email over SMTP encrypted with TLS and authenticating with username and password. - [smtp_starttls.rs] - Send an email over SMTP with STARTTLS and authenticating with username and password. @@ -10,6 +11,7 @@ This folder contains examples showing how to use lettre in your own projects. - The [smtp_tls.rs] and [smtp_starttls.rs] examples also feature `async`hronous implementations powered by [Tokio](https://tokio.rs/). These files are prefixed with `tokio02_` or `tokio03_`. +[file_html.rs]: ./file_html.rs [smtp.rs]: ./smtp.rs [smtp_tls.rs]: ./smtp_tls.rs [smtp_starttls.rs]: ./smtp_starttls.rs diff --git a/examples/basic_html.rs b/examples/basic_html.rs new file mode 100644 index 0000000..19aca6b --- /dev/null +++ b/examples/basic_html.rs @@ -0,0 +1,51 @@ +use lettre::message::{header, MultiPart, SinglePart}; +use lettre::{FileTransport, Message, Transport}; + +fn main() { + // The html we want to send. + let html = r#" + + + + + Hello from Lettre! + + +
+

Hello from Lettre!

+

A mailer library for Rust

+
+ +"#; + + // Build the message. + let email = Message::builder() + .from("NoBody ".parse().unwrap()) + .to("Hei ".parse().unwrap()) + .subject("Hello from Lettre!") + .multipart( + MultiPart::alternative() // This is composed of two parts. + .singlepart( + SinglePart::eight_bit() + .header(header::ContentType( + "text/plain; charset=utf8".parse().unwrap(), + )) + .body("Hello from Lettre! A mailer library for Rust"), // Every message should have a plain text fallback. + ) + .singlepart( + SinglePart::quoted_printable() + .header(header::ContentType( + "text/html; charset=utf8".parse().unwrap(), + )) + .body(html), + ), + ) + .expect("failed to build email"); + + // Create our mailer. Please see the other examples for creating SMTP mailers. + // The path given here must exist on the filesystem. + let mailer = FileTransport::new("./"); + + // Store the message when you're ready. + mailer.send(&email).expect("failed to deliver message"); +} diff --git a/examples/maud_html.rs b/examples/maud_html.rs new file mode 100644 index 0000000..02ffceb --- /dev/null +++ b/examples/maud_html.rs @@ -0,0 +1,60 @@ +use lettre::message::{header, MultiPart, SinglePart}; +use lettre::{FileTransport, Message, Transport}; +use maud::html; + +fn main() { + // The recipient's name. We might obtain this from a form or their email address. + let recipient = "Hei"; + + // Create the html we want to send. + let html = html! { + head { + title { "Hello from Lettre!" } + style type="text/css" { + "h2, h4 { font-family: Arial, Helvetica, sans-serif; }" + } + } + div style="display: flex; flex-direction: column; align-items: center;" { + h2 { "Hello from Lettre!" } + // Substitute in the name of our recipient. + p { "Dear " (recipient) "," } + p { "This email was sent with Lettre, a mailer library for Rust!"} + p { + "This example uses " + a href="https://crates.io/crates/maud" { "maud" } + ". It is about 20% cooler than the basic HTML example." + } + } + }; + + // Build the message. + let email = Message::builder() + .from("NoBody ".parse().unwrap()) + .to("Hei ".parse().unwrap()) + .subject("Hello from Lettre!") + .multipart( + MultiPart::alternative() // This is composed of two parts. + .singlepart( + SinglePart::eight_bit() + .header(header::ContentType( + "text/plain; charset=utf8".parse().unwrap(), + )) + .body("Hello from Lettre! A mailer library for Rust"), // Every message should have a plain text fallback. + ) + .singlepart( + SinglePart::quoted_printable() + .header(header::ContentType( + "text/html; charset=utf8".parse().unwrap(), + )) + .body(html.into_string()), + ), + ) + .expect("failed to build email"); + + // Create our mailer. Please see the other examples for creating SMTP mailers. + // The path given here must exist on the filesystem. + let mailer = FileTransport::new("./"); + + // Store the message when you're ready. + mailer.send(&email).expect("failed to deliver message"); +} diff --git a/src/transport/smtp/async_transport.rs b/src/transport/smtp/async_transport.rs index 6eac753..94e60fd 100644 --- a/src/transport/smtp/async_transport.rs +++ b/src/transport/smtp/async_transport.rs @@ -132,7 +132,8 @@ where } } -/// Contains client configuration +/// Contains client configuration. +/// Instances of this struct can be created using functions of [`AsyncSmtpTransport`]. #[allow(missing_debug_implementations)] #[derive(Clone)] pub struct AsyncSmtpTransportBuilder { diff --git a/src/transport/smtp/transport.rs b/src/transport/smtp/transport.rs index 7c56ce4..6ffcd6e 100644 --- a/src/transport/smtp/transport.rs +++ b/src/transport/smtp/transport.rs @@ -107,7 +107,8 @@ impl SmtpTransport { } } -/// Contains client configuration +/// Contains client configuration. +/// Instances of this struct can be created using functions of [`SmtpTransport`]. #[allow(missing_debug_implementations)] #[derive(Clone)] pub struct SmtpTransportBuilder {