mail_parser/parsers/fields/
raw.rs1use crate::{parsers::MessageStream, HeaderValue};
8
9impl<'x> MessageStream<'x> {
10 pub fn parse_raw(&mut self) -> HeaderValue<'x> {
11 let mut token_start: usize = 0;
12 let mut token_end: usize = 0;
13
14 while let Some(ch) = self.next() {
15 match ch {
16 b'\n' => {
17 if !self.try_next_is_space() {
18 break;
19 } else {
20 continue;
21 }
22 }
23 b' ' | b'\t' | b'\r' => continue,
24 _ => (),
25 }
26
27 if token_start == 0 {
28 token_start = self.offset();
29 }
30
31 token_end = self.offset();
32 }
33
34 if token_start > 0 {
35 HeaderValue::Text(String::from_utf8_lossy(
36 self.bytes(token_start - 1..token_end),
37 ))
38 } else {
39 HeaderValue::Empty
40 }
41 }
42
43 pub fn parse_and_ignore(&mut self) {
44 while let Some(&ch) = self.next() {
45 if ch == b'\n' && !self.try_next_is_space() {
46 break;
47 }
48 }
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use crate::{parsers::MessageStream, MessageParser};
55
56 #[test]
57 fn parse_raw_text() {
58 let inputs = [
59 ("Saying Hello\nMessage-Id", "Saying Hello"),
60 ("Re: Saying Hello\r\n \r\nFrom:", "Re: Saying Hello"),
61 (
62 concat!(
63 " from x.y.test\n by example.net\n via TCP\n",
64 " with ESMTP\n id ABC12345\n ",
65 "for <mary@example.net>; 21 Nov 1997 10:05:43 -0600\n"
66 ),
67 concat!(
68 "from x.y.test\n by example.net\n via TCP\n",
69 " with ESMTP\n id ABC12345\n ",
70 "for <mary@example.net>; 21 Nov 1997 10:05:43 -0600"
71 ),
72 ),
73 ("Re: Saying Hello", "Re: Saying Hello"), ];
75
76 for (input, expected) in inputs {
77 assert_eq!(
78 MessageStream::new(input.as_bytes())
79 .parse_raw()
80 .unwrap_text(),
81 expected,
82 "Failed for '{:?}'",
83 input
84 );
85 }
86 }
87
88 #[test]
89 fn ordered_raw_headers() {
90 let input = br#"From: Art Vandelay <art@vandelay.com>
91To: jane@example.com
92Date: Sat, 20 Nov 2021 14:22:01 -0800
93Subject: Why not both importing AND exporting? =?utf-8?b?4pi6?=
94Content-Type: multipart/mixed; boundary="festivus";
95
96Here's a message body.
97"#;
98 let message = MessageParser::default().parse(input).unwrap();
99 let mut iter = message.headers_raw();
100 assert_eq!(
101 iter.next().unwrap(),
102 ("From", " Art Vandelay <art@vandelay.com>\n")
103 );
104 assert_eq!(iter.next().unwrap(), ("To", " jane@example.com\n"));
105 assert_eq!(
106 iter.next().unwrap(),
107 ("Date", " Sat, 20 Nov 2021 14:22:01 -0800\n")
108 );
109 assert_eq!(
110 iter.next().unwrap(),
111 (
112 "Subject",
113 " Why not both importing AND exporting? =?utf-8?b?4pi6?=\n"
114 )
115 );
116 assert_eq!(
117 iter.next().unwrap(),
118 ("Content-Type", " multipart/mixed; boundary=\"festivus\";\n")
119 );
120 }
121}