1macro_rules! def_cclass {
7 ( $typ:ident, $test:ident) => {
8 #[derive(Debug, Clone, PartialEq)]
9 pub struct $typ(pub Vec<u8>);
10 impl Parsable for $typ {
11 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
12 let mut pos: usize = 0;
13 let mut output: Vec<u8> = Vec::new();
14 while pos < input.len() && $test(input[pos]) {
15 output.push(input[pos]);
16 pos += 1;
17 }
18 if output.len() > 0 {
19 Ok( ($typ(output), &input[pos..]) )
20 }
21 else {
22 if pos >= input.len() { Err( ParseError::Eof("$typ") ) }
23 else { Err( ParseError::NotFound("$typ") ) }
24 }
25 }
26 }
27 impl Streamable for $typ {
28 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
29 Ok(w.write(&self.0[..])?)
30 }
31 }
32 };
33}
34
35macro_rules! parse {
38 ($pth:ident, $rem:ident) => {
39 {
40 $pth::parse($rem).map(|(value, r)| { $rem = r; value })
41 }
42 };
43}
44
45macro_rules! req {
46 ($rem:ident, $bytes:expr, $input:ident) => {
47 let len: usize = $bytes.len();
48 if $rem.len() < len {
49 return Err(ParseError::Eof("$bytes"));
50 }
51 if &$rem[0..len] != $bytes {
52 return Err(ParseError::Expected($bytes.to_vec()));
53 }
54 $rem = &$rem[len..];
55 };
56}
57
58macro_rules! impl_display {
59 ($t:ty) => {
60 impl ::std::fmt::Display for $t {
61 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
62 let mut output: Vec<u8> = Vec::new();
63 if let Err(_) = self.stream(&mut output) {
64 return Err(::std::fmt::Error);
65 }
66 unsafe {
67 write!(f, "{}", ::std::str::from_utf8_unchecked(&*output))
69 }
70 }
71 }
72 }
73}
74
75pub mod error;
76pub use self::error::ParseError;
77pub mod types;
78pub mod headers;
79pub mod email_address;
80
81use std::io::Write;
82use std::io::Error as IoError;
83use buf_read_ext::BufReadExt;
84use ::TryFrom;
85use self::headers::{Return, Received};
86use self::headers::{ResentDate, ResentFrom, ResentSender, ResentTo, ResentCc, ResentBcc,
87 ResentMessageId};
88use self::headers::{OrigDate, From, Sender, ReplyTo, To, Cc, Bcc, MessageId, InReplyTo,
89 References, Subject, Comments, Keywords, OptionalField};
90
91pub trait Parsable: Sized {
92 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError>;
95}
96
97pub trait Streamable {
98 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError>;
100}
101
102#[derive(Debug, Clone, PartialEq)]
106pub struct Trace {
107 return_path: Option<Return>,
108 received: Vec<Received>
109}
110impl Parsable for Trace {
111 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
112 let mut rem = input;
113 let maybe_return = parse!(Return, rem).ok();
114 let mut received: Vec<Received> = Vec::new();
115 while let Ok(r) = parse!(Received, rem) {
116 received.push(r);
117 }
118 if received.len() < 1 { return Err(ParseError::NotFound("Trace")); }
119 Ok((Trace {
120 return_path: maybe_return,
121 received: received,
122 }, rem))
123 }
124}
125impl Streamable for Trace {
126 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
127 let mut count: usize = 0;
128 if let Some(ref rp) = self.return_path {
129 count += rp.stream(w)?;
130 }
131 for r in &self.received {
132 count += r.stream(w)?;
133 }
134 Ok(count)
135 }
136}
137impl_display!(Trace);
138
139#[derive(Debug, Clone, PartialEq)]
140pub enum ResentField {
141 Date(ResentDate),
142 From(ResentFrom),
143 Sender(ResentSender),
144 To(ResentTo),
145 Cc(ResentCc),
146 Bcc(ResentBcc),
147 MessageId(ResentMessageId),
148}
149impl Parsable for ResentField {
150 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
151 let mut rem = input;
152 if let Ok(x) = parse!(ResentDate, rem) {
153 return Ok((ResentField::Date(x), rem));
154 }
155 if let Ok(x) = parse!(ResentFrom, rem) {
156 return Ok((ResentField::From(x), rem));
157 }
158 if let Ok(x) = parse!(ResentSender, rem) {
159 return Ok((ResentField::Sender(x), rem));
160 }
161 if let Ok(x) = parse!(ResentTo, rem) {
162 return Ok((ResentField::To(x), rem));
163 }
164 if let Ok(x) = parse!(ResentCc, rem) {
165 return Ok((ResentField::Cc(x), rem));
166 }
167 if let Ok(x) = parse!(ResentBcc, rem) {
168 return Ok((ResentField::Bcc(x), rem));
169 }
170 if let Ok(x) = parse!(ResentMessageId, rem) {
171 return Ok((ResentField::MessageId(x), rem));
172 }
173 Err(ParseError::NotFound("Resent-Field"))
174 }
175}
176impl Streamable for ResentField {
177 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
178 match *self {
179 ResentField::Date(ref x) => x.stream(w),
180 ResentField::From(ref x) => x.stream(w),
181 ResentField::Sender(ref x) => x.stream(w),
182 ResentField::To(ref x) => x.stream(w),
183 ResentField::Cc(ref x) => x.stream(w),
184 ResentField::Bcc(ref x) => x.stream(w),
185 ResentField::MessageId(ref x) => x.stream(w),
186 }
187 }
188}
189impl_display!(ResentField);
190
191#[derive(Debug, Clone, PartialEq)]
194pub enum Field {
195 OrigDate(OrigDate),
196 From(From),
197 Sender(Sender),
198 ReplyTo(ReplyTo),
199 To(To),
200 Cc(Cc),
201 Bcc(Bcc),
202 MessageId(MessageId),
203 InReplyTo(InReplyTo),
204 References(References),
205 Subject(Subject),
206 Comments(Comments),
207 Keywords(Keywords),
208 OptionalField(OptionalField),
209}
210impl Parsable for Field {
211 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
212 let mut rem = input;
213 if let Ok(x) = parse!(OrigDate, rem) {
214 return Ok((Field::OrigDate(x), rem));
215 }
216 if let Ok(x) = parse!(From, rem) {
217 return Ok((Field::From(x), rem));
218 }
219 if let Ok(x) = parse!(Sender, rem) {
220 return Ok((Field::Sender(x), rem));
221 }
222 if let Ok(x) = parse!(ReplyTo, rem) {
223 return Ok((Field::ReplyTo(x), rem));
224 }
225 if let Ok(x) = parse!(To, rem) {
226 return Ok((Field::To(x), rem));
227 }
228 if let Ok(x) = parse!(Cc, rem) {
229 return Ok((Field::Cc(x), rem));
230 }
231 if let Ok(x) = parse!(Bcc, rem) {
232 return Ok((Field::Bcc(x), rem));
233 }
234 if let Ok(x) = parse!(MessageId, rem) {
235 return Ok((Field::MessageId(x), rem));
236 }
237 if let Ok(x) = parse!(InReplyTo, rem) {
238 return Ok((Field::InReplyTo(x), rem));
239 }
240 if let Ok(x) = parse!(References, rem) {
241 return Ok((Field::References(x), rem));
242 }
243 if let Ok(x) = parse!(Subject, rem) {
244 return Ok((Field::Subject(x), rem));
245 }
246 if let Ok(x) = parse!(Comments, rem) {
247 return Ok((Field::Comments(x), rem));
248 }
249 if let Ok(x) = parse!(Keywords, rem) {
250 return Ok((Field::Keywords(x), rem));
251 }
252 if let Ok(x) = parse!(OptionalField, rem) {
253 return Ok((Field::OptionalField(x), rem));
254 }
255 Err(ParseError::NotFound("Field"))
256 }
257}
258impl Streamable for Field {
259 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
260 match *self {
261 Field::OrigDate(ref x) => x.stream(w),
262 Field::From(ref x) => x.stream(w),
263 Field::Sender(ref x) => x.stream(w),
264 Field::ReplyTo(ref x) => x.stream(w),
265 Field::To(ref x) => x.stream(w),
266 Field::Cc(ref x) => x.stream(w),
267 Field::Bcc(ref x) => x.stream(w),
268 Field::MessageId(ref x) => x.stream(w),
269 Field::InReplyTo(ref x) => x.stream(w),
270 Field::References(ref x) => x.stream(w),
271 Field::Subject(ref x) => x.stream(w),
272 Field::Comments(ref x) => x.stream(w),
273 Field::Keywords(ref x) => x.stream(w),
274 Field::OptionalField(ref x) => x.stream(w),
275 }
276 }
277}
278impl_display!(Field);
279
280#[derive(Debug, Clone, PartialEq)]
283pub struct ResentTraceBlock {
284 pub trace: Trace,
285 pub resent_fields: Vec<ResentField>,
286}
287impl Parsable for ResentTraceBlock {
288 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
289 let mut rem = input;
290 if let Ok(t) = parse!(Trace, rem) {
291 let mut fields: Vec<ResentField> = Vec::new();
292 while let Ok(f) = parse!(ResentField, rem) {
293 fields.push(f);
294 }
295 if fields.len() == 0 {
296 Err(ParseError::ExpectedType("Resent Field"))
297 } else {
298 Ok((ResentTraceBlock {
299 trace: t,
300 resent_fields: fields
301 }, rem))
302 }
303 } else {
304 Err(ParseError::NotFound("Resent Trace Block"))
305 }
306 }
307}
308impl Streamable for ResentTraceBlock {
309 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
310 let mut count: usize = 0;
311 count += self.trace.stream(w)?;
312 for field in &self.resent_fields {
313 count += field.stream(w)?;
314 }
315 Ok(count)
316 }
317}
318impl_display!(ResentTraceBlock);
319
320#[derive(Debug, Clone, PartialEq)]
323pub struct OptTraceBlock {
324 pub trace: Trace,
325 pub opt_fields: Vec<OptionalField>,
326}
327impl Parsable for OptTraceBlock {
328 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
329 let mut rem = input;
330 if let Ok(t) = parse!(Trace, rem) {
331 let mut fields: Vec<OptionalField> = Vec::new();
332 while let Ok(f) = parse!(OptionalField, rem) {
333 fields.push(f);
334 }
335 if fields.len() == 0 {
336 Err(ParseError::ExpectedType("Optional Field"))
337 } else {
338 Ok((OptTraceBlock {
339 trace: t,
340 opt_fields: fields
341 }, rem))
342 }
343 } else {
344 Err(ParseError::NotFound("Opt Trace Block"))
345 }
346 }
347}
348impl Streamable for OptTraceBlock {
349 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
350 let mut count: usize = 0;
351 count += self.trace.stream(w)?;
352 for field in &self.opt_fields {
353 count += field.stream(w)?;
354 }
355 Ok(count)
356 }
357}
358impl_display!(OptTraceBlock);
359
360#[derive(Debug, Clone, PartialEq)]
363pub enum TraceBlock {
364 Resent(ResentTraceBlock),
365 Opt(OptTraceBlock),
366}
367impl Parsable for TraceBlock {
368 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
369 let mut rem = input;
370 if let Ok(block) = parse!(ResentTraceBlock, rem) {
371 Ok((TraceBlock::Resent(block), rem))
372 }
373 else if let Ok(block) = parse!(OptTraceBlock, rem) {
374 Ok((TraceBlock::Opt(block), rem))
375 }
376 else {
377 Err(ParseError::NotFound("Trace Block"))
378 }
379 }
380}
381impl Streamable for TraceBlock {
382 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
383 match *self {
384 TraceBlock::Resent(ref block) => block.stream(w),
385 TraceBlock::Opt(ref block) => block.stream(w),
386 }
387 }
388}
389impl_display!(TraceBlock);
390
391#[derive(Debug, Clone, PartialEq)]
416pub struct Fields {
417 pub trace_blocks: Vec<TraceBlock>,
418 pub fields: Vec<Field>,
419}
420impl Parsable for Fields {
421 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
422 let mut rem = input;
423 let mut trace_blocks: Vec<TraceBlock> = Vec::new();
424 while let Ok(tb) = parse!(TraceBlock, rem) {
425 trace_blocks.push(tb);
426 }
427 let mut fields: Vec<Field> = Vec::new();
428 while let Ok(f) = parse!(Field, rem) {
429 fields.push(f);
430 }
431 Ok((Fields {
432 trace_blocks: trace_blocks,
433 fields: fields,
434 }, rem))
435 }
436}
437impl Streamable for Fields {
438 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
439 let mut count: usize = 0;
440 for tb in &self.trace_blocks {
441 count += tb.stream(w)?;
442 }
443 for f in &self.fields {
444 count += f.stream(w)?;
445 }
446 Ok(count)
447 }
448}
449impl_display!(Fields);
450
451#[inline]
457pub fn is_text(c: u8) -> bool {
458 (c>=1 && c<=9) || c==11 || c==12 || (c>=14 && c<=127)
459}
460def_cclass!(Text, is_text);
461
462#[derive(Debug, Clone, PartialEq)]
465pub struct Body(pub Vec<u8>);
468impl Parsable for Body {
469 fn parse(mut input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
470 let mut body: Vec<u8> = Vec::new();
471 let mut line_number: usize = 0;
472 loop {
473 line_number += 1;
474 let mut line: Vec<u8> = Vec::new();
475 match input.stream_until_token(b"\r\n", &mut line) {
476 Err(e) => return Err(ParseError::Io(e)),
477 Ok((_, found)) => {
478 let mut rem = &*line;
479 if let Ok(text) = parse!(Text, rem) {
480 if rem.len() > 0 {
481 return Err(ParseError::InvalidBodyChar(rem[0]));
482 }
483 if text.0.len() > 998 {
484 return Err(ParseError::LineTooLong(line_number));
485 }
486 body.extend(text.0.clone());
487 }
488 if !found { break; } else { body.extend_from_slice(b"\r\n"); }
490 }
491 }
492 }
493 Ok((Body(body), input))
494 }
495}
496impl Streamable for Body {
497 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
498 w.write(&self.0)
499 }
500}
501impl<'a> TryFrom<&'a [u8]> for Body {
502 type Error = ParseError;
503 fn try_from(input: &'a [u8]) -> Result<Body, ParseError> {
504 let (out,rem) = Body::parse(input)?;
505 if rem.len() > 0 {
506 Err(ParseError::TrailingInput("Body", input.len() - rem.len()))
507 } else {
508 Ok(out)
509 }
510 }
511}
512impl<'a> TryFrom<&'a str> for Body {
513 type Error = ParseError;
514 fn try_from(input: &'a str) -> Result<Body, ParseError> {
515 TryFrom::try_from(input.as_bytes())
516 }
517}
518impl_display!(Body);
519
520#[derive(Debug, Clone, PartialEq)]
524pub struct Message {
525 pub fields: Fields,
526 pub body: Option<Body>
527}
528impl Parsable for Message {
529 fn parse(input: &[u8]) -> Result<(Self, &[u8]), ParseError> {
530 let mut rem = input;
531 if let Ok(fields) = parse!(Fields, rem) {
532 if &rem[..2] != b"\r\n" {
533 return Ok((Message {
534 fields: fields,
535 body: None,
536 }, rem));
537 }
538 rem = &rem[2..];
539 parse!(Body, rem).map(|b| (Message {
540 fields: fields,
541 body: Some(b),
542 }, rem))
543 } else {
544 Err(ParseError::NotFound("Message"))
545 }
546 }
547}
548impl Streamable for Message {
549 fn stream<W: Write>(&self, w: &mut W) -> Result<usize, IoError> {
550 let mut count: usize = 0;
551 count += self.fields.stream(w)?;
552 if let Some(ref body) = self.body {
553 count += w.write(b"\r\n")?;
554 count += body.stream(w)?;
555 }
556 Ok(count)
557 }
558}
559impl_display!(Message);