summaryrefslogtreecommitdiffstats
path: root/melib/src/email/parser.rs
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-07-26 16:08:22 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-07-27 15:06:56 +0300
commit32b4c30feecb43586843900e2a77c094437a18c9 (patch)
treee3948595176850cab7ec26336543d10afa16587e /melib/src/email/parser.rs
parent52cec592158e5afd4332557098ee4f11ab5e2bdd (diff)
melib/email.rs: use SmallVec for Address fields
Diffstat (limited to 'melib/src/email/parser.rs')
-rw-r--r--melib/src/email/parser.rs70
1 files changed, 67 insertions, 3 deletions
diff --git a/melib/src/email/parser.rs b/melib/src/email/parser.rs
index 8e46fb0e..6f29fb8b 100644
--- a/melib/src/email/parser.rs
+++ b/melib/src/email/parser.rs
@@ -1348,8 +1348,8 @@ pub mod address {
// ws!(alt_complete!(mailbox | group))
}
- pub fn rfc2822address_list(input: &[u8]) -> IResult<&[u8], Vec<Address>> {
- separated_list(is_a(","), address)(input.ltrim())
+ pub fn rfc2822address_list(input: &[u8]) -> IResult<&[u8], SmallVec<[Address; 1]>> {
+ separated_list_smallvec(is_a(","), address)(input.ltrim())
// ws!( separated_list!(is_a!(","), address))
}
@@ -1417,6 +1417,70 @@ pub mod address {
separated_list(is_a(" \n\t\r"), message_id_peek)(input)
// separated_list!(complete!(is_a!(" \n\t\r")), message_id_peek));
}
+
+ use smallvec::SmallVec;
+ pub fn separated_list_smallvec<I, O, Sep, E, F, G>(
+ sep: G,
+ f: F,
+ ) -> impl FnMut(I) -> IResult<I, SmallVec<[O; 1]>, E>
+ where
+ I: Clone + PartialEq,
+ F: Fn(I) -> IResult<I, O, E>,
+ G: Fn(I) -> IResult<I, Sep, E>,
+ E: nom::error::ParseError<I>,
+ {
+ move |i: I| {
+ let mut res = SmallVec::new();
+ let mut i = i.clone();
+
+ // Parse the first element
+ match f(i.clone()) {
+ Err(e) => return Err(e),
+ Ok((i1, o)) => {
+ if i1 == i {
+ return Err(nom::Err::Error(E::from_error_kind(
+ i1,
+ ErrorKind::SeparatedList,
+ )));
+ }
+
+ res.push(o);
+ i = i1;
+ }
+ }
+
+ loop {
+ match sep(i.clone()) {
+ Err(nom::Err::Error(_)) => return Ok((i, res)),
+ Err(e) => return Err(e),
+ Ok((i1, _)) => {
+ if i1 == i {
+ return Err(nom::Err::Error(E::from_error_kind(
+ i1,
+ ErrorKind::SeparatedList,
+ )));
+ }
+
+ match f(i1.clone()) {
+ Err(nom::Err::Error(_)) => return Ok((i, res)),
+ Err(e) => return Err(e),
+ Ok((i2, o)) => {
+ if i2 == i {
+ return Err(nom::Err::Error(E::from_error_kind(
+ i2,
+ ErrorKind::SeparatedList,
+ )));
+ }
+
+ res.push(o);
+ i = i2;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
#[cfg(test)]
@@ -1497,7 +1561,7 @@ mod tests {
assert_eq!(
(
&s[0..0],
- vec![
+ smallvec::smallvec![
make_address!("Obit Oppidum", "user@domain"),
make_address!("list", "list@domain.tld"),
make_address!("list2", "list2@domain.tld"),