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![])))
|
||||
},
|
||||
|
||||
// 3.6.4. Identification Fields
|
||||
"Message-ID" => {
|
||||
unimplemented!();
|
||||
},
|
||||
"In-Reply-To" => {
|
||||
unimplemented!();
|
||||
},
|
||||
"References" => {
|
||||
unimplemented!();
|
||||
},
|
||||
|
||||
// Rest
|
||||
"Subject" => {
|
||||
let (input, body) = unstructured(input)?;
|
||||
(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
|
||||
mod mailbox;
|
||||
mod address;
|
||||
mod identification;
|
||||
|
|
|
@ -118,7 +118,7 @@ fn inner_domain_litteral(input: &str) -> IResult<&str, String> {
|
|||
/// %d94-126 / ; characters not including
|
||||
/// 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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
///
|
||||
/// This is a structure intended for parsing/decoding,
|
||||
|
|
|
@ -40,7 +40,7 @@ pub fn atom(input: &str) -> IResult<&str, &str> {
|
|||
/// dot-atom-text
|
||||
///
|
||||
/// `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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue