1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
use lut::{Table, Any};
use lookup_tables::{
MediaTypeChars,
QText,
QTextWs,
DQuoteOrEscape, Ws,
Token
};
use qs::error::CoreError;
use qs::spec::{
PartialCodePoint,
ParsingImpl,
State,
WithoutQuotingValidator,
QuotingClassifier, QuotingClass,
};
use super::{MimeParsingExt, FWSState};
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
pub struct MimeTokenValidator;
impl MimeTokenValidator {
pub fn new() -> Self {
Default::default()
}
}
impl WithoutQuotingValidator for MimeTokenValidator {
fn next(&mut self, pcp: PartialCodePoint) -> bool {
MediaTypeChars::check_at(pcp.as_u8() as usize, Token)
}
fn end(&self) -> bool {
true
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
pub struct MimeObsQuoting;
impl QuotingClassifier for MimeObsQuoting {
fn classify_for_quoting(pcp: PartialCodePoint) -> QuotingClass {
let iu8 = pcp.as_u8();
if MediaTypeChars::check_at(iu8 as usize, QTextWs) {
QuotingClass::QText
} else if iu8 <= 0x7f {
QuotingClass::NeedsQuoting
} else {
QuotingClass::Invalid
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
pub struct MimeObsUtf8Quoting;
impl QuotingClassifier for MimeObsUtf8Quoting {
fn classify_for_quoting(pcp: PartialCodePoint) -> QuotingClass {
let iu8 = pcp.as_u8();
if iu8 > 0x7f || MediaTypeChars::check_at(iu8 as usize, QTextWs) {
QuotingClass::QText
} else {
QuotingClass::NeedsQuoting
}
}
}
macro_rules! def_mime_parsing {
(
$(#[$meta:meta])*
pub struct $name:ident {
utf8 = $utf8:tt;
obsolte_syntax = $obs:tt;
}
fn can_be_quoted($nm:ident: PartialCodePoint) -> bool
$body:block
) => (
$(#[$meta])*
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct $name(FWSState);
impl MimeParsingExt for $name {
const ALLOW_UTF8: bool = $utf8;
const OBS: bool = $obs;
fn custom_state(state: FWSState, emit: bool) -> (State<Self>, bool) {
(State::Custom($name(state)), emit)
}
}
impl ParsingImpl for $name {
fn can_be_quoted($nm: PartialCodePoint) -> bool {
$body
}
fn handle_normal_state(bch: PartialCodePoint) -> Result<(State<Self>, bool), CoreError> {
<Self as MimeParsingExt>::handle_normal_state(bch)
}
fn advance(&self, bch: PartialCodePoint) -> Result<(State<Self>, bool), CoreError> {
self.0.advance(bch)
}
}
);
}
def_mime_parsing! {
pub struct MimeObsParsing {
utf8 = false;
obsolte_syntax = true;
}
fn can_be_quoted(bch: PartialCodePoint) -> bool {
bch.as_u8() <= 0x7f
}
}
def_mime_parsing! {
pub struct MimeObsParsingUtf8 {
utf8 = true;
obsolte_syntax = true;
}
fn can_be_quoted(bch: PartialCodePoint) -> bool {
bch.as_u8() <= 0x7f
}
}
def_mime_parsing! {
pub struct MimeParsing {
utf8 = false;
obsolte_syntax = false;
}
fn can_be_quoted(bch: PartialCodePoint) -> bool {
let idx = bch.as_u8() as usize;
MediaTypeChars::check_at(idx, Any::new(Ws) | QText | DQuoteOrEscape)
}
}
def_mime_parsing! {
pub struct MimeParsingUtf8 {
utf8 = true;
obsolte_syntax = false;
}
fn can_be_quoted(bch: PartialCodePoint) -> bool {
let idx = bch.as_u8() as usize;
MediaTypeChars::check_at(idx, Any::new(Ws) | QText | DQuoteOrEscape)
}
}