Struct Mail

Source
pub struct Mail { /* private fields */ }
Expand description

Re-export of all parts of the mail_core crate.

Some parts like error/default_impl will get overridden. A type representing a Mail.

This type is used to represent a mail including headers and body. It is also used for the bodies of multipart mime mail bodies as they can be seen as “sub-mails” or “hirachical nested mails”, at last wrt. everything relevant on this type.

A mail can be created using the Builder or more specific either the SinglepartBuilder or the MultipartBuilder for a multipart mime mail.

§Example

This will create, encode and print a simple plain text mail.

use std::str;
// either from `mail::headers` or from `mail_header as headers`
use headers::{
    headers::*,
    header_components::Domain
};
use mail_core::{
    Mail, Resource,
    default_impl::simple_context
};

// Domain will implement `from_str` in the future,
// currently it doesn't have a validator/parser.
let domain = Domain::from_unchecked("example.com".to_owned());
// Normally you create this _once per application_.
let ctx = simple_context::new(domain, "xqi93".parse().unwrap())
    .unwrap();

let mut mail = Mail::plain_text("Hy there!", &ctx);
mail.insert_headers(headers! {
    _From: [("I'm Awesome", "bla@examle.com")],
    _To: ["unknow@example.com"],
    Subject: "Hy there message"
}.unwrap());

// We don't added anythink which needs loading but we could have
// and all of it would have been loaded concurrent and async.
let encoded = mail.into_encodable_mail(ctx.clone())
    .wait().unwrap()
    .encode_into_bytes(MailType::Ascii).unwrap();

let mail_str = str::from_utf8(&encoded).unwrap();
println!("{}", mail_str);

And here is an example to create the same mail using the builder:

// either from `mail::headers` or from `mail_header as headers`
use headers::{
    headers::*,
};
use mail_core::{Mail,  Resource};

let resource = Resource::plain_text("Hy there!", &ctx);
let mut mail = Mail::new_singlepart_mail(resource);
mail.insert_headers(headers! {
    _From: [("I'm Awesome", "bla@examle.com")],
    _To: ["unknow@example.com"],
    Subject: "Hy there message"
}.unwrap());

And here is an example creating a multipart mail with a made up multipart type.

// either from `mail::headers` or from `mail_header as headers`
use headers::{
    headers::*,
    header_components::{
        MediaType,
    }
};
use mail_core::{Mail, Resource};

let sub_body1 = Mail::plain_text("Body 1", &ctx);
let sub_body2 = Mail::plain_text("Body 2, yay", &ctx);

// This will generate `multipart/x.made-up-think; boundary=randome_generate_boundary`
let media_type = MediaType::new("multipart", "x.made-up-thing").unwrap();
let mut mail = Mail::new_multipart_mail(media_type, vec![sub_body1, sub_body2]);
mail.insert_headers(headers! {
    _From: [("I'm Awesome", "bla@examle.com")],
    _To: ["unknow@example.com"],
    Subject: "Hy there message"
}.unwrap());

Implementations§

Source§

impl Mail

Source

pub fn plain_text(text: impl Into<String>, ctx: &impl Context) -> Mail

Create a new plain text mail.

This will

  • turn the text into a String
  • generate a new ContentId using the context
  • create a Resource from the String (with content type text/plain; charset=utf-8)
  • create a mail from the resource
Source

pub fn has_multipart_body(&self) -> bool

Returns true if the body of the mail is a multipart body.

Source

pub fn new_multipart_mail(content_type: MediaType, bodies: Vec<Mail>) -> Mail

Create a new multipart mail with given content type and given bodies.

Note that while the given content_type has to be a multipart content type (when encoding the mail) it is not required nor expected to have the boundary parameter. The boundary will always be automatically generated independently of wether or not it was passed as media type.

Source

pub fn new_singlepart_mail(body: Resource) -> Mail

Create a new non-multipart mail for given Resource as body.

Source

pub fn insert_header<H>(&mut self, header: Header<H>)
where H: HeaderKind,

Inserts a new header into the header map.

