Skip to content
This repository was archived by the owner on Jul 22, 2019. It is now read-only.

Commit 5b9dc9b

Browse files
committed
Add basic support for parsing the BODY attribute
1 parent 5b87dba commit 5b9dc9b

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

src/parser.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,53 @@ named!(flag_perm<&str>, alt!(
162162
flag
163163
));
164164

165+
named!(section_part<Vec<u32>>, do_parse!(
166+
part: number >>
167+
rest: many0!(do_parse!(
168+
tag_s!(".") >>
169+
part: number >>
170+
(part)
171+
)) >> ({
172+
let mut res = vec![part];
173+
res.extend(rest);
174+
res
175+
})
176+
));
177+
178+
named!(section_msgtext<MessageSection>, map!(
179+
alt!(tag_s!("HEADER") | tag_s!("TEXT")),
180+
|s| match s {
181+
b"HEADER" => MessageSection::Header,
182+
b"TEXT" => MessageSection::Text,
183+
_ => panic!("cannot happen"),
184+
}
185+
));
186+
187+
named!(section_text<MessageSection>, alt!(
188+
section_msgtext |
189+
do_parse!(tag_s!("MIME") >> (MessageSection::Mime))
190+
));
191+
192+
named!(section_spec<SectionPath>, alt!(
193+
map!(section_msgtext, |val| SectionPath::Full(val)) |
194+
do_parse!(
195+
part: section_part >>
196+
text: opt!(do_parse!(
197+
tag_s!(".") >>
198+
text: section_text >>
199+
(text)
200+
)) >>
201+
(SectionPath::Part(part, text))
202+
)
203+
));
204+
205+
named!(section<Option<SectionPath>>, do_parse!(
206+
tag_s!("[") >>
207+
spec: opt!(section_spec) >>
208+
tag_s!("]") >>
209+
(spec)
210+
));
211+
165212
named!(resp_text_code_permanent_flags<ResponseCode>, do_parse!(
166213
tag_s!("PERMANENTFLAGS (") >>
167214
elements: opt!(do_parse!(
@@ -341,6 +388,20 @@ named!(opt_addresses<Option<Vec<Address>>>, alt!(
341388
)
342389
));
343390

391+
named!(msg_att_body_section<AttributeValue>, do_parse!(
392+
tag_s!("BODY") >>
393+
section: section >>
394+
index: opt!(do_parse!(
395+
tag_s!("<") >>
396+
num: number >>
397+
tag_s!(">") >>
398+
(num)
399+
)) >>
400+
tag_s!(" ") >>
401+
data: nstring >>
402+
(AttributeValue::BodySection { section, index, data })
403+
));
404+
344405
named!(msg_att_envelope<AttributeValue>, do_parse!(
345406
tag_s!("ENVELOPE (") >>
346407
date: nstring >>
@@ -416,6 +477,7 @@ named!(msg_att_uid<AttributeValue>, do_parse!(
416477
));
417478

418479
named!(msg_att<AttributeValue>, alt!(
480+
msg_att_body_section |
419481
msg_att_envelope |
420482
msg_att_internal_date |
421483
msg_att_flags |
@@ -554,4 +616,19 @@ mod tests {
554616
rsp @ _ => panic!("unexpected response {:?}", rsp),
555617
}
556618
}
619+
620+
#[test]
621+
fn test_body_text() {
622+
match parse_response(b"* 2 FETCH (BODY[TEXT] {3}\r\nfoo)\r\n") {
623+
IResult::Done(_, Response::Fetch(_, attrs)) => {
624+
let body = &attrs[0];
625+
assert_eq!(body, &AttributeValue::BodySection {
626+
section: Some(SectionPath::Full(MessageSection::Text)),
627+
index: None,
628+
data: Some(b"foo"),
629+
}, "body = {:?}", body);
630+
},
631+
rsp @ _ => panic!("unexpected response {:?}", rsp),
632+
}
633+
}
557634
}

src/types.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,26 @@ pub enum Attribute {
7777
Uid,
7878
}
7979

80+
#[derive(Debug, Eq, PartialEq)]
81+
pub enum MessageSection {
82+
Header,
83+
Mime,
84+
Text,
85+
}
86+
87+
#[derive(Debug, Eq, PartialEq)]
88+
pub enum SectionPath {
89+
Full(MessageSection),
90+
Part(Vec<u32>, Option<MessageSection>),
91+
}
92+
8093
#[derive(Debug, Eq, PartialEq)]
8194
pub enum AttributeValue<'a> {
95+
BodySection {
96+
section: Option<SectionPath>,
97+
index: Option<u32>,
98+
data: Option<&'a [u8]>,
99+
},
82100
Envelope(Envelope<'a>),
83101
Flags(Vec<&'a str>),
84102
InternalDate(&'a str),

0 commit comments

Comments
 (0)