compile subset
This commit is contained in:
parent
a503eb1de6
commit
50b837438e
5 changed files with 31 additions and 25 deletions
|
@ -103,7 +103,7 @@ Todo:
|
||||||
| 🔴 |2049 | ↳ Multipurpose Internet Mail Extensions (MIME) Part Five: Conformance Criteria and Examples |
|
| 🔴 |2049 | ↳ Multipurpose Internet Mail Extensions (MIME) Part Five: Conformance Criteria and Examples |
|
||||||
| | | **Headers extensions** |
|
| | | **Headers extensions** |
|
||||||
| 🔴 |2183 | ↳ Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field |
|
| 🔴 |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 |
|
| 🔴 |9228 | ↳ Delivered-To Email Header Field |
|
||||||
| | | **MIME extensions** |
|
| | | **MIME extensions** |
|
||||||
| 🔴 |1847 | ↳ Security Multiparts for MIME: Multipart/Signed and Multipart/Encrypted |
|
| 🔴 |1847 | ↳ Security Multiparts for MIME: Multipart/Signed and Multipart/Encrypted |
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
use encoding_rs::Encoding;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Default)]
|
#[derive(Debug, PartialEq, Default)]
|
||||||
pub struct Text<'a> {
|
pub struct Text<'a> {
|
||||||
parts: Vec<&'a [u8]>,
|
parts: Vec<&'a [u8]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Text<'a> {
|
impl<'a> Text<'a> {
|
||||||
pub fn push(&mut self, e: &[u8]) {
|
pub fn push(&mut self, e: &'a [u8]) {
|
||||||
self.parts.push(e)
|
self.parts.push(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,14 @@ pub enum EncodedWord<'a> {
|
||||||
Quoted(QuotedWord<'a>),
|
Quoted(QuotedWord<'a>),
|
||||||
Base64(Base64Word<'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)]
|
#[derive(PartialEq,Debug)]
|
||||||
pub struct Base64Word<'a> {
|
pub struct Base64Word<'a> {
|
||||||
|
|
|
@ -2,12 +2,11 @@ use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::take_while1,
|
bytes::complete::take_while1,
|
||||||
character::complete::space0,
|
character::complete::space0,
|
||||||
combinator::{into, map, opt},
|
combinator::{map, opt},
|
||||||
multi::{many0, many1},
|
multi::{many0, many1},
|
||||||
sequence::{preceded, tuple},
|
sequence::{preceded},
|
||||||
IResult,
|
IResult,
|
||||||
};
|
};
|
||||||
use std::borrow::Cow;
|
|
||||||
|
|
||||||
use crate::text::{
|
use crate::text::{
|
||||||
quoted::quoted_string,
|
quoted::quoted_string,
|
||||||
|
@ -52,7 +51,7 @@ impl<'a> Word<'a> {
|
||||||
match self {
|
match self {
|
||||||
Word::Quoted(v) => v.to_string(),
|
Word::Quoted(v) => v.to_string(),
|
||||||
Word::Encoded(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>>);
|
pub struct Phrase<'a>(pub Vec<Word<'a>>);
|
||||||
impl<'a> Phrase<'a> {
|
impl<'a> Phrase<'a> {
|
||||||
pub fn to_string(&self) -> String {
|
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
|
is_vchar(c) || is_obs_no_ws_ctl(c) || c == ascii::NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
enum UnstrToken<'a> {
|
pub enum UnstrToken<'a> {
|
||||||
Init,
|
Init,
|
||||||
Encoded(encoding::EncodedWord<'a>),
|
Encoded(encoding::EncodedWord<'a>),
|
||||||
Plain(&'a [u8]),
|
Plain(&'a [u8]),
|
||||||
|
@ -106,7 +105,7 @@ impl<'a> UnstrToken<'a> {
|
||||||
match self {
|
match self {
|
||||||
UnstrToken::Init => "".into(),
|
UnstrToken::Init => "".into(),
|
||||||
UnstrToken::Encoded(e) => e.to_string(),
|
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 {
|
pub fn to_string(&self) -> String {
|
||||||
self.0.iter().fold(
|
self.0.iter().fold(
|
||||||
(&UnstrToken::Init, String::new()),
|
(&UnstrToken::Init, String::new()),
|
||||||
|(prev_token, result), current_token| {
|
|(prev_token, mut result), current_token| {
|
||||||
match (prev_token, current_token) {
|
match (prev_token, current_token) {
|
||||||
(UnstrToken::Init, v) => result.push_str(v.to_string().as_ref()),
|
(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) => {
|
(_, v) => {
|
||||||
result.push(' ');
|
result.push(' ');
|
||||||
result.push_str(v.to_string().as_ref())
|
result.push_str(v.to_string().as_ref())
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
result
|
(current_token, result)
|
||||||
}
|
}
|
||||||
)
|
).1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::{take_while1, tag},
|
bytes::complete::{take_while1, take, tag},
|
||||||
character::complete::anychar,
|
combinator::{opt},
|
||||||
combinator::{recognize, opt},
|
|
||||||
multi::many0,
|
multi::many0,
|
||||||
sequence::{pair, preceded},
|
sequence::{pair, preceded},
|
||||||
IResult,
|
IResult,
|
||||||
|
@ -18,10 +17,12 @@ use crate::text::buffer;
|
||||||
/// quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
|
/// quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
|
||||||
/// obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR)
|
/// obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR)
|
||||||
/// ```
|
/// ```
|
||||||
pub fn quoted_pair(input: &[u8]) -> IResult<&[u8], u8> {
|
pub fn quoted_pair(input: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||||
preceded(tag(&[ascii::SLASH]), anychar)(input)
|
preceded(tag(&[ascii::SLASH]), take(1usize))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Allowed characters in quote
|
/// Allowed characters in quote
|
||||||
///
|
///
|
||||||
/// ```abnf
|
/// ```abnf
|
||||||
|
@ -43,8 +44,8 @@ fn is_qtext(c: u8) -> bool {
|
||||||
/// ```abnf
|
/// ```abnf
|
||||||
/// qcontent = qtext / quoted-pair
|
/// qcontent = qtext / quoted-pair
|
||||||
/// ```
|
/// ```
|
||||||
fn qcontent(input: &u8) -> IResult<&[u8], &[u8]> {
|
fn qcontent(input: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||||
alt((take_while1(is_qtext), recognize(quoted_pair)))(input)
|
alt((take_while1(is_qtext), quoted_pair))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Quoted string
|
/// Quoted string
|
||||||
|
@ -63,7 +64,7 @@ pub fn quoted_string(input: &[u8]) -> IResult<&[u8], buffer::Text> {
|
||||||
let mut qstring = content
|
let mut qstring = content
|
||||||
.iter()
|
.iter()
|
||||||
.fold(buffer::Text::default(), |mut acc, (maybe_wsp, c)| {
|
.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(&[ascii::SP]);
|
||||||
}
|
}
|
||||||
acc.push(c);
|
acc.push(c);
|
||||||
|
@ -71,8 +72,8 @@ pub fn quoted_string(input: &[u8]) -> IResult<&[u8], buffer::Text> {
|
||||||
});
|
});
|
||||||
|
|
||||||
let (input, maybe_wsp) = opt(fws)(input)?;
|
let (input, maybe_wsp) = opt(fws)(input)?;
|
||||||
if let Some(wsp) = maybe_wsp {
|
if let Some(_) = maybe_wsp {
|
||||||
qstring.push(wsp);
|
qstring.push(&[ascii::SP]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (input, _) = tag("\"")(input)?;
|
let (input, _) = tag("\"")(input)?;
|
||||||
|
|
Loading…
Add table
Reference in a new issue