From 6c2ee3ee673557e6ab1e8939a501a92e3ac50621 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Mon, 19 Jun 2023 21:18:23 +0200 Subject: [PATCH] extract fields --- src/multipass/extract_fields.rs | 41 +++++++++++++++++++++++++-------- src/multipass/guess_charset.rs | 8 +++---- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/multipass/extract_fields.rs b/src/multipass/extract_fields.rs index 7bcb585..b34a51d 100644 --- a/src/multipass/extract_fields.rs +++ b/src/multipass/extract_fields.rs @@ -14,27 +14,24 @@ use crate::fragments::whitespace; #[derive(Debug, PartialEq)] pub struct ExtractFields<'a> { - pub raw_header: Cow<'a, str>, pub fields: Vec<&'a str>, pub body: &'a [u8], } -impl<'a> TryFrom> for ExtractFields<'a> { +impl<'a> TryFrom<&'a GuessCharset<'a>> for ExtractFields<'a> { type Error = IMFError<'a>; - fn try_from(gcha: GuessCharset<'a>) -> Result { - let mut ef = ExtractFields { fields: vec![], raw_header: gcha.header, body: gcha.body }; - let (_, fields) = all_consuming(many0(foldable_line))(ef.raw_header).map_err(|e| IMFError::ExtractFields(e))?; - panic!(); - //ef.fields = fields; - //Ok(ef) + fn try_from(gcha: &'a GuessCharset<'a>) -> Result { + all_consuming(many0(foldable_line))(&gcha.header) + .map_err(|e| IMFError::ExtractFields(e)) + .map(|(_, fields)| ExtractFields { fields, body: gcha.body }) } } /// ```abnf -/// fold_line = !crlf *(1*(crlf WS) !crlf) crlf +/// fold_line = any *(1*(crlf WS) any) crlf /// ``` -fn foldable_line<'a>(input: Cow<'a, str>) -> IResult, Cow<'a, str>> { +fn foldable_line(input: &str) -> IResult<&str, &str> { recognize(tuple(( is_not("\r\n"), many0(pair( @@ -43,3 +40,27 @@ fn foldable_line<'a>(input: Cow<'a, str>) -> IResult, Cow<'a, str>> whitespace::perm_crlf )))(input) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_extract() { + assert_eq!( + ExtractFields::try_from(&GuessCharset { + header: "From: hello@world.com,\r\n\talice@wonderlands.com\r\nDate: 12 Mar 1997 07:33:25 Z\r\n".into(), + encoding: encoding_rs::UTF_8, + malformed: false, + body: b"Hello world!", + }), + Ok(ExtractFields { + fields: vec![ + "From: hello@world.com,\r\n\talice@wonderlands.com\r\n", + "Date: 12 Mar 1997 07:33:25 Z\r\n", + ], + body: b"Hello world!", + }) + ); + } +} diff --git a/src/multipass/guess_charset.rs b/src/multipass/guess_charset.rs index bcf223f..aa63324 100644 --- a/src/multipass/guess_charset.rs +++ b/src/multipass/guess_charset.rs @@ -16,8 +16,8 @@ const IS_LAST_BUFFER: bool = true; const ALLOW_UTF8: bool = true; const NO_TLD: Option<&[u8]> = None; -impl<'a> From> for GuessCharset<'a> { - fn from(seg: Segment<'a>) -> Self { +impl<'a> From<&'a Segment<'a>> for GuessCharset<'a> { + fn from(seg: &'a Segment<'a>) -> Self { // Create detector let mut detector = EncodingDetector::new(); detector.feed(&seg.header, IS_LAST_BUFFER); @@ -37,12 +37,12 @@ mod tests { #[test] fn test_charset() { assert_eq!( - GuessCharset::from(Segment { + GuessCharset::from(&Segment { body: b"Hello world!", header: b"From: hello@world.com\r\nDate: 12 Mar 1997 07:33:25 Z\r\n", }), GuessCharset { - header: Cow::Borrowed("From: hello@world.com\r\nDate: 12 Mar 1997 07:33:25 Z\r\n"), + header: "From: hello@world.com\r\nDate: 12 Mar 1997 07:33:25 Z\r\n".into(), encoding: encoding_rs::UTF_8, malformed: false, body: b"Hello world!",