This will call insert on the inner HeaderMap, which means all behavior of HeaderMap::insert does apply, like e.g. the “max one” behavior.

Source

pub fn insert_headers(&mut self, headers: HeaderMap)

Inserts all headers into the inner header map.

This will call HeaderMap::insert_all internally which means all behavior of HeaderMap::insert does apply, like e.g. the “max one” behavior.

Source

pub fn headers(&self) -> &HeaderMap

Returns a reference to the currently set headers.

Note that some headers namely Content-Transfer-Encoding as well as Content-Type for singlepart mails are derived from the content and should not be set. If done so they are either ignored or an error is caused by them in other parts of the crate (like e.g. encoding). Also Date is auto-generated if not set and it is needed.

Source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Return a mutable reference to the currently set headers.

Source

pub fn body(&self) -> &MailBody

Returns a reference to the body/bodies.

Source

pub fn body_mut(&mut self) -> &mut MailBody

Return a mutable reference to the body/bodies.

Source

pub fn generally_validate_mail(&self) -> Result<(), MailError>

Validate the mail.

This will mainly validate the mail headers by

  • checking if no ContentTransferHeader is given
  • (for mails with multipart bodies) checking if the content type is a multipart media type
  • (for mail with non-multipart bodies) check if there is no content type header (as the content type header will be derived from he Resource)
  • running all header validators (with use_contextual_validators) this also checks for “max one” consistency (see HeaderMap’s documentation for more details)
  • doing this recursively with all contained mails

Note that this will be called by into_encodable_mail, therefor it is normally not required to call this function by yourself.

Be aware that this does a general validation applicable to both the top level headers and headers from multipart mail sub bodies. This means it e.g. doesn’t check if there are any of the required headers (Date and From).

Source

pub fn into_encodable_mail<C>(self, ctx: C) -> MailFuture<C>
where C: Context,

Turns the mail into a future with resolves to an EncodableMail.

While this future resolves it will do following thinks:

  1. Validate the mail.

    • This uses generally_validate_mail.
    • Additionally it does check for required top level headers which will not be auto-generated (the From header).
  2. Make sure all resources are loaded and transfer encoded.

    • This will concurrently load + transfer encode all resources replacing the old resource instances with the new loaded and encoded ones once all of them had been loaded (and encoded) successfully.
  3. Insert all auto generated headers (like e.g. Date).

  4. Insert boundary parameters into all multipart media types (overriding any existing one).

Use this if you want to encode a mail. This is needed as Resource instances used in the mail are loaded “on-demand”, i.e. if you attach two images but never turn the mail into an encodable mail the images are never loaded from disk.

Source§

impl Mail

Source

pub fn wrap_with_mixed(self, other_bodies: Vec<Mail>) -> Mail

Create a multipart/mixed Mail instance containing this mail as first body and one additional body for each attachment.

Normally this is used with embeddings having a attachment disposition creating a mail with attachments.

Source

pub fn wrap_with_alternatives(self, alternates: Vec<Mail>) -> Mail

Create a multipart/alternative Mail instance containing this mail as the main body with given alternatives.

The “priority” of alternative bodies is ascending with the body which should be shown only if all other bodies can’t be displayed first. I.e. the order is the same order as specified by multipart/alternative. This also means that this body will be the last body as it is meant to be the main body.

Creates a multipart/related Mail instance containing this mail first and then all related bodies.

Trait Implementations§

Source§

impl Clone for Mail

Source§

fn clone(&self) -> Mail

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Mail

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Into<Mail> for EncodableMail

Source§

fn into(self) -> Mail

Converts this type into the (usually inferred) input type.

Auto Trait Implementations§

§

impl Freeze for Mail

§

impl !RefUnwindSafe for Mail

§

impl Send for Mail

§

impl Sync for Mail

§

impl Unpin for Mail

§

impl !UnwindSafe for Mail

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> HeaderTryFrom<T> for T

Source§

impl<F, T> HeaderTryInto<T> for F
where T: HeaderTryFrom<F>,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Erased for T