capture preamble and epilogue

This commit is contained in:
Quentin 2023-07-24 18:32:26 +02:00
parent 606d3f7494
commit 7db49875ea
Signed by: quentin
GPG key ID: E9602264D639FF68
2 changed files with 35 additions and 12 deletions

View file

@ -11,6 +11,14 @@ use crate::text::boundary::{boundary, Delimiter};
pub struct Multipart<'a> { pub struct Multipart<'a> {
pub interpreted: mime::Multipart<'a>, pub interpreted: mime::Multipart<'a>,
pub children: Vec<AnyPart<'a>>, pub children: Vec<AnyPart<'a>>,
pub preamble: &'a [u8],
pub epilogue: &'a [u8],
}
impl<'a> Multipart<'a> {
pub fn with_epilogue(mut self, e: &'a [u8]) -> Self {
self.epilogue = e;
self
}
} }
pub fn multipart<'a>( pub fn multipart<'a>(
@ -20,7 +28,7 @@ pub fn multipart<'a>(
move |input| { move |input| {
let bound = m.0.boundary.as_bytes(); let bound = m.0.boundary.as_bytes();
let (mut input_loop, _) = part::part_raw(bound)(input)?; let (mut input_loop, preamble) = part::part_raw(bound)(input)?;
let mut mparts: Vec<AnyPart> = vec![]; let mut mparts: Vec<AnyPart> = vec![];
loop { loop {
let input = match boundary(bound)(input_loop) { let input = match boundary(bound)(input_loop) {
@ -30,6 +38,8 @@ pub fn multipart<'a>(
Multipart { Multipart {
interpreted: m.clone(), interpreted: m.clone(),
children: mparts, children: mparts,
preamble,
epilogue: &[],
}, },
)) ))
} }
@ -39,6 +49,8 @@ pub fn multipart<'a>(
Multipart { Multipart {
interpreted: m.clone(), interpreted: m.clone(),
children: mparts, children: mparts,
preamble,
epilogue: &[],
}, },
)) ))
} }
@ -70,6 +82,13 @@ pub struct Message<'a> {
pub interpreted: mime::Message<'a>, pub interpreted: mime::Message<'a>,
pub imf: imf::Imf<'a>, pub imf: imf::Imf<'a>,
pub child: Box<AnyPart<'a>>, pub child: Box<AnyPart<'a>>,
pub epilogue: &'a [u8],
}
impl<'a> Message<'a> {
pub fn with_epilogue(mut self, e: &'a [u8]) -> Self {
self.epilogue = e;
self
}
} }
pub fn message<'a>( pub fn message<'a>(
@ -88,6 +107,7 @@ pub fn message<'a>(
interpreted: m.clone(), interpreted: m.clone(),
imf, imf,
child: Box::new(part), child: Box::new(part),
epilogue: &[],
}, },
)) ))
} }
@ -134,6 +154,8 @@ This is the epilogue. It is also to be ignored.
Ok((&b"\nThis is the epilogue. It is also to be ignored.\n"[..], Ok((&b"\nThis is the epilogue. It is also to be ignored.\n"[..],
Multipart { Multipart {
interpreted: base_mime, interpreted: base_mime,
preamble: &b"This is the preamble. It is to be ignored, though it\nis a handy place for composition agents to include an\nexplanatory note to non-MIME conformant readers.\n"[..],
epilogue: &b""[..],
children: vec![ children: vec![
AnyPart::Txt(Text { AnyPart::Txt(Text {
interpreted: mime::Text( interpreted: mime::Text(
@ -215,6 +237,7 @@ OoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO<br />
&[][..], &[][..],
Message { Message {
interpreted: base_mime, interpreted: base_mime,
epilogue: &b""[..],
imf: imf::Imf { imf: imf::Imf {
date: Some(FixedOffset::east_opt(2 * 3600) date: Some(FixedOffset::east_opt(2 * 3600)
.unwrap() .unwrap()
@ -288,6 +311,8 @@ OoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO<br />
}, },
mime::Generic::default(), mime::Generic::default(),
), ),
preamble: &b"This is a multi-part message in MIME format.\n"[..],
epilogue: &b""[..],
children: vec![ children: vec![
AnyPart::Txt(Text { AnyPart::Txt(Text {
interpreted: mime::Text( interpreted: mime::Text(

View file

@ -10,7 +10,7 @@ pub mod field;
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::is_not, bytes::complete::is_not,
combinator::{map, not, recognize}, combinator::{not, recognize},
multi::many0, multi::many0,
sequence::pair, sequence::pair,
IResult, IResult,
@ -63,20 +63,18 @@ impl<'a> AnyPart<'a> {
pub fn to_anypart<'a>(m: AnyMIME<'a>, rpart: &'a [u8]) -> AnyPart<'a> { pub fn to_anypart<'a>(m: AnyMIME<'a>, rpart: &'a [u8]) -> AnyPart<'a> {
match m { match m {
AnyMIME::Mult(a) => map(multipart(a), AnyPart::Mult)(rpart) AnyMIME::Mult(a) => multipart(a)(rpart)
.map(|v| v.1) .map(|(rest, multi)| AnyPart::Mult(multi.with_epilogue(rest)))
.unwrap_or(AnyPart::Txt(Text {
interpreted: mime::Text::default(),
body: rpart,
})),
AnyMIME::Msg(a) => message(a)(rpart)
.map(|(rest, msg)| AnyPart::Msg(msg.with_epilogue(rest)))
.unwrap_or(AnyPart::Txt(Text { .unwrap_or(AnyPart::Txt(Text {
interpreted: mime::Text::default(), interpreted: mime::Text::default(),
body: rpart, body: rpart,
})), })),
AnyMIME::Msg(a) => {
map(message(a), AnyPart::Msg)(rpart)
.map(|v| v.1)
.unwrap_or(AnyPart::Txt(Text {
interpreted: mime::Text::default(),
body: rpart,
}))
}
AnyMIME::Txt(a) => AnyPart::Txt(Text { AnyMIME::Txt(a) => AnyPart::Txt(Text {
interpreted: a, interpreted: a,
body: rpart, body: rpart,