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