move boundary to text

This commit is contained in:
Quentin 2023-07-22 16:46:36 +02:00
parent 5df9b253ec
commit 6c8e738d43
Signed by: quentin
GPG key ID: E9602264D639FF68
5 changed files with 97 additions and 56 deletions

View file

@ -3,12 +3,13 @@ use nom::{
branch::alt,
bytes::complete::{tag_no_case, tag, take_while1},
character::complete::space0,
combinator::map,
combinator::{not, map},
multi::many0,
sequence::{pair, terminated, tuple},
sequence::{pair, preceded, terminated, tuple},
};
use crate::text::whitespace::{foldable_line, obs_crlf};
use crate::text::misc_token::{Unstructured, unstructured};
use crate::text::boundary::boundary;
#[derive(Debug, PartialEq)]
pub enum CompField<'a, T> {
@ -38,6 +39,18 @@ pub fn header<'a, T>(fx: impl Fn(&'a [u8]) -> IResult<&[u8], T> + Copy)
))), obs_crlf), CompFieldList)(input)
}
pub fn header_in_boundaries<'a, T>(bound: &'a [u8], fx: impl Fn(&'a [u8]) -> IResult<&[u8], T> + Copy)
-> impl Fn(&'a [u8]) -> IResult<&[u8], CompFieldList<T>>
{
move |input| map(terminated(many0(preceded(
not(boundary(bound)),
alt((
map(fx, CompField::Known),
map(opt_field, |(k,v)| CompField::Unknown(k,v)),
map(foldable_line, CompField::Bad),
)))), obs_crlf), CompFieldList)(input)
}
pub fn field_name<'a>(name: &'static [u8]) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], &'a [u8]> {
move |input| {
terminated(

View file

@ -50,7 +50,7 @@ mod tests {
if let Content::Type(nt) = content {
assert_eq!(
nt.to_type(),
Type::Text(TextDesc {
Type::Text(Text {
charset: EmailCharset::UTF_8,
subtype: TextSubtype::Plain,
}),

View file

@ -7,51 +7,49 @@ use nom::{
combinator::{not, opt, recognize},
};
use crate::mime::r#type;
pub struct Part<'a, T> {
pub struct Part<'a> {
Multipart(r#type::Multipart, Vec<Part<'a>>),
Message(r#type::Message, Message, Part<'a>),
Text(r#type::Text, &'a [u8]),
Binary(&'a [u8]),
}
impl<'a> Part<'a, r#type::Text<'a>> {
pub fn message() -> IResult<&[u8], Part> {
}
#[derive(Debug, PartialEq)]
pub enum PartNodeLazy<'a>{
Discrete(MIMESection<'a>, &'a [u8]),
Composite(MIMESection<'a>, &'a [u8]),
}
#[derive(Debug, PartialEq)]
pub enum PartNode<'a> {
Discrete(MIMESection<'a>, &'a [u8]),
Composite(MIMESection<'a>, Vec<PartNode<'a>>),
}
#[derive(Debug, PartialEq)]
pub enum Delimiter {
Next,
Last
}
const IS_LAST_BUFFER: bool = true;
const ALLOW_UTF8: bool = true;
const NO_TLD: Option<&[u8]> = None;
fn part_node_lazy(input: &[u8]) -> IResult<&[u8], PartNodeLazy> {
//let mime = header.iter().map(|e| eager::MIMEField::from(lazy::MIMEField::from(e)));
todo!();
}
pub fn boundary<'a>(boundary: &'a [u8]) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Delimiter> {
pub fn multipart<'a>(ctype: Type) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Part<'a>> {
move |input: &[u8]| {
let (rest, (_, _, _, last, _)) = tuple((obs_crlf, tag(b"--"), tag(boundary), opt(tag(b"--")), opt(obs_crlf)))(input)?;
match last {
Some(_) => Ok((rest, Delimiter::Last)),
None => Ok((rest, Delimiter::Next)),
let (mut input_loop, _) = preamble(ctype.boundary)(input)?;
let mut parts: Vec<Part> = vec![];
loop {
let input = match boundary(ctype.boundary)(input_loop) {
Err(_) => return Ok((input_loop, parts)),
Ok((inp, Delimiter::Last)) => return Ok((inp, Part::Multipart(ctype, parts))),
Ok((inp, Delimiter::Next)) => inp,
};
// parse mime headers
header(content)(input)?;
// based on headers, parse part
let input = match part(bound)(input) {
Err(_) => return Ok((input, parts)),
Ok((inp, part)) => {
parts.push(part);
inp
}
};
input_loop = input;
}
}
}
pub fn discrete() -> IResult<&[u8], Part> {
}
pub fn part<'a>(bound: &'a [u8]) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], &'a [u8]> {
@ -105,22 +103,6 @@ pub fn multipart<'a>(bound: &'a [u8]) -> impl Fn(&'a [u8]) -> IResult<&'a [u8],
mod tests {
use super::*;
#[test]
fn test_boundary_next() {
assert_eq!(
boundary(b"hello")(b"\r\n--hello\r\n"),
Ok((&b""[..], Delimiter::Next))
);
}
#[test]
fn test_boundary_last() {
assert_eq!(
boundary(b"hello")(b"\r\n--hello--\r\n"),
Ok((&b""[..], Delimiter::Last))
);
}
#[test]
fn test_preamble() {
assert_eq!(

45
src/text/boundary.rs Normal file
View file

@ -0,0 +1,45 @@
use nom::{
IResult,
bytes::complete::tag,
sequence::tuple,
combinator::opt,
};
use crate::text::whitespace::obs_crlf;
#[derive(Debug, PartialEq)]
pub enum Delimiter {
Next,
Last
}
pub fn boundary<'a>(boundary: &'a [u8]) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Delimiter> {
move |input: &[u8]| {
let (rest, (_, _, _, last, _)) = tuple((opt(obs_crlf), tag(b"--"), tag(boundary), opt(tag(b"--")), opt(obs_crlf)))(input)?;
match last {
Some(_) => Ok((rest, Delimiter::Last)),
None => Ok((rest, Delimiter::Next)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_boundary_next() {
assert_eq!(
boundary(b"hello")(b"\r\n--hello\r\n"),
Ok((&b""[..], Delimiter::Next))
);
}
#[test]
fn test_boundary_last() {
assert_eq!(
boundary(b"hello")(b"\r\n--hello--\r\n"),
Ok((&b""[..], Delimiter::Last))
);
}
}

View file

@ -4,3 +4,4 @@ pub mod misc_token;
pub mod quoted;
pub mod whitespace;
pub mod words;
pub mod boundary;