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
impl Mail
Sourcepub fn plain_text(text: impl Into<String>, ctx: &impl Context) -> Mail
pub fn plain_text(text: impl Into<String>, ctx: &impl Context) -> Mail
Create a new plain text mail.
This will
- turn the
text
into aString
- generate a new ContentId using the context
- create a
Resource
from theString
(with content typetext/plain; charset=utf-8
) - create a mail from the resource
Sourcepub fn has_multipart_body(&self) -> bool
pub fn has_multipart_body(&self) -> bool
Returns true if the body of the mail is a multipart body.
Sourcepub fn new_multipart_mail(content_type: MediaType, bodies: Vec<Mail>) -> Mail
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.
Sourcepub fn new_singlepart_mail(body: Resource) -> Mail
pub fn new_singlepart_mail(body: Resource) -> Mail
Create a new non-multipart mail for given Resource
as body.
Sourcepub fn insert_header<H>(&mut self, header: Header<H>)where
H: HeaderKind,
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.
Sourcepub fn insert_headers(&mut self, headers: HeaderMap)
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.
Sourcepub fn headers(&self) -> &HeaderMap
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.
Sourcepub fn headers_mut(&mut self) -> &mut HeaderMap
pub fn headers_mut(&mut self) -> &mut HeaderMap
Return a mutable reference to the currently set headers.
Sourcepub fn generally_validate_mail(&self) -> Result<(), MailError>
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 (seeHeaderMap
’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
).
Sourcepub fn into_encodable_mail<C>(self, ctx: C) -> MailFuture<C>where
C: Context,
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:
-
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).
- This uses
-
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.
-
Insert all auto generated headers (like e.g.
Date
). -
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
impl Mail
Sourcepub fn wrap_with_mixed(self, other_bodies: Vec<Mail>) -> Mail
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.
Sourcepub fn wrap_with_alternatives(self, alternates: Vec<Mail>) -> Mail
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.