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) } }