1
2use std::io::Write;
3use std::io::Error as IoError;
4use ::TryFrom;
5use super::{Parsable, ParseError, Streamable};
6use super::types::{DateTime, MailboxList, Mailbox, AddressList, CFWS, MsgId,
7 Unstructured, Phrase, ReceivedToken, Path, FieldName};
8
9macro_rules! req_name {
10 ($rem:ident, $str:expr) => {
11 let len: usize = $str.as_bytes().len();
12 if $rem.len() < len ||
13 &(&$rem[0..len]).to_ascii_lowercase().as_slice() != &$str.as_bytes()
14 {
15 return Err(ParseError::NotFound($str));
16 }
17 $rem = &$rem[len..];
18 };
19}
20
21macro_rules! req_crlf {
22 ($rem:ident) => {
23 if $rem.len() < 2 {
24 return Err(ParseError::NotFound("CRLF"));
25 }
26 if &$rem[..2] != b"\r\n" {
27 return Err(ParseError::NotFound("CRLF"));
28 }
29 $rem = &$rem[2..];
30 }
31}
32
33macro_rules! impl_try_from {
34 ($from:ident, $to:ident) => {
35 impl<'a> TryFrom<&'a [u8]> for $to {
36 type Error = ParseError;
37 fn try_from(input: &'a [u8]) -> Result<$to, ParseError> {
38 let (out,rem) = $from::parse(input)?;
39 if rem.len() > 0 {
40 return Err(ParseError::TrailingInput("$to", input.len() - rem.len()));
41 }
42 Ok($to(out))
43 }
44 }
45 impl<'a> TryFrom<&'a str> for $to {
46 type Error = ParseError;
47 fn try_from(input: &'a str) -> Result<$to, ParseError> {
48 TryFrom::try_from(input.as_bytes())
49 }
50 }
51 impl<'a> TryFrom<$from> for $to {
52 type Error = ParseError;
53 fn try_from(input: $from) -> Result<$to, ParseError> {
54 Ok($to(input))
55 }
56 }
57 }
58}
59
60#[derive(Debug, Clone, PartialEq)]
63pub struct OrigDate(pub DateTime);
64impl Parsable for OrigDate {
65 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
66 if input.len() == 0 { return Err(ParseError::Eof("Date")); }
67 let mut rem = input;
68 req_name!(rem, "date:");
69 match parse!(DateTime, rem) {
70 Ok(dt) => {
71 req_crlf!(rem);
72 Ok((OrigDate(dt), rem))
73 },
74 Err(e) => Err(ParseError::Parse("Date", Box::new(e)))
75 }
76 }
77}
78impl Streamable for OrigDate {
79 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
80 Ok(w.write(b"Date:")?
81 + self.0.stream(w)?
82 + w.write(b"\r\n")?)
83 }
84}
85impl_try_from!(DateTime, OrigDate);
86#[cfg(feature="time")]
87impl<'a> TryFrom<&'a ::time::Tm> for OrigDate {
88 type Error = ParseError;
89 fn try_from(input: &'a ::time::Tm) -> Result<OrigDate, ParseError> {
90 let s = match input.strftime("%a, %d %b %Y %T %z") {
91 Ok(s) => format!("{}",s),
92 Err(_) => return Err(ParseError::InternalError),
93 };
94 TryFrom::try_from(s.as_bytes())
95 }
96}
97#[cfg(feature="chrono")]
98impl<'a, Tz: ::chrono::TimeZone> TryFrom<&'a ::chrono::DateTime<Tz>> for OrigDate
99 where Tz::Offset: ::std::fmt::Display
100{
101 type Error = ParseError;
102 fn try_from(input: &'a ::chrono::DateTime<Tz>) -> Result<OrigDate, ParseError> {
103 let s = input.format("%a, %d %b %Y %T %z").to_string();
104 TryFrom::try_from(s.as_bytes())
105 }
106}
107impl_display!(OrigDate);
108
109#[derive(Debug, Clone, PartialEq)]
112pub struct From(pub MailboxList);
113impl Parsable for From {
114 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
115 if input.len() == 0 { return Err(ParseError::Eof("From")); }
116 let mut rem = input;
117 req_name!(rem, "from:");
118 match parse!(MailboxList, rem) {
119 Ok(mbl) => {
120 req_crlf!(rem);
121 return Ok((From(mbl), rem));
122 },
123 Err(e) => Err(ParseError::Parse("From", Box::new(e)))
124 }
125 }
126}
127impl Streamable for From {
128 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
129 Ok(w.write(b"From:")?
130 + self.0.stream(w)?
131 + w.write(b"\r\n")?)
132 }
133}
134impl_try_from!(MailboxList, From);
135impl_display!(From);
136
137#[derive(Debug, Clone, PartialEq)]
140pub struct Sender(pub Mailbox);
141impl Parsable for Sender {
142 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
143 if input.len() == 0 { return Err(ParseError::Eof("Sender")); }
144 let mut rem = input;
145 req_name!(rem, "sender:");
146 match parse!(Mailbox, rem) {
147 Ok(mb) => {
148 req_crlf!(rem);
149 return Ok((Sender(mb), rem));
150 },
151 Err(e) => Err(ParseError::Parse("Sender", Box::new(e)))
152 }
153 }
154}
155impl Streamable for Sender {
156 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
157 Ok(w.write(b"Sender:")?
158 + self.0.stream(w)?
159 + w.write(b"\r\n")?)
160 }
161}
162impl_try_from!(Mailbox, Sender);
163impl_display!(Sender);
164
165#[derive(Debug, Clone, PartialEq)]
168pub struct ReplyTo(pub AddressList);
169impl Parsable for ReplyTo {
170 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
171 if input.len() == 0 { return Err(ParseError::Eof("Reply-To")); }
172 let mut rem = input;
173 req_name!(rem, "reply-to:");
174 match parse!(AddressList, rem) {
175 Ok(x) => {
176 req_crlf!(rem);
177 return Ok((ReplyTo(x), rem));
178 },
179 Err(e) => Err(ParseError::Parse("Reply-To", Box::new(e)))
180 }
181 }
182}
183impl Streamable for ReplyTo {
184 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
185 Ok(w.write(b"Reply-To:")?
186 + self.0.stream(w)?
187 + w.write(b"\r\n")?)
188 }
189}
190impl_try_from!(AddressList, ReplyTo);
191impl_display!(ReplyTo);
192
193#[derive(Debug, Clone, PartialEq)]
196pub struct To(pub AddressList);
197impl Parsable for To {
198 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
199 if input.len() == 0 { return Err(ParseError::Eof("To")); }
200 let mut rem = input;
201 req_name!(rem, "to:");
202 match parse!(AddressList, rem) {
203 Ok(x) => {
204 req_crlf!(rem);
205 return Ok((To(x), rem));
206 },
207 Err(e) => Err(ParseError::Parse("To", Box::new(e))),
208 }
209 }
210}
211impl Streamable for To {
212 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
213 Ok(w.write(b"To:")?
214 + self.0.stream(w)?
215 + w.write(b"\r\n")?)
216 }
217}
218impl_try_from!(AddressList, To);
219impl_display!(To);
220
221#[derive(Debug, Clone, PartialEq)]
224pub struct Cc(pub AddressList);
225impl Parsable for Cc {
226 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
227 if input.len() == 0 { return Err(ParseError::Eof("Cc")); }
228 let mut rem = input;
229 req_name!(rem, "cc:");
230 match parse!(AddressList, rem) {
231 Ok(x) => {
232 req_crlf!(rem);
233 return Ok((Cc(x), rem));
234 },
235 Err(e) => Err(ParseError::Parse("Cc", Box::new(e))),
236 }
237 }
238}
239impl Streamable for Cc {
240 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
241 Ok(w.write(b"Cc:")?
242 + self.0.stream(w)?
243 + w.write(b"\r\n")?)
244 }
245}
246impl_try_from!(AddressList, Cc);
247impl_display!(Cc);
248
249#[derive(Debug, Clone, PartialEq)]
252pub enum Bcc {
253 AddressList(AddressList),
254 CFWS(CFWS),
255 Empty
256}
257impl Parsable for Bcc {
258 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
259 if input.len() == 0 { return Err(ParseError::Eof("Bcc")); }
260 let mut rem = input;
261 req_name!(rem, "bcc:");
262 if let Ok(x) = parse!(AddressList, rem) {
263 req_crlf!(rem);
264 return Ok((Bcc::AddressList(x), rem));
265 }
266 if let Ok(x) = parse!(CFWS, rem) {
267 req_crlf!(rem);
268 return Ok((Bcc::CFWS(x), rem));
269 }
270 req_crlf!(rem);
271 return Ok((Bcc::Empty, rem));
272 }
273}
274impl Streamable for Bcc {
275 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
276 let mut count: usize = 0;
277 count += w.write(b"Bcc:")?;
278 count += match *self {
279 Bcc::AddressList(ref al) => al.stream(w)?,
280 Bcc::CFWS(ref cfws) => cfws.stream(w)?,
281 Bcc::Empty => 0,
282 };
283 count += w.write(b"\r\n")?;
284 Ok(count)
285 }
286}
287impl<'a> TryFrom<&'a [u8]> for Bcc {
288 type Error = ParseError;
289 fn try_from(input: &'a [u8]) -> Result<Bcc, ParseError> {
290 let (out,rem) = AddressList::parse(input)?;
291 if rem.len() > 0 {
292 return Err(ParseError::TrailingInput("Bcc", input.len() - rem.len()));
293 }
294 Ok(Bcc::AddressList(out))
295 }
296}
297impl<'a> TryFrom<&'a str> for Bcc {
298 type Error = ParseError;
299 fn try_from(input: &'a str) -> Result<Bcc, ParseError> {
300 TryFrom::try_from(input.as_bytes())
301 }
302}
303impl<'a> TryFrom<AddressList> for Bcc {
304 type Error = ParseError;
305 fn try_from(input: AddressList) -> Result<Bcc, ParseError> {
306 Ok(Bcc::AddressList(input))
307 }
308}
309impl_display!(Bcc);
310
311#[derive(Debug, Clone, PartialEq)]
314pub struct MessageId(pub MsgId);
315impl Parsable for MessageId {
316 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
317 if input.len() == 0 { return Err(ParseError::Eof("MessageId")); }
318 let mut rem = input;
319 req_name!(rem, "message-id:");
320 match parse!(MsgId, rem) {
321 Ok(x) => {
322 req_crlf!(rem);
323 return Ok((MessageId(x), rem));
324 },
325 Err(e) => Err(ParseError::Parse("Message-Id", Box::new(e))),
326 }
327 }
328}
329impl Streamable for MessageId {
330 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
331 Ok(w.write(b"Message-ID:")?
332 + self.0.stream(w)?
333 + w.write(b"\r\n")?)
334 }
335}
336impl_try_from!(MsgId, MessageId);
337impl_display!(MessageId);
338
339#[derive(Debug, Clone, PartialEq)]
342pub struct InReplyTo(pub Vec<MsgId>);
343impl Parsable for InReplyTo {
344 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
345 if input.len() == 0 { return Err(ParseError::Eof("InReplyTo")); }
346 let mut rem = input;
347 let mut contents: Vec<MsgId> = Vec::new();
348 req_name!(rem, "in-reply-to:");
349 let err;
350 loop {
351 match parse!(MsgId, rem) {
352 Ok(x) => contents.push(x),
353 Err(e) => { err = e; break; }
354 }
355 }
356 if contents.len() == 0 {
357 return Err(ParseError::Parse("In-Reply-To", Box::new(err)));
358 }
359 req_crlf!(rem);
360 Ok((InReplyTo(contents), rem))
361 }
362}
363impl Streamable for InReplyTo {
364 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
365 let mut count: usize = 0;
366 count += w.write(b"In-Reply-To:")?;
367 for msgid in &self.0 {
368 count += msgid.stream(w)?
369 }
370 count += w.write(b"\r\n")?;
371 Ok(count)
372 }
373}
374impl<'a> TryFrom<&'a [u8]> for InReplyTo {
375 type Error = ParseError;
376 fn try_from(input: &'a [u8]) -> Result<InReplyTo, ParseError> {
377 let mut msgids: Vec<MsgId> = Vec::new();
378 let mut rem = input;
379 while let Ok(x) = parse!(MsgId, rem) {
380 msgids.push(x);
381 }
382 if rem.len() > 0 {
383 Err(ParseError::TrailingInput("In-Reply-To", input.len() - rem.len()))
384 } else {
385 Ok(InReplyTo(msgids))
386 }
387 }
388}
389impl<'a> TryFrom<&'a str> for InReplyTo {
390 type Error = ParseError;
391 fn try_from(input: &'a str) -> Result<InReplyTo, ParseError> {
392 TryFrom::try_from(input.as_bytes())
393 }
394}
395impl<'a> TryFrom<Vec<MsgId>> for InReplyTo {
396 type Error = ParseError;
397 fn try_from(input: Vec<MsgId>) -> Result<InReplyTo, ParseError> {
398 Ok(InReplyTo(input))
399 }
400}
401impl_display!(InReplyTo);
402
403#[derive(Debug, Clone, PartialEq)]
406pub struct References(pub Vec<MsgId>);
407impl Parsable for References {
408 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
409 if input.len() == 0 { return Err(ParseError::Eof("References")); }
410 let mut rem = input;
411 let mut contents: Vec<MsgId> = Vec::new();
412 req_name!(rem, "references:");
413 let err;
414 loop {
415 match parse!(MsgId, rem) {
416 Ok(x) => contents.push(x),
417 Err(e) => { err = e; break }
418 }
419 }
420 if contents.len() == 0 {
421 return Err(ParseError::Parse("References", Box::new(err)));
422 }
423 req_crlf!(rem);
424 Ok((References(contents), rem))
425 }
426}
427impl Streamable for References {
428 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
429 let mut count: usize = 0;
430 count += w.write(b"References:")?;
431 for msgid in &self.0 {
432 count += msgid.stream(w)?
433 }
434 count += w.write(b"\r\n")?;
435 Ok(count)
436 }
437}
438impl<'a> TryFrom<&'a [u8]> for References {
439 type Error = ParseError;
440 fn try_from(input: &'a [u8]) -> Result<References, ParseError> {
441 let mut msgids: Vec<MsgId> = Vec::new();
442 let mut rem = input;
443 while let Ok(x) = parse!(MsgId, rem) {
444 msgids.push(x);
445 }
446 if rem.len() > 0 {
447 Err(ParseError::TrailingInput("References", input.len() - rem.len()))
448 } else {
449 Ok(References(msgids))
450 }
451 }
452}
453impl<'a> TryFrom<&'a str> for References {
454 type Error = ParseError;
455 fn try_from(input: &'a str) -> Result<References, ParseError> {
456 TryFrom::try_from(input.as_bytes())
457 }
458}
459impl<'a> TryFrom<Vec<MsgId>> for References {
460 type Error = ParseError;
461 fn try_from(input: Vec<MsgId>) -> Result<References, ParseError> {
462 Ok(References(input))
463 }
464}
465impl_display!(References);
466
467#[derive(Debug, Clone, PartialEq)]
470pub struct Subject(pub Unstructured);
471impl Parsable for Subject {
472 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
473 if input.len() == 0 { return Err(ParseError::Eof("Subject")); }
474 let mut rem = input;
475 req_name!(rem, "subject:");
476 match parse!(Unstructured, rem) {
477 Ok(x) => {
478 req_crlf!(rem);
479 return Ok((Subject(x), rem));
480 },
481 Err(e) => Err(ParseError::Parse("Subject", Box::new(e))),
482 }
483 }
484}
485impl Streamable for Subject {
486 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
487 Ok(w.write(b"Subject:")?
488 + self.0.stream(w)?
489 + w.write(b"\r\n")?)
490 }
491}
492impl_try_from!(Unstructured, Subject);
493impl_display!(Subject);
494
495#[derive(Debug, Clone, PartialEq)]
498pub struct Comments(pub Unstructured);
499impl Parsable for Comments {
500 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
501 if input.len() == 0 { return Err(ParseError::Eof("Comments")); }
502 let mut rem = input;
503 req_name!(rem, "comments:");
504 match parse!(Unstructured, rem) {
505 Ok(x) => {
506 req_crlf!(rem);
507 return Ok((Comments(x), rem));
508 },
509 Err(e) => Err(ParseError::Parse("Comments", Box::new(e))),
510 }
511 }
512}
513impl Streamable for Comments {
514 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
515 Ok(w.write(b"Comments:")?
516 + self.0.stream(w)?
517 + w.write(b"\r\n")?)
518 }
519}
520impl_try_from!(Unstructured, Comments);
521impl_display!(Comments);
522
523#[derive(Debug, Clone, PartialEq)]
526pub struct Keywords(pub Vec<Phrase>);
527impl Parsable for Keywords {
528 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
529 if input.len() == 0 { return Err(ParseError::Eof("Keywords")); }
530 let mut rem = input;
531 req_name!(rem, "keywords:");
532 let mut output: Vec<Phrase> = Vec::new();
533 let err;
534 loop {
535 match parse!(Phrase, rem) {
536 Ok(x) => output.push(x),
537 Err(e) => { err = e; break; }
538 }
539 }
540 if output.len()==0 {
541 return Err(ParseError::Parse("Keywords", Box::new(err)));
542 }
543 req_crlf!(rem);
544 Ok((Keywords(output), rem))
545 }
546}
547impl Streamable for Keywords {
548 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
549 let mut count: usize = 0;
550 count += w.write(b"Keywords:")?;
551 let mut virgin = true;
552 for phrase in &self.0 {
553 if ! virgin {
554 count += w.write(b",")?;
555 }
556 count += phrase.stream(w)?;
557 virgin = false
558 }
559 count += w.write(b"\r\n")?;
560 Ok(count)
561 }
562}
563impl<'a> TryFrom<&'a [u8]> for Keywords {
564 type Error = ParseError;
565 fn try_from(input: &'a [u8]) -> Result<Keywords, ParseError> {
566 let mut msgids: Vec<Phrase> = Vec::new();
567 let mut rem = input;
568 while let Ok(x) = parse!(Phrase, rem) {
569 msgids.push(x);
570 }
571 if rem.len() > 0 {
572 Err(ParseError::TrailingInput("Keywords", input.len() - rem.len()))
573 } else {
574 Ok(Keywords(msgids))
575 }
576 }
577}
578impl<'a> TryFrom<&'a str> for Keywords {
579 type Error = ParseError;
580 fn try_from(input: &'a str) -> Result<Keywords, ParseError> {
581 TryFrom::try_from(input.as_bytes())
582 }
583}
584impl<'a> TryFrom<Vec<Phrase>> for Keywords {
585 type Error = ParseError;
586 fn try_from(input: Vec<Phrase>) -> Result<Keywords, ParseError> {
587 Ok(Keywords(input))
588 }
589}
590impl_display!(Keywords);
591
592#[derive(Debug, Clone, PartialEq)]
595pub struct ResentDate(pub DateTime);
596impl Parsable for ResentDate {
597 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
598 if input.len() == 0 { return Err(ParseError::Eof("Resent-Date")); }
599 let mut rem = input;
600 req_name!(rem, "resent-date:");
601 match parse!(DateTime, rem) {
602 Ok(dt) => {
603 req_crlf!(rem);
604 Ok((ResentDate(dt), rem))
605 },
606 Err(e) => Err(ParseError::Parse("Resent-Date", Box::new(e)))
607 }
608 }
609}
610impl Streamable for ResentDate {
611 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
612 Ok(w.write(b"Resent-Date:")?
613 + self.0.stream(w)?
614 + w.write(b"\r\n")?)
615 }
616}
617impl_try_from!(DateTime, ResentDate);
618impl_display!(ResentDate);
619
620#[derive(Debug, Clone, PartialEq)]
623pub struct ResentFrom(pub MailboxList);
624impl Parsable for ResentFrom {
625 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
626 if input.len() == 0 { return Err(ParseError::Eof("Resent-From")); }
627 let mut rem = input;
628 req_name!(rem, "resent-from:");
629 match parse!(MailboxList, rem) {
630 Ok(mbl) => {
631 req_crlf!(rem);
632 return Ok((ResentFrom(mbl), rem));
633 },
634 Err(e) => Err(ParseError::Parse("Resent-From", Box::new(e))),
635 }
636 }
637}
638impl Streamable for ResentFrom {
639 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
640 Ok(w.write(b"Resent-From:")?
641 + self.0.stream(w)?
642 + w.write(b"\r\n")?)
643 }
644}
645impl_try_from!(MailboxList, ResentFrom);
646impl_display!(ResentFrom);
647
648#[derive(Debug, Clone, PartialEq)]
651pub struct ResentSender(pub Mailbox);
652impl Parsable for ResentSender {
653 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
654 if input.len() == 0 { return Err(ParseError::Eof("Resent-Sender")); }
655 let mut rem = input;
656 req_name!(rem, "resent-sender:");
657 match parse!(Mailbox, rem) {
658 Ok(mb) => {
659 req_crlf!(rem);
660 return Ok((ResentSender(mb), rem));
661 },
662 Err(e) => Err(ParseError::Parse("Resent-Sender", Box::new(e))),
663 }
664 }
665}
666impl Streamable for ResentSender {
667 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
668 Ok(w.write(b"Resent-Sender:")?
669 + self.0.stream(w)?
670 + w.write(b"\r\n")?)
671 }
672}
673impl_try_from!(Mailbox, ResentSender);
674impl_display!(ResentSender);
675
676#[derive(Debug, Clone, PartialEq)]
679pub struct ResentTo(pub AddressList);
680impl Parsable for ResentTo {
681 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
682 if input.len() == 0 { return Err(ParseError::Eof("Resent-To")); }
683 let mut rem = input;
684 req_name!(rem, "resent-to:");
685 match parse!(AddressList, rem) {
686 Ok(x) => {
687 req_crlf!(rem);
688 return Ok((ResentTo(x), rem));
689 },
690 Err(e) => Err(ParseError::Parse("Resent-To", Box::new(e))),
691 }
692 }
693}
694impl Streamable for ResentTo {
695 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
696 Ok(w.write(b"Resent-To:")?
697 + self.0.stream(w)?
698 + w.write(b"\r\n")?)
699 }
700}
701impl_try_from!(AddressList, ResentTo);
702impl_display!(ResentTo);
703
704#[derive(Debug, Clone, PartialEq)]
707pub struct ResentCc(pub AddressList);
708impl Parsable for ResentCc {
709 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
710 if input.len() == 0 { return Err(ParseError::Eof("Resent-Cc")); }
711 let mut rem = input;
712 req_name!(rem, "resent-cc:");
713 match parse!(AddressList, rem) {
714 Ok(x) => {
715 req_crlf!(rem);
716 return Ok((ResentCc(x), rem));
717 },
718 Err(e) => Err(ParseError::Parse("Resent-Cc", Box::new(e)))
719 }
720 }
721}
722impl Streamable for ResentCc {
723 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
724 Ok(w.write(b"Resent-Cc:")?
725 + self.0.stream(w)?
726 + w.write(b"\r\n")?)
727 }
728}
729impl_try_from!(AddressList, ResentCc);
730impl_display!(ResentCc);
731
732#[derive(Debug, Clone, PartialEq)]
735pub enum ResentBcc {
736 AddressList(AddressList),
737 CFWS(CFWS),
738 Empty
739}
740impl Parsable for ResentBcc {
741 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
742 if input.len() == 0 { return Err(ParseError::Eof("Resent-Bcc")); }
743 let mut rem = input;
744 req_name!(rem, "resent-bcc:");
745 if let Ok(x) = parse!(AddressList, rem) {
746 req_crlf!(rem);
747 return Ok((ResentBcc::AddressList(x), rem));
748 }
749 if let Ok(x) = parse!(CFWS, rem) {
750 req_crlf!(rem);
751 return Ok((ResentBcc::CFWS(x), rem));
752 }
753 req_crlf!(rem);
754 return Ok((ResentBcc::Empty, rem));
755 }
756}
757impl Streamable for ResentBcc {
758 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
759 let mut count: usize = 0;
760 count += w.write(b"Resent-Bcc:")?;
761 count += match *self {
762 ResentBcc::AddressList(ref al) => al.stream(w)?,
763 ResentBcc::CFWS(ref cfws) => cfws.stream(w)?,
764 ResentBcc::Empty => 0,
765 };
766 count += w.write(b"\r\n")?;
767 Ok(count)
768 }
769}
770impl<'a> TryFrom<&'a [u8]> for ResentBcc {
771 type Error = ParseError;
772 fn try_from(input: &'a [u8]) -> Result<ResentBcc, ParseError> {
773 let (out,rem) = AddressList::parse(input)?;
774 if rem.len() > 0 {
775 return Err(ParseError::TrailingInput("Resent-Bcc", input.len() - rem.len()));
776 }
777 Ok(ResentBcc::AddressList(out))
778 }
779}
780impl<'a> TryFrom<&'a str> for ResentBcc {
781 type Error = ParseError;
782 fn try_from(input: &'a str) -> Result<ResentBcc, ParseError> {
783 TryFrom::try_from(input.as_bytes())
784 }
785}
786impl<'a> TryFrom<AddressList> for ResentBcc {
787 type Error = ParseError;
788 fn try_from(input: AddressList) -> Result<ResentBcc, ParseError> {
789 Ok(ResentBcc::AddressList(input))
790 }
791}
792impl_display!(ResentBcc);
793
794#[derive(Debug, Clone, PartialEq)]
797pub struct ResentMessageId(pub MsgId);
798impl Parsable for ResentMessageId {
799 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
800 if input.len() == 0 { return Err(ParseError::Eof("Resent-Message-ID")); }
801 let mut rem = input;
802 req_name!(rem, "resent-message-id:");
803 match parse!(MsgId, rem) {
804 Ok(x) => {
805 req_crlf!(rem);
806 return Ok((ResentMessageId(x), rem));
807 },
808 Err(e) => Err(ParseError::Parse("Resent-Message-Id", Box::new(e))),
809 }
810 }
811}
812impl Streamable for ResentMessageId {
813 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
814 Ok(w.write(b"Resent-Message-ID:")?
815 + self.0.stream(w)?
816 + w.write(b"\r\n")?)
817 }
818}
819impl_try_from!(MsgId, ResentMessageId);
820impl_display!(ResentMessageId);
821
822#[derive(Debug, Clone, PartialEq)]
828pub enum ReceivedTokens {
829 Tokens(Vec<ReceivedToken>),
830 Comment(CFWS),
831}
832#[derive(Debug, Clone, PartialEq)]
833pub struct Received {
834 pub received_tokens: ReceivedTokens,
835 pub date_time: DateTime,
836}
837impl Parsable for Received {
838 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
839 if input.len() == 0 { return Err(ParseError::Eof("Received")); }
840 let mut rem = input;
841 req_name!(rem, "received:");
842 let mut tokens: Vec<ReceivedToken> = Vec::new();
843 let err;
844 loop {
845 match parse!(ReceivedToken, rem) {
846 Ok(r) => tokens.push(r),
847 Err(e) => { err = e; break; }
848 }
849 }
850 let received_tokens = if tokens.len()==0 {
851 if let Ok(cfws) = parse!(CFWS, rem) {
852 ReceivedTokens::Comment(cfws)
853 } else {
854 return Err(ParseError::Parse("Received", Box::new(err)));
855 }
856 } else {
857 ReceivedTokens::Tokens(tokens)
858 };
859 req!(rem, b";", input);
860 match parse!(DateTime, rem) {
861 Ok(dt) => {
862 req_crlf!(rem);
863 return Ok((Received {
864 received_tokens: received_tokens,
865 date_time: dt
866 }, rem));
867 },
868 Err(e) => Err(ParseError::Parse("Received", Box::new(e))),
869 }
870 }
871}
872impl Streamable for Received {
873 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
874 let mut count: usize = 0;
875 count += w.write(b"Received:")?;
876 match self.received_tokens {
877 ReceivedTokens::Tokens(ref vec) => {
878 for token in vec {
879 count += token.stream(w)?;
880 }
881 },
882 ReceivedTokens::Comment(ref c) => {
883 count += c.stream(w)?;
884 },
885 }
886 count += w.write(b";")?;
887 count += self.date_time.stream(w)?;
888 count += w.write(b"\r\n")?;
889 Ok(count)
890 }
891}
892impl<'a> TryFrom<&'a [u8]> for Received {
893 type Error = ParseError;
894 fn try_from(input: &'a [u8]) -> Result<Received, ParseError> {
895 let mut fudged_input: Vec<u8> = "Received:".as_bytes().to_owned();
896 fudged_input.extend(&*input);
897 fudged_input.extend("\r\n".as_bytes());
898 let (out,rem) = Received::parse(input)?;
899 if rem.len() > 0 {
900 return Err(ParseError::TrailingInput("Received", input.len() - rem.len()));
901 } else {
902 Ok(out)
903 }
904 }
905}
906impl<'a> TryFrom<&'a str> for Received {
907 type Error = ParseError;
908 fn try_from(input: &'a str) -> Result<Received, ParseError> {
909 TryFrom::try_from(input.as_bytes())
910 }
911}
912impl<'a> TryFrom<(ReceivedTokens, DateTime)> for Received {
913 type Error = ParseError;
914 fn try_from(input: (ReceivedTokens, DateTime)) -> Result<Received, ParseError> {
915 Ok(Received {
916 received_tokens: input.0,
917 date_time: input.1 })
918 }
919}
920impl_display!(Received);
921
922#[derive(Debug, Clone, PartialEq)]
925pub struct Return(pub Path);
926impl Parsable for Return {
927 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
928 let mut rem = input;
929 req_name!(rem, "return-path:");
930 match parse!(Path, rem) {
931 Ok(path) => {
932 req_crlf!(rem);
933 return Ok((Return(path), rem));
934 },
935 Err(e) => Err(ParseError::Parse("Return-Path", Box::new(e))),
936 }
937 }
938}
939impl Streamable for Return {
940 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
941 Ok(w.write(b"Return-Path:")?
942 + self.0.stream(w)?
943 + w.write(b"\r\n")?)
944 }
945}
946impl_try_from!(Path, Return);
947impl_display!(Return);
948
949#[derive(Debug, Clone, PartialEq)]
952pub struct OptionalField {
953 pub name: FieldName,
954 pub value: Unstructured,
955}
956impl Parsable for OptionalField {
957 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
958 let mut rem = input;
959
960 match parse!(FieldName, rem) {
961 Ok(name) => {
962 req!(rem, b":", input);
963 match parse!(Unstructured, rem) {
964 Ok(value) => {
965 req_crlf!(rem);
966 return Ok((OptionalField {
967 name: name,
968 value: value,
969 }, rem));
970 },
971 Err(e) => Err(ParseError::Parse("Optional Field", Box::new(e))),
972 }
973 },
974 Err(e) => Err(ParseError::Parse("Optional Field", Box::new(e))),
975 }
976 }
977}
978impl Streamable for OptionalField {
979 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
980 Ok(self.name.stream(w)?
981 + w.write(b":")?
982 + self.value.stream(w)?
983 + w.write(b"\r\n")?)
984 }
985}
986impl<'a> TryFrom<(FieldName, Unstructured)> for OptionalField {
987 type Error = ParseError;
988 fn try_from(input: (FieldName, Unstructured)) -> Result<OptionalField, ParseError> {
989 Ok(OptionalField {
990 name: input.0,
991 value: input.1 })
992 }
993}
994impl<'a,'b> TryFrom<(&'a [u8], &'b [u8])> for OptionalField {
995 type Error = ParseError;
996 fn try_from(input: (&'a [u8], &'b [u8])) -> Result<OptionalField, ParseError> {
997 let (name,rem) = FieldName::parse(input.0)?;
998 if rem.len() > 0 {
999 return Err(ParseError::TrailingInput("Optional Field", input.0.len() - rem.len()));
1000 }
1001 let (value,rem) = Unstructured::parse(input.1)?;
1002 if rem.len() > 0 {
1003 return Err(ParseError::TrailingInput("Optional Field", input.1.len() - rem.len()));
1004 }
1005 Ok(OptionalField {
1006 name: name,
1007 value: value,
1008 })
1009 }
1010}
1011impl<'a,'b> TryFrom<(&'a str, &'b str)> for OptionalField {
1012 type Error = ParseError;
1013 fn try_from(input: (&'a str, &'b str)) -> Result<OptionalField, ParseError> {
1014 TryFrom::try_from((input.0.as_bytes(), input.1.as_bytes()))
1015 }
1016}
1017impl_display!(OptionalField);