parse message-id
This commit is contained in:
parent
de6926bb92
commit
30507aafec
6 changed files with 75 additions and 2 deletions
|
@ -175,6 +175,18 @@ fn header_field(input: &str) -> IResult<&str, HeaderField> {
|
||||||
(input, HeaderField::Bcc(body.unwrap_or(vec![])))
|
(input, HeaderField::Bcc(body.unwrap_or(vec![])))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 3.6.4. Identification Fields
|
||||||
|
"Message-ID" => {
|
||||||
|
unimplemented!();
|
||||||
|
},
|
||||||
|
"In-Reply-To" => {
|
||||||
|
unimplemented!();
|
||||||
|
},
|
||||||
|
"References" => {
|
||||||
|
unimplemented!();
|
||||||
|
},
|
||||||
|
|
||||||
|
// Rest
|
||||||
"Subject" => {
|
"Subject" => {
|
||||||
let (input, body) = unstructured(input)?;
|
let (input, body) = unstructured(input)?;
|
||||||
(input, HeaderField::Subject(body))
|
(input, HeaderField::Subject(body))
|
||||||
|
|
54
src/identification.rs
Normal file
54
src/identification.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use nom::{
|
||||||
|
IResult,
|
||||||
|
branch::alt,
|
||||||
|
bytes::complete::{take_while, tag},
|
||||||
|
combinator::opt,
|
||||||
|
sequence::{delimited, pair, tuple},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::whitespace::cfws;
|
||||||
|
use crate::words::dot_atom_text;
|
||||||
|
use crate::mailbox::is_dtext;
|
||||||
|
use crate::model::MessageId;
|
||||||
|
|
||||||
|
/// Message identifier
|
||||||
|
///
|
||||||
|
/// ```abnf
|
||||||
|
/// msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
|
||||||
|
/// ```
|
||||||
|
pub fn msg_id(input: &str) -> IResult<&str, MessageId> {
|
||||||
|
let (input, (left, _, right)) = delimited(
|
||||||
|
pair(opt(cfws), tag("<")),
|
||||||
|
tuple((id_left, tag("@"), id_right)),
|
||||||
|
pair(tag(">"), opt(cfws)),
|
||||||
|
)(input)?;
|
||||||
|
Ok((input, MessageId{ left, right }))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Missing obsolete
|
||||||
|
fn id_left(input: &str) -> IResult<&str, &str> {
|
||||||
|
dot_atom_text(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Missing obsolete
|
||||||
|
fn id_right(input: &str) -> IResult<&str, &str> {
|
||||||
|
alt((dot_atom_text, no_fold_litteral))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn no_fold_litteral(input: &str) -> IResult<&str, &str> {
|
||||||
|
delimited(tag("["), take_while(is_dtext), tag("]"))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_msg_id() {
|
||||||
|
assert_eq!(
|
||||||
|
msg_id("<5678.21-Nov-1997@example.com>"),
|
||||||
|
Ok(("", MessageId{left: "5678.21-Nov-1997", right: "example.com"})),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,3 +10,4 @@ mod misc_token;
|
||||||
// Header specific
|
// Header specific
|
||||||
mod mailbox;
|
mod mailbox;
|
||||||
mod address;
|
mod address;
|
||||||
|
mod identification;
|
||||||
|
|
|
@ -118,7 +118,7 @@ fn inner_domain_litteral(input: &str) -> IResult<&str, String> {
|
||||||
/// %d94-126 / ; characters not including
|
/// %d94-126 / ; characters not including
|
||||||
/// obs-dtext ; "[", "]", or "\"
|
/// obs-dtext ; "[", "]", or "\"
|
||||||
/// ```
|
/// ```
|
||||||
fn is_dtext(c: char) -> bool {
|
pub fn is_dtext(c: char) -> bool {
|
||||||
(c >= '\x21' && c <= '\x5A') || (c >= '\x5E' && c <= '\x7E') || !c.is_ascii()
|
(c >= '\x21' && c <= '\x5A') || (c >= '\x5E' && c <= '\x7E') || !c.is_ascii()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,12 @@ impl From<GroupRef> for AddressRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct MessageId<'a> {
|
||||||
|
pub left: &'a str,
|
||||||
|
pub right: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
/// Permissive Header Section
|
/// Permissive Header Section
|
||||||
///
|
///
|
||||||
/// This is a structure intended for parsing/decoding,
|
/// This is a structure intended for parsing/decoding,
|
||||||
|
|
|
@ -40,7 +40,7 @@ pub fn atom(input: &str) -> IResult<&str, &str> {
|
||||||
/// dot-atom-text
|
/// dot-atom-text
|
||||||
///
|
///
|
||||||
/// `1*atext *("." 1*atext)`
|
/// `1*atext *("." 1*atext)`
|
||||||
fn dot_atom_text(input: &str) -> IResult<&str, &str> {
|
pub fn dot_atom_text(input: &str) -> IResult<&str, &str> {
|
||||||
recognize(pair(take_while1(is_atext), many0(pair(tag("."), take_while1(is_atext)))))(input)
|
recognize(pair(take_while1(is_atext), many0(pair(tag("."), take_while1(is_atext)))))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue