eml-codec/src/identification.rs
2023-06-13 15:12:16 +02:00

54 lines
1.3 KiB
Rust

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"})),
);
}
}