// Copyright 2019 Alexandros Frantzis
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//
// SPDX-License-Identifier: MPL-2.0
//! The mda crate provides a library for writing custom Mail Deliver Agents. It
//! supports local delivery to maildirs, access to normalized email byte
//! data for easier processing, and access to individual header fields.
//!
//! Email data normalization involves ensuring header fields are in single
//! lines, decoding text parts of the message that use some kind of transfer
//! encoding (e.g., base64), and converting all text to UTF-8. The original
//! (non-normalized) email data is used during delivery.
//!
//! This crate also exposes convenience methods for regular expression searching
//! and processing/filtering of emails.
//!
//! # Email construction
//!
//! The [Email struct](struct.Email.html) is the basic abstraction of the `mda`
//! crate. To construct an Email use the
//! [Email::from_stdin](struct.Email.html#method.from_stdin) or
//! [Email::from_vec](struct.Email.html#method.from_vec) method.
//!
//! ```no_run
//! use mda::Email;
//! let email = Email::from_stdin()?;
//! let email = Email::from_vec(vec![97, 98, 99])?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! # Email delivery
//!
//! Use the
//! [Email::deliver_to_maildir](struct.Email.html#method.deliver_to_maildir)
//! method to deliver the email to local maildir directories. Note that
//! the original (non-normalized) email data is used during delivery.
//!
//! ```no_run
//! use mda::Email;
//! let email = Email::from_stdin()?;
//! email.deliver_to_maildir("/my/maildir/path")?;
//! email.deliver_to_maildir("/my/other/maildir/path")?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! # Accessing email header fields
//!
//! Use the [Email::header_field](struct.Email.html#method.header_field) and
//! [Email::header_field_all_occurrences](struct.Email.html#method.header_field_all_occurrences)
//! methods to access the email header fields. Any MIME encoded words in the
//! header field values are decoded and the field value is converted to UTF-8.
//!
//! ```no_run
//! use mda::Email;
//! let email = Email::from_stdin()?;
//! let to = email.header_field("To").unwrap_or("");
//! if to.contains("me@example.com") {
//! email.deliver_to_maildir("/my/maildir/path")?;
//! }
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! # Searching with regular expressions
//!
//! The [EmailRegex](trait.EmailRegex.html) trait provides convenience methods
//! for searching the header, the body or the whole email with regular
//! expressions. The convenience functions use case-insensitive, multi-line
//! search (`^` and `$` match beginning and end of lines). If the above don't
//! match your needs, or you require additional functionality, you can perform
//! manual regex search using the email data.
//!
//! ```no_run
//! use mda::{Email, EmailRegex};
//! let email = Email::from_stdin()?;
//! if email.header().search(r"^To:.*me@example.com")? {
//! email.deliver_to_maildir("/my/maildir/path")?;
//! }
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! # Processing and filtering the email with external programs
//!
//! Use the [Email::filter](struct.Email.html#method.filter) and
//! [Email::from_stdin_filtered](struct.Email.html#method.from_stdin_filtered)
//! methods to filter the email, in both cases creating a new email.
//!
//! ```no_run
//! use mda::Email;
//! // Filtering directly from stdin is more efficient.
//! let email = Email::from_stdin_filtered(&["bogofilter", "-ep"])?;
//! let bogosity = email.header_field("X-Bogosity").unwrap_or("");
//! if bogosity.contains("Spam, tests=bogofilter") {
//! email.deliver_to_maildir("/my/spam/path")?;
//! }
//! // We can also filter at any other time.
//! let email = email.filter(&["bogofilter", "-ep"])?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! To perform more general processing use the
//! [Email::process](struct.Email.html#method.process)
//! method:
//!
//! ```no_run
//! use mda::Email;
//! let email = Email::from_stdin()?;
//! let output = email.process(&["bogofilter"])?;
//! if let Some(0) = output.status.code() {
//! email.deliver_to_maildir("/my/spam/path")?;
//! }
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! # Access to byte data
//!
//! Use the [Email::header](struct.Email.html#method.header),
//! [Email::body](struct.Email.html#method.body),
//! [Email::data](struct.Email.html#method.data) methods to access the
//! normalized byte data of the header, body and whole email respectively.
//!
//! Normalization involves ensuring header fields are in single lines, decoding
//! text parts of the message that use some kind of transfer encoding (e.g.,
//! base64), and converting all text to UTF-8 character encoding.
//!
//! If for some reason you need access to non-normalized data use
//! [Email::raw_data](struct.Email.html#method.raw_data).
//!
//! ```no_run
//! use std::str;
//! use mda::Email;
//! let email = Email::from_stdin()?;
//! let body_str = String::from_utf8_lossy(email.header());
//!
//! if body_str.contains("FREE BEER") {
//! email.deliver_to_maildir("/my/spam/path")?;
//! }
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! # Decide delivery durability vs speed trade-off
//!
//! Use the [Email::set_delivery_durability](struct.Email.html#method.set_delivery_durability)
//! to decide which [DeliveryDurability](enum.DeliveryDurability.html) method to use.
//! By default the most durable (but also slower) method is used.
//!
//! ```no_run
//! use mda::{Email, DeliveryDurability};
//! let mut email = Email::from_stdin()?;
//! email.set_delivery_durability(DeliveryDurability::FileSyncOnly);
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
use io;
use *;
use ;
use ;
use HashMap;
use ;
use normalize_email;
pub use crate EmailRegex;
pub type Result<T> = Result;
/// The method to use to try to guarantee durable email delivery.
/// A representation of an email.