eml-codec/src/fragments/identification.rs

83 lines
2 KiB
Rust
Raw Normal View History

2023-06-13 13:12:16 +00:00
use nom::{
branch::alt,
2023-06-22 13:08:50 +00:00
bytes::complete::{tag, take_while},
2023-06-13 13:12:16 +00:00
combinator::opt,
2023-06-20 13:56:06 +00:00
multi::many1,
2023-06-13 13:12:16 +00:00
sequence::{delimited, pair, tuple},
2023-06-22 13:08:50 +00:00
IResult,
2023-06-13 13:12:16 +00:00
};
2023-06-22 13:08:50 +00:00
use crate::error::IMFError;
2023-06-20 13:56:06 +00:00
use crate::fragments::lazy;
2023-06-19 15:25:16 +00:00
use crate::fragments::mailbox::is_dtext;
2023-06-20 13:56:06 +00:00
use crate::fragments::model::{MessageId, MessageIdList};
2023-06-22 13:08:50 +00:00
use crate::fragments::whitespace::cfws;
use crate::fragments::words::dot_atom_text;
2023-06-20 13:56:06 +00:00
2023-06-22 08:48:07 +00:00
impl<'a> TryFrom<&'a lazy::Identifier<'a>> for MessageId<'a> {
2023-06-20 13:56:06 +00:00
type Error = IMFError<'a>;
2023-06-22 08:48:07 +00:00
fn try_from(id: &'a lazy::Identifier<'a>) -> Result<Self, Self::Error> {
2023-06-20 13:56:06 +00:00
msg_id(id.0)
.map(|(_, i)| i)
.map_err(|e| IMFError::MessageID(e))
}
}
2023-06-22 08:48:07 +00:00
impl<'a> TryFrom<&'a lazy::IdentifierList<'a>> for MessageIdList<'a> {
2023-06-20 13:56:06 +00:00
type Error = IMFError<'a>;
2023-06-22 08:48:07 +00:00
fn try_from(id: &'a lazy::IdentifierList<'a>) -> Result<Self, Self::Error> {
2023-06-20 13:56:06 +00:00
many1(msg_id)(id.0)
.map(|(_, i)| i)
.map_err(|e| IMFError::MessageIDList(e))
}
}
2023-06-13 13:12:16 +00:00
/// 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)?;
2023-06-22 13:08:50 +00:00
Ok((input, MessageId { left, right }))
2023-06-13 13:12:16 +00:00
}
// Missing obsolete
fn id_left(input: &str) -> IResult<&str, &str> {
2023-06-22 13:08:50 +00:00
dot_atom_text(input)
2023-06-13 13:12:16 +00:00
}
// 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>"),
2023-06-22 13:08:50 +00:00
Ok((
"",
MessageId {
left: "5678.21-Nov-1997",
right: "example.com"
}
)),
2023-06-13 13:12:16 +00:00
);
}
}