trace
This commit is contained in:
parent
54f6ce82a3
commit
b998aec37d
3 changed files with 59 additions and 32 deletions
|
@ -63,9 +63,8 @@ pub fn mailbox(input: &[u8]) -> IResult<&[u8], MailboxRef> {
|
||||||
/// ```
|
/// ```
|
||||||
fn name_addr(input: &[u8]) -> IResult<&[u8], MailboxRef> {
|
fn name_addr(input: &[u8]) -> IResult<&[u8], MailboxRef> {
|
||||||
let (input, name) = opt(phrase)(input)?;
|
let (input, name) = opt(phrase)(input)?;
|
||||||
let (input, mut mbox) = angle_addr(input)?;
|
let (input, addrspec) = angle_addr(input)?;
|
||||||
mbox.name = name;
|
Ok((input, MailboxRef { name, addrspec }))
|
||||||
Ok((input, mbox))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enclosed addr-spec with < and >
|
/// Enclosed addr-spec with < and >
|
||||||
|
@ -74,10 +73,10 @@ fn name_addr(input: &[u8]) -> IResult<&[u8], MailboxRef> {
|
||||||
/// angle-addr = [CFWS] "<" addr-spec ">" [CFWS] /
|
/// angle-addr = [CFWS] "<" addr-spec ">" [CFWS] /
|
||||||
/// obs-angle-addr
|
/// obs-angle-addr
|
||||||
/// ```
|
/// ```
|
||||||
pub fn angle_addr(input: &[u8]) -> IResult<&[u8], MailboxRef> {
|
pub fn angle_addr(input: &[u8]) -> IResult<&[u8], AddrSpec> {
|
||||||
delimited(
|
delimited(
|
||||||
tuple((opt(cfws), tag(&[ascii::LT]), opt(obs_route))),
|
tuple((opt(cfws), tag(&[ascii::LT]), opt(obs_route))),
|
||||||
into(addr_spec),
|
addr_spec,
|
||||||
pair(tag(&[ascii::GT]), opt(cfws)),
|
pair(tag(&[ascii::GT]), opt(cfws)),
|
||||||
)(input)
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
pub mod mailbox;
|
pub mod mailbox;
|
||||||
pub mod address;
|
pub mod address;
|
||||||
pub mod datetime;
|
pub mod datetime;
|
||||||
|
pub mod trace;
|
||||||
|
|
|
@ -1,17 +1,30 @@
|
||||||
use crate::error::IMFError;
|
|
||||||
use crate::fragments::{datetime, lazy, mailbox, misc_token, model, whitespace};
|
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::tag,
|
bytes::complete::{is_a, tag},
|
||||||
combinator::{map, opt, recognize},
|
combinator::{map, opt, not},
|
||||||
multi::many0,
|
multi::many0,
|
||||||
sequence::tuple,
|
sequence::{tuple, terminated},
|
||||||
IResult,
|
IResult,
|
||||||
};
|
};
|
||||||
|
use chrono::{DateTime, FixedOffset};
|
||||||
|
|
||||||
|
use crate::rfc5322::{datetime, mailbox};
|
||||||
|
use crate::text::{ascii, whitespace, misc_token };
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct ReceivedLog<'a>(pub &'a str);
|
pub enum ReceivedLogToken<'a> {
|
||||||
|
Addr(mailbox::AddrSpec<'a>),
|
||||||
|
Domain(mailbox::Domain<'a>),
|
||||||
|
Word(misc_token::Word<'a>)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct ReceivedLog<'a> {
|
||||||
|
pub log: Vec<ReceivedLogToken<'a>>,
|
||||||
|
pub date: Option<DateTime<FixedOffset>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
impl<'a> TryFrom<&'a lazy::ReceivedLog<'a>> for ReceivedLog<'a> {
|
impl<'a> TryFrom<&'a lazy::ReceivedLog<'a>> for ReceivedLog<'a> {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
|
@ -20,47 +33,48 @@ impl<'a> TryFrom<&'a lazy::ReceivedLog<'a>> for ReceivedLog<'a> {
|
||||||
.map_err(|e| IMFError::ReceivedLog(e))
|
.map_err(|e| IMFError::ReceivedLog(e))
|
||||||
.map(|(_, v)| ReceivedLog(v))
|
.map(|(_, v)| ReceivedLog(v))
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
pub fn received_body(input: &str) -> IResult<&str, &str> {
|
pub fn received_body(input: &[u8]) -> IResult<&[u8], ReceivedLog> {
|
||||||
map(
|
map(
|
||||||
tuple((
|
tuple((
|
||||||
recognize(many0(received_tokens)),
|
many0(received_tokens),
|
||||||
tag(";"),
|
tag(";"),
|
||||||
datetime::section,
|
datetime::section,
|
||||||
)),
|
)),
|
||||||
|(tokens, _, _)| tokens,
|
|(tokens, _, dt)| ReceivedLog { log: tokens, date: dt } ,
|
||||||
)(input)
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn return_path_body(input: &str) -> IResult<&str, Option<model::MailboxRef>> {
|
pub fn return_path_body(input: &[u8]) -> IResult<&[u8], Option<mailbox::AddrSpec>> {
|
||||||
alt((map(mailbox::angle_addr, |a| Some(a)), empty_path))(input)
|
alt((map(mailbox::angle_addr, |a| Some(a)), empty_path))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn empty_path(input: &str) -> IResult<&str, Option<model::MailboxRef>> {
|
fn empty_path(input: &[u8]) -> IResult<&[u8], Option<mailbox::AddrSpec>> {
|
||||||
let (input, _) = tuple((
|
let (input, _) = tuple((
|
||||||
opt(whitespace::cfws),
|
opt(whitespace::cfws),
|
||||||
tag("<"),
|
tag(&[ascii::LT]),
|
||||||
opt(whitespace::cfws),
|
opt(whitespace::cfws),
|
||||||
tag(">"),
|
tag(&[ascii::GT]),
|
||||||
opt(whitespace::cfws),
|
opt(whitespace::cfws),
|
||||||
))(input)?;
|
))(input)?;
|
||||||
Ok((input, None))
|
Ok((input, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
// @FIXME use obs_domain as it is a superset of domain
|
fn received_tokens(input: &[u8]) -> IResult<&[u8], ReceivedLogToken> {
|
||||||
fn received_tokens(input: &str) -> IResult<&str, &str> {
|
|
||||||
alt((
|
alt((
|
||||||
recognize(mailbox::angle_addr),
|
terminated(map(misc_token::word, |x| ReceivedLogToken::Word(x)), not(is_a([ascii::PERIOD, ascii::AT]))),
|
||||||
recognize(mailbox::addr_spec),
|
map(mailbox::angle_addr, |x| ReceivedLogToken::Addr(x)),
|
||||||
recognize(mailbox::obs_domain),
|
map(mailbox::addr_spec, |x| ReceivedLogToken::Addr(x)),
|
||||||
recognize(misc_token::word),
|
map(mailbox::obs_domain, |x| ReceivedLogToken::Domain(x)),
|
||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use chrono::TimeZone;
|
||||||
|
use crate::rfc5322::trace::misc_token::Word;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_received_body() {
|
fn test_received_body() {
|
||||||
|
@ -68,17 +82,30 @@ mod tests {
|
||||||
by server with LMTP
|
by server with LMTP
|
||||||
id xxxxxxxxx
|
id xxxxxxxxx
|
||||||
(envelope-from <gitlab@example.com>)
|
(envelope-from <gitlab@example.com>)
|
||||||
for <me@example.com>; Tue, 13 Jun 2023 19:01:08 +0000"#;
|
for <me@example.com>; Tue, 13 Jun 2023 19:01:08 +0000"#.as_bytes();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
received_body(hdrs),
|
received_body(hdrs),
|
||||||
Ok((
|
Ok((
|
||||||
"",
|
&b""[..],
|
||||||
r#"from smtp.example.com ([10.83.2.2])
|
ReceivedLog {
|
||||||
by server with LMTP
|
date: Some(FixedOffset::east_opt(0).unwrap().with_ymd_and_hms(2023, 06, 13, 19, 1, 8).unwrap()),
|
||||||
id xxxxxxxxx
|
log: vec![
|
||||||
(envelope-from <gitlab@example.com>)
|
ReceivedLogToken::Word(Word::Atom(&b"from"[..])),
|
||||||
for <me@example.com>"#
|
ReceivedLogToken::Domain(mailbox::Domain::Atoms(vec![&b"smtp"[..], &b"example"[..], &b"com"[..]])),
|
||||||
|
ReceivedLogToken::Word(Word::Atom(&b"by"[..])),
|
||||||
|
ReceivedLogToken::Word(Word::Atom(&b"server"[..])),
|
||||||
|
ReceivedLogToken::Word(Word::Atom(&b"with"[..])),
|
||||||
|
ReceivedLogToken::Word(Word::Atom(&b"LMTP"[..])),
|
||||||
|
ReceivedLogToken::Word(Word::Atom(&b"id"[..])),
|
||||||
|
ReceivedLogToken::Word(Word::Atom(&b"xxxxxxxxx"[..])),
|
||||||
|
ReceivedLogToken::Word(Word::Atom(&b"for"[..])),
|
||||||
|
ReceivedLogToken::Addr(mailbox::AddrSpec {
|
||||||
|
local_part: mailbox::LocalPart(vec![mailbox::LocalPartToken::Word(Word::Atom(&b"me"[..]))]),
|
||||||
|
domain: mailbox::Domain::Atoms(vec![&b"example"[..], &b"com"[..]]),
|
||||||
|
})
|
||||||
|
],
|
||||||
|
}
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue