1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
use crate::{MailHeader, MailHeaderMap};
use std::fmt;
use std::slice;
/// A struct that wrapps the header portion of a message and provides
/// utility functions to look up specific headers.
pub struct Headers<'a> {
raw_bytes: &'a [u8],
headers: &'a [MailHeader<'a>],
}
impl<'a> Headers<'a> {
pub(crate) fn new(raw_bytes: &'a [u8], headers: &'a [MailHeader<'a>]) -> Headers<'a> {
Headers { raw_bytes, headers }
}
/// Returns the raw, unparsed bytes that make up the header block of
/// the message. This includes everything up to and including the empty
/// line at the end of the header block.
///
/// # Examples
/// ```
/// use mailparse::{parse_mail, headers::Headers};
/// let mail = parse_mail(concat!(
/// "SubJECT : foo\n",
/// "\n",
/// "Body starts here").as_bytes())
/// .unwrap();
/// assert_eq!(mail.get_headers().get_raw_bytes(), b"SubJECT : foo\n\n");
pub fn get_raw_bytes(&self) -> &'a [u8] {
self.raw_bytes
}
}
/// Allows iterating over the individual `MailHeader` items in this block of
/// headers.
///
/// # Examples
/// ```
/// use mailparse::{parse_mail, headers::Headers};
/// let mail = parse_mail(concat!(
/// "Subject: foo\n",
/// "Another header: bar\n",
/// "\n",
/// "Body starts here").as_bytes())
/// .unwrap();
/// let mut iter = mail.get_headers().into_iter();
/// assert_eq!(iter.next().unwrap().get_key(), "Subject");
/// assert_eq!(iter.next().unwrap().get_key(), "Another header");
/// ```
impl<'a> IntoIterator for Headers<'a> {
type Item = &'a MailHeader<'a>;
type IntoIter = slice::Iter<'a, MailHeader<'a>>;
fn into_iter(self) -> Self::IntoIter {
self.headers.into_iter()
}
}
/// Allows formatting and printing the `Headers` struct items.
///
/// # Examples
/// ```
/// use mailparse::parse_mail;
/// let mail = parse_mail(concat!(
/// "Subject: foo\n",
/// "Another header: bar\n",
/// "\n",
/// "Body starts here").as_bytes())
/// .unwrap();
/// let mut headers = mail.get_headers();
/// assert_eq!(format!("{:?}", headers), "Headers { \
/// headers: [MailHeader { key: \"Subject\", value: \"foo\" }, \
/// MailHeader { key: \"Another header\", value: \"bar\" }] }");
/// ```
impl<'a> fmt::Debug for Headers<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Headers")
.field("headers", &self.headers)
.finish()
}
}
impl<'a> MailHeaderMap for Headers<'a> {
/// # Examples
/// ```
/// use mailparse::{parse_mail, MailHeaderMap, headers::Headers};
/// let mail = parse_mail(concat!(
/// "Subject: Test\n",
/// "\n",
/// "This is a test message").as_bytes())
/// .unwrap();
/// assert_eq!(mail.get_headers().get_first_value("Subject"), Some("Test".to_string()));
/// ```
fn get_first_value(&self, key: &str) -> Option<String> {
self.headers.get_first_value(key)
}
fn get_first_header(&self, key: &str) -> Option<&MailHeader> {
self.headers.get_first_header(key)
}
/// # Examples
/// ```
/// use mailparse::{parse_mail, MailHeaderMap, headers::Headers};
/// let mail = parse_mail(concat!(
/// "Key: Value1\n",
/// "Key: Value2").as_bytes())
/// .unwrap();
/// assert_eq!(mail.get_headers().get_all_values("Key"),
/// vec!["Value1".to_string(), "Value2".to_string()]);
/// ```
fn get_all_values(&self, key: &str) -> Vec<String> {
self.headers.get_all_values(key)
}
fn get_all_headers(&self, key: &str) -> Vec<&MailHeader> {
self.headers.get_all_headers(key)
}
}