eml-codec/src/rfc5322/trace.rs

86 lines
2.1 KiB
Rust
Raw Normal View History

2023-06-22 15:08:50 +02:00
use crate::error::IMFError;
use crate::fragments::{datetime, lazy, mailbox, misc_token, model, whitespace};
2023-06-13 17:47:57 +02:00
use nom::{
2023-06-13 22:50:29 +02:00
branch::alt,
bytes::complete::tag,
2023-06-16 09:58:07 +02:00
combinator::{map, opt, recognize},
multi::many0,
2023-06-22 11:15:01 +02:00
sequence::tuple,
2023-06-22 15:08:50 +02:00
IResult,
2023-06-13 19:35:41 +02:00
};
2023-06-20 17:03:18 +02:00
#[derive(Debug, PartialEq)]
pub struct ReceivedLog<'a>(pub &'a str);
2023-06-22 10:48:07 +02:00
impl<'a> TryFrom<&'a lazy::ReceivedLog<'a>> for ReceivedLog<'a> {
2023-06-20 17:03:18 +02:00
type Error = IMFError<'a>;
2023-06-22 10:48:07 +02:00
fn try_from(input: &'a lazy::ReceivedLog<'a>) -> Result<Self, Self::Error> {
2023-06-20 17:03:18 +02:00
received_body(input.0)
.map_err(|e| IMFError::ReceivedLog(e))
.map(|(_, v)| ReceivedLog(v))
}
}
2023-06-16 09:58:07 +02:00
pub fn received_body(input: &str) -> IResult<&str, &str> {
map(
tuple((
recognize(many0(received_tokens)),
tag(";"),
datetime::section,
)),
2023-06-22 15:08:50 +02:00
|(tokens, _, _)| tokens,
2023-06-13 22:50:29 +02:00
)(input)
}
2023-06-16 09:58:07 +02:00
pub fn return_path_body(input: &str) -> IResult<&str, Option<model::MailboxRef>> {
2023-06-22 15:08:50 +02:00
alt((map(mailbox::angle_addr, |a| Some(a)), empty_path))(input)
2023-06-13 22:50:29 +02:00
}
fn empty_path(input: &str) -> IResult<&str, Option<model::MailboxRef>> {
let (input, _) = tuple((
opt(whitespace::cfws),
tag("<"),
opt(whitespace::cfws),
tag(">"),
opt(whitespace::cfws),
))(input)?;
Ok((input, None))
}
2023-06-18 21:17:27 +02:00
// @FIXME use obs_domain as it is a superset of domain
2023-06-13 22:50:29 +02:00
fn received_tokens(input: &str) -> IResult<&str, &str> {
alt((
recognize(mailbox::angle_addr),
recognize(mailbox::addr_spec),
2023-06-18 21:17:27 +02:00
recognize(mailbox::obs_domain),
2023-06-22 15:08:50 +02:00
recognize(misc_token::word),
2023-06-13 22:50:29 +02:00
))(input)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
2023-06-16 10:19:28 +02:00
fn test_received_body() {
2023-06-16 09:58:07 +02:00
let hdrs = r#"from smtp.example.com ([10.83.2.2])
2023-06-13 22:50:29 +02:00
by server with LMTP
id xxxxxxxxx
(envelope-from <gitlab@example.com>)
2023-06-16 09:58:07 +02:00
for <me@example.com>; Tue, 13 Jun 2023 19:01:08 +0000"#;
2023-06-13 22:50:29 +02:00
assert_eq!(
2023-06-16 09:58:07 +02:00
received_body(hdrs),
2023-06-22 15:08:50 +02:00
Ok((
"",
r#"from smtp.example.com ([10.83.2.2])
2023-06-13 22:50:29 +02:00
by server with LMTP
id xxxxxxxxx
(envelope-from <gitlab@example.com>)
2023-06-22 15:08:50 +02:00
for <me@example.com>"#
))
2023-06-13 22:50:29 +02:00
);
}
2023-06-13 17:47:57 +02:00
}