use crate::parse::{
command::{address_literal, Atom, Domain, Mailbox, Path, Reverse_path, String},
imf::{
datetime::date_time,
folding_ws_and_comment::{CFWS, FWS},
identification::msg_id,
},
};
use abnf_core::streaming::CRLF;
use nom::{
branch::alt,
bytes::streaming::{tag, tag_no_case},
combinator::{opt, recognize},
multi::many1,
sequence::tuple,
IResult,
};
pub fn Return_path_line(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((tag_no_case(b"Return-Path:"), FWS, Reverse_path, CRLF));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn Time_stamp_line(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((tag_no_case(b"Received:"), FWS, Stamp, CRLF));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn Stamp(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((
From_domain,
By_domain,
Opt_info,
opt(CFWS),
tag(b";"),
FWS,
date_time,
));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn From_domain(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((tag_no_case(b"FROM"), FWS, Extended_Domain));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn By_domain(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((CFWS, tag_no_case(b"BY"), FWS, Extended_Domain));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn Extended_Domain(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = alt((
recognize(Domain),
recognize(tuple((Domain, FWS, tag(b"("), TCP_info, tag(b")")))),
recognize(tuple((
address_literal,
FWS,
tag(b"("),
TCP_info,
tag(b")"),
))),
));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn TCP_info(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = alt((
recognize(address_literal),
recognize(tuple((Domain, FWS, address_literal))),
));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn Opt_info(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((
opt(Via),
opt(With),
opt(ID),
opt(For),
opt(Additional_Registered_Clauses),
));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn Via(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((CFWS, tag_no_case(b"VIA"), FWS, Link));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn With(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((CFWS, tag_no_case(b"WITH"), FWS, Protocol));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn ID(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((CFWS, tag_no_case(b"ID"), FWS, alt((Atom, msg_id))));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn For(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((CFWS, tag_no_case(b"FOR"), FWS, alt((Path, Mailbox))));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn Additional_Registered_Clauses(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = many1(tuple((CFWS, Atom, FWS, String)));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn Link(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = alt((tag_no_case(b"TCP"), Addtl_Link));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn Addtl_Link(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = Atom;
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn Protocol(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = alt((tag_no_case(b"ESMTP"), tag_no_case(b"SMTP"), Attdl_Protocol));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn Attdl_Protocol(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = Atom;
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}