eml-codec/src/imf/identification.rs

88 lines
2.1 KiB
Rust
Raw Normal View History

2023-06-13 15:12:16 +02:00
use nom::{
branch::alt,
2023-06-22 15:08:50 +02:00
bytes::complete::{tag, take_while},
2023-06-13 15:12:16 +02:00
combinator::opt,
2023-07-20 09:41:10 +02:00
multi::many1,
2023-06-13 15:12:16 +02:00
sequence::{delimited, pair, tuple},
2023-06-22 15:08:50 +02:00
IResult,
2023-06-13 15:12:16 +02:00
};
2023-07-24 12:37:30 +02:00
use std::fmt;
2023-06-13 15:12:16 +02:00
2023-07-24 11:02:49 +02:00
use crate::imf::mailbox::is_dtext;
2023-07-19 18:30:43 +02:00
use crate::text::whitespace::cfws;
use crate::text::words::dot_atom_text;
2023-06-20 15:56:06 +02:00
2023-07-23 19:14:42 +02:00
#[derive(PartialEq, Clone)]
2023-07-20 09:41:10 +02:00
pub struct MessageID<'a> {
2023-07-19 18:30:43 +02:00
pub left: &'a [u8],
pub right: &'a [u8],
2023-07-18 23:25:10 +02:00
}
2023-07-23 19:14:42 +02:00
impl<'a> ToString for MessageID<'a> {
fn to_string(&self) -> String {
2023-07-24 12:37:30 +02:00
format!(
"{}@{}",
String::from_utf8_lossy(self.left),
String::from_utf8_lossy(self.right)
)
2023-07-23 19:14:42 +02:00
}
}
impl<'a> fmt::Debug for MessageID<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2023-07-24 12:37:30 +02:00
fmt.debug_tuple("MessageID")
.field(&format_args!("\"{}\"", self.to_string()))
.finish()
2023-07-23 19:14:42 +02:00
}
}
2023-07-20 09:41:10 +02:00
pub type MessageIDList<'a> = Vec<MessageID<'a>>;
2023-07-18 23:25:10 +02:00
2023-06-13 15:12:16 +02:00
/// Message identifier
///
/// ```abnf
/// msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
/// ```
2023-07-20 09:41:10 +02:00
pub fn msg_id(input: &[u8]) -> IResult<&[u8], MessageID> {
2023-06-13 15:12:16 +02:00
let (input, (left, _, right)) = delimited(
pair(opt(cfws), tag("<")),
tuple((id_left, tag("@"), id_right)),
pair(tag(">"), opt(cfws)),
)(input)?;
2023-07-20 09:41:10 +02:00
Ok((input, MessageID { left, right }))
2023-06-13 15:12:16 +02:00
}
2023-07-20 09:41:10 +02:00
pub fn msg_list(input: &[u8]) -> IResult<&[u8], MessageIDList> {
2023-07-19 22:27:59 +02:00
many1(msg_id)(input)
}
2023-07-19 18:30:43 +02:00
// @FIXME Missing obsolete
fn id_left(input: &[u8]) -> IResult<&[u8], &[u8]> {
2023-06-22 15:08:50 +02:00
dot_atom_text(input)
2023-06-13 15:12:16 +02:00
}
2023-07-19 18:30:43 +02:00
// @FIXME Missing obsolete
fn id_right(input: &[u8]) -> IResult<&[u8], &[u8]> {
2023-06-13 15:12:16 +02:00
alt((dot_atom_text, no_fold_litteral))(input)
}
2023-07-19 18:30:43 +02:00
fn no_fold_litteral(input: &[u8]) -> IResult<&[u8], &[u8]> {
2023-06-13 15:12:16 +02:00
delimited(tag("["), take_while(is_dtext), tag("]"))(input)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_msg_id() {
assert_eq!(
2023-07-19 18:30:43 +02:00
msg_id(b"<5678.21-Nov-1997@example.com>"),
2023-06-22 15:08:50 +02:00
Ok((
2023-07-19 18:30:43 +02:00
&b""[..],
2023-07-20 09:41:10 +02:00
MessageID {
2023-07-19 18:30:43 +02:00
left: &b"5678.21-Nov-1997"[..],
right: &b"example.com"[..],
2023-06-22 15:08:50 +02:00
}
)),
2023-06-13 15:12:16 +02:00
);
}
}