2023-06-13 22:50:29 +02:00
|
|
|
use std::collections::HashMap;
|
2023-06-13 17:47:57 +02:00
|
|
|
use nom::{
|
|
|
|
IResult,
|
2023-06-13 22:50:29 +02:00
|
|
|
branch::alt,
|
|
|
|
bytes::complete::tag,
|
|
|
|
character::complete::space0,
|
2023-06-16 09:58:07 +02:00
|
|
|
combinator::{map, opt, recognize},
|
|
|
|
multi::many0,
|
|
|
|
sequence::{delimited, pair, tuple},
|
2023-06-13 19:35:41 +02:00
|
|
|
};
|
2023-06-20 17:03:18 +02:00
|
|
|
use crate::fragments::{datetime, mailbox, model, misc_token, whitespace, lazy};
|
|
|
|
use crate::error::IMFError;
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub struct ReceivedLog<'a>(pub &'a str);
|
|
|
|
|
2023-06-20 18:48:49 +02:00
|
|
|
impl<'a> TryFrom<lazy::ReceivedLog<'a>> for ReceivedLog<'a> {
|
2023-06-20 17:03:18 +02:00
|
|
|
type Error = IMFError<'a>;
|
|
|
|
|
2023-06-20 18:48:49 +02:00
|
|
|
fn try_from(input: 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,
|
|
|
|
)),
|
|
|
|
|(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-13 22:50:29 +02:00
|
|
|
alt((
|
|
|
|
map(mailbox::angle_addr, |a| Some(a)),
|
|
|
|
empty_path
|
|
|
|
))(input)
|
|
|
|
}
|
|
|
|
|
|
|
|
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-13 22:50:29 +02:00
|
|
|
recognize(misc_token::word),
|
|
|
|
))(input)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
use chrono::{FixedOffset, TimeZone};
|
|
|
|
|
|
|
|
#[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),
|
|
|
|
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-16 09:58:07 +02:00
|
|
|
for <me@example.com>"#))
|
2023-06-13 22:50:29 +02:00
|
|
|
);
|
|
|
|
}
|
2023-06-13 17:47:57 +02:00
|
|
|
}
|