mail_parser/parsers/fields/
id.rs1use crate::{parsers::MessageStream, HeaderValue};
8
9impl<'x> MessageStream<'x> {
10 pub fn parse_id(&mut self) -> HeaderValue<'x> {
11 let mut token_start: usize = 0;
12 let mut token_end: usize = 0;
13 let mut token_invalid_start: usize = 0; let mut token_invalid_end: usize = 0; let mut is_id_part = false;
16 let mut ids = Vec::new();
17
18 while let Some(&ch) = self.next() {
19 match ch {
20 b'\n' => {
21 if !self.try_next_is_space() {
22 return match ids.len() {
23 1 => HeaderValue::Text(ids.pop().unwrap()),
24 0 => {
25 if token_invalid_start > 0 {
26 HeaderValue::Text(String::from_utf8_lossy(
27 self.bytes(token_invalid_start - 1..token_invalid_end),
28 ))
29 } else {
30 HeaderValue::Empty
31 }
32 }
33 _ => HeaderValue::TextList(ids),
34 };
35 } else {
36 continue;
37 }
38 }
39 b'<' => {
40 is_id_part = true;
41 continue;
42 }
43 b'>' => {
44 is_id_part = false;
45 if token_start > 0 {
46 ids.push(String::from_utf8_lossy(
47 self.bytes(token_start - 1..token_end),
48 ));
49 token_start = 0;
50 } else {
51 continue;
52 }
53 }
54 b' ' | b'\t' | b'\r' => continue,
55 _ => {}
56 }
57 if is_id_part {
58 if token_start == 0 {
59 token_start = self.offset();
60 }
61 token_end = self.offset();
62 } else {
63 if token_invalid_start == 0 {
64 token_invalid_start = self.offset();
65 }
66 token_invalid_end = self.offset();
67 }
68 }
69
70 HeaderValue::Empty
71 }
72}
73#[cfg(test)]
74mod tests {
75 use std::borrow::Cow;
76
77 use crate::parsers::{fields::load_tests, MessageStream};
78
79 #[test]
80 fn parse_message_ids() {
81 for test in load_tests::<Option<Vec<Cow<'static, str>>>>("id.json") {
82 assert_eq!(
83 MessageStream::new(test.header.as_bytes())
84 .parse_id()
85 .into_text_list(),
86 test.expected,
87 "failed for {:?}",
88 test.header
89 );
90 }
91 }
92}