compile subset

This commit is contained in:
Quentin 2023-07-19 10:41:51 +02:00
parent a503eb1de6
commit 50b837438e
Signed by: quentin
GPG key ID: E9602264D639FF68
5 changed files with 31 additions and 25 deletions

View file

@ -103,7 +103,7 @@ Todo:
| 🔴 |2049 | ↳ Multipurpose Internet Mail Extensions (MIME) Part Five: Conformance Criteria and Examples |
| | | **Headers extensions** |
| 🔴 |2183 | ↳ Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field |
| 🟩 |6532 | ↳ Internationalized Email Headers |
| 🔴 |6532 | ↳ Internationalized Email Headers |
| 🔴 |9228 | ↳ Delivered-To Email Header Field |
| | | **MIME extensions** |
| 🔴 |1847 | ↳ Security Multiparts for MIME: Multipart/Signed and Multipart/Encrypted |

View file

@ -1,12 +1,10 @@
use encoding_rs::Encoding;
#[derive(Debug, PartialEq, Default)]
pub struct Text<'a> {
parts: Vec<&'a [u8]>,
}
impl<'a> Text<'a> {
pub fn push(&mut self, e: &[u8]) {
pub fn push(&mut self, e: &'a [u8]) {
self.parts.push(e)
}

View file

@ -48,6 +48,14 @@ pub enum EncodedWord<'a> {
Quoted(QuotedWord<'a>),
Base64(Base64Word<'a>),
}
impl<'a> EncodedWord<'a> {
pub fn to_string(&self) -> String {
match self {
EncodedWord::Quoted(v) => v.to_string(),
EncodedWord::Base64(v) => v.to_string(),
}
}
}
#[derive(PartialEq,Debug)]
pub struct Base64Word<'a> {

View file

@ -2,12 +2,11 @@ use nom::{
branch::alt,
bytes::complete::take_while1,
character::complete::space0,
combinator::{into, map, opt},
combinator::{map, opt},
multi::{many0, many1},
sequence::{preceded, tuple},
sequence::{preceded},
IResult,
};
use std::borrow::Cow;
use crate::text::{
quoted::quoted_string,
@ -52,7 +51,7 @@ impl<'a> Word<'a> {
match self {
Word::Quoted(v) => v.to_string(),
Word::Encoded(v) => v.to_string(),
Word::Atom(v) => v.to_string(),
Word::Atom(v) => encoding_rs::UTF_8.decode_without_bom_handling(v).0.to_string(),
}
}
}
@ -73,7 +72,7 @@ pub fn word(input: &[u8]) -> IResult<&[u8], Word> {
pub struct Phrase<'a>(pub Vec<Word<'a>>);
impl<'a> Phrase<'a> {
pub fn to_string(&self) -> String {
self.0.join(" ")
self.0.iter().map(|v| v.to_string()).collect::<Vec<String>>().join(" ")
}
}
@ -96,7 +95,7 @@ fn is_unstructured(c: u8) -> bool {
is_vchar(c) || is_obs_no_ws_ctl(c) || c == ascii::NULL
}
enum UnstrToken<'a> {
pub enum UnstrToken<'a> {
Init,
Encoded(encoding::EncodedWord<'a>),
Plain(&'a [u8]),
@ -106,7 +105,7 @@ impl<'a> UnstrToken<'a> {
match self {
UnstrToken::Init => "".into(),
UnstrToken::Encoded(e) => e.to_string(),
UnstrToken::Plain(e) => encoding_rs::UTF_8.decode_without_bom_handling(e).into_owned(),
UnstrToken::Plain(e) => encoding_rs::UTF_8.decode_without_bom_handling(e).0.into_owned(),
}
}
}
@ -116,19 +115,19 @@ impl<'a> Unstructured<'a> {
pub fn to_string(&self) -> String {
self.0.iter().fold(
(&UnstrToken::Init, String::new()),
|(prev_token, result), current_token| {
|(prev_token, mut result), current_token| {
match (prev_token, current_token) {
(UnstrToken::Init, v) => result.push_str(v.to_string().as_ref()),
(UnstrToken::EncodedWord(_), UnstrToken::EncodedWord(v)) => result.push_str(v.to_string()).as_ref(),
(UnstrToken::Encoded(_), UnstrToken::Encoded(v)) => result.push_str(v.to_string().as_ref()),
(_, v) => {
result.push(' ');
result.push_str(v.to_string().as_ref())
},
};
result
(current_token, result)
}
)
).1
}
}

View file

@ -1,8 +1,7 @@
use nom::{
branch::alt,
bytes::complete::{take_while1, tag},
character::complete::anychar,
combinator::{recognize, opt},
bytes::complete::{take_while1, take, tag},
combinator::{opt},
multi::many0,
sequence::{pair, preceded},
IResult,
@ -18,10 +17,12 @@ use crate::text::buffer;
/// quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
/// obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR)
/// ```
pub fn quoted_pair(input: &[u8]) -> IResult<&[u8], u8> {
preceded(tag(&[ascii::SLASH]), anychar)(input)
pub fn quoted_pair(input: &[u8]) -> IResult<&[u8], &[u8]> {
preceded(tag(&[ascii::SLASH]), take(1usize))(input)
}
/// Allowed characters in quote
///
/// ```abnf
@ -43,8 +44,8 @@ fn is_qtext(c: u8) -> bool {
/// ```abnf
/// qcontent = qtext / quoted-pair
/// ```
fn qcontent(input: &u8) -> IResult<&[u8], &[u8]> {
alt((take_while1(is_qtext), recognize(quoted_pair)))(input)
fn qcontent(input: &[u8]) -> IResult<&[u8], &[u8]> {
alt((take_while1(is_qtext), quoted_pair))(input)
}
/// Quoted string
@ -63,7 +64,7 @@ pub fn quoted_string(input: &[u8]) -> IResult<&[u8], buffer::Text> {
let mut qstring = content
.iter()
.fold(buffer::Text::default(), |mut acc, (maybe_wsp, c)| {
if let Some(wsp) = maybe_wsp {
if let Some(_) = maybe_wsp {
acc.push(&[ascii::SP]);
}
acc.push(c);
@ -71,8 +72,8 @@ pub fn quoted_string(input: &[u8]) -> IResult<&[u8], buffer::Text> {
});
let (input, maybe_wsp) = opt(fws)(input)?;
if let Some(wsp) = maybe_wsp {
qstring.push(wsp);
if let Some(_) = maybe_wsp {
qstring.push(&[ascii::SP]);
}
let (input, _) = tag("\"")(input)?;