extern crate base64;
extern crate charset;
extern crate quoted_printable;
use std::collections::BTreeMap;
pub mod body;
mod dateparse;
mod error;
mod util;
use body::Body;
pub use dateparse::dateparse;
pub use error::*;
/// A struct that represents a single header in the message.
/// It holds slices into the raw byte array passed to parse_mail, and so the
/// lifetime of this struct must be contained within the lifetime of the raw
/// input. There are additional accessor functions on this struct to extract
/// the data as Rust strings.
#[derive(Debug)]
pub struct MailHeader<'a> {
key: &'a [u8],
value: &'a [u8],
}
impl<'a> MailHeader<'a> {
/// Get the name of the header. Note that header names are case-insensitive.
pub fn get_key(&self) -> Result<String, MailParseError> {
Ok(decode_latin1(self.key).into_owned())
}
fn decode_word(&self, encoded: &str) -> Option<String> {
let ix_delim1 = encoded.find('?')?;
let ix_delim2 = find_from(encoded, ix_delim1 + 1, "?")?;
let charset = &encoded[0..ix_delim1];
let transfer_coding = &encoded[ix_delim1 + 1..ix_delim2];
let input = &encoded[ix_delim2 + 1..];
let decoded = match transfer_coding {
"B" | "b" => base64::decode(input.as_bytes()).ok()?,
"Q" | "q" => {
// The quoted_printable module does a trim_end on the input, so if
// that affects the output we should save and restore the trailing
// whitespace
let to_decode = input.replace("_", " ");
let trimmed = to_decode.trim_end();
let mut d = quoted_printable::decode(&trimmed, quoted_printable::ParseMode::Robust);
if d.is_ok() && to_decode.len() != trimmed.len() {
d.as_mut()
.unwrap()