summaryrefslogtreecommitdiffstats
path: root/target/doc/src/mailparse/lib.rs.html
diff options
context:
space:
mode:
Diffstat (limited to 'target/doc/src/mailparse/lib.rs.html')
-rw-r--r--target/doc/src/mailparse/lib.rs.html692
1 files changed, 531 insertions, 161 deletions
diff --git a/target/doc/src/mailparse/lib.rs.html b/target/doc/src/mailparse/lib.rs.html
index f97606e..1912221 100644
--- a/target/doc/src/mailparse/lib.rs.html
+++ b/target/doc/src/mailparse/lib.rs.html
@@ -1067,6 +1067,191 @@
<span id="1022">1022</span>
<span id="1023">1023</span>
<span id="1024">1024</span>
+<span id="1025">1025</span>
+<span id="1026">1026</span>
+<span id="1027">1027</span>
+<span id="1028">1028</span>
+<span id="1029">1029</span>
+<span id="1030">1030</span>
+<span id="1031">1031</span>
+<span id="1032">1032</span>
+<span id="1033">1033</span>
+<span id="1034">1034</span>
+<span id="1035">1035</span>
+<span id="1036">1036</span>
+<span id="1037">1037</span>
+<span id="1038">1038</span>
+<span id="1039">1039</span>
+<span id="1040">1040</span>
+<span id="1041">1041</span>
+<span id="1042">1042</span>
+<span id="1043">1043</span>
+<span id="1044">1044</span>
+<span id="1045">1045</span>
+<span id="1046">1046</span>
+<span id="1047">1047</span>
+<span id="1048">1048</span>
+<span id="1049">1049</span>
+<span id="1050">1050</span>
+<span id="1051">1051</span>
+<span id="1052">1052</span>
+<span id="1053">1053</span>
+<span id="1054">1054</span>
+<span id="1055">1055</span>
+<span id="1056">1056</span>
+<span id="1057">1057</span>
+<span id="1058">1058</span>
+<span id="1059">1059</span>
+<span id="1060">1060</span>
+<span id="1061">1061</span>
+<span id="1062">1062</span>
+<span id="1063">1063</span>
+<span id="1064">1064</span>
+<span id="1065">1065</span>
+<span id="1066">1066</span>
+<span id="1067">1067</span>
+<span id="1068">1068</span>
+<span id="1069">1069</span>
+<span id="1070">1070</span>
+<span id="1071">1071</span>
+<span id="1072">1072</span>
+<span id="1073">1073</span>
+<span id="1074">1074</span>
+<span id="1075">1075</span>
+<span id="1076">1076</span>
+<span id="1077">1077</span>
+<span id="1078">1078</span>
+<span id="1079">1079</span>
+<span id="1080">1080</span>
+<span id="1081">1081</span>
+<span id="1082">1082</span>
+<span id="1083">1083</span>
+<span id="1084">1084</span>
+<span id="1085">1085</span>
+<span id="1086">1086</span>
+<span id="1087">1087</span>
+<span id="1088">1088</span>
+<span id="1089">1089</span>
+<span id="1090">1090</span>
+<span id="1091">1091</span>
+<span id="1092">1092</span>
+<span id="1093">1093</span>
+<span id="1094">1094</span>
+<span id="1095">1095</span>
+<span id="1096">1096</span>
+<span id="1097">1097</span>
+<span id="1098">1098</span>
+<span id="1099">1099</span>
+<span id="1100">1100</span>
+<span id="1101">1101</span>
+<span id="1102">1102</span>
+<span id="1103">1103</span>
+<span id="1104">1104</span>
+<span id="1105">1105</span>
+<span id="1106">1106</span>
+<span id="1107">1107</span>
+<span id="1108">1108</span>
+<span id="1109">1109</span>
+<span id="1110">1110</span>
+<span id="1111">1111</span>
+<span id="1112">1112</span>
+<span id="1113">1113</span>
+<span id="1114">1114</span>
+<span id="1115">1115</span>
+<span id="1116">1116</span>
+<span id="1117">1117</span>
+<span id="1118">1118</span>
+<span id="1119">1119</span>
+<span id="1120">1120</span>
+<span id="1121">1121</span>
+<span id="1122">1122</span>
+<span id="1123">1123</span>
+<span id="1124">1124</span>
+<span id="1125">1125</span>
+<span id="1126">1126</span>
+<span id="1127">1127</span>
+<span id="1128">1128</span>
+<span id="1129">1129</span>
+<span id="1130">1130</span>
+<span id="1131">1131</span>
+<span id="1132">1132</span>
+<span id="1133">1133</span>
+<span id="1134">1134</span>
+<span id="1135">1135</span>
+<span id="1136">1136</span>
+<span id="1137">1137</span>
+<span id="1138">1138</span>
+<span id="1139">1139</span>
+<span id="1140">1140</span>
+<span id="1141">1141</span>
+<span id="1142">1142</span>
+<span id="1143">1143</span>
+<span id="1144">1144</span>
+<span id="1145">1145</span>
+<span id="1146">1146</span>
+<span id="1147">1147</span>
+<span id="1148">1148</span>
+<span id="1149">1149</span>
+<span id="1150">1150</span>
+<span id="1151">1151</span>
+<span id="1152">1152</span>
+<span id="1153">1153</span>
+<span id="1154">1154</span>
+<span id="1155">1155</span>
+<span id="1156">1156</span>
+<span id="1157">1157</span>
+<span id="1158">1158</span>
+<span id="1159">1159</span>
+<span id="1160">1160</span>
+<span id="1161">1161</span>
+<span id="1162">1162</span>
+<span id="1163">1163</span>
+<span id="1164">1164</span>
+<span id="1165">1165</span>
+<span id="1166">1166</span>
+<span id="1167">1167</span>
+<span id="1168">1168</span>
+<span id="1169">1169</span>
+<span id="1170">1170</span>
+<span id="1171">1171</span>
+<span id="1172">1172</span>
+<span id="1173">1173</span>
+<span id="1174">1174</span>
+<span id="1175">1175</span>
+<span id="1176">1176</span>
+<span id="1177">1177</span>
+<span id="1178">1178</span>
+<span id="1179">1179</span>
+<span id="1180">1180</span>
+<span id="1181">1181</span>
+<span id="1182">1182</span>
+<span id="1183">1183</span>
+<span id="1184">1184</span>
+<span id="1185">1185</span>
+<span id="1186">1186</span>
+<span id="1187">1187</span>
+<span id="1188">1188</span>
+<span id="1189">1189</span>
+<span id="1190">1190</span>
+<span id="1191">1191</span>
+<span id="1192">1192</span>
+<span id="1193">1193</span>
+<span id="1194">1194</span>
+<span id="1195">1195</span>
+<span id="1196">1196</span>
+<span id="1197">1197</span>
+<span id="1198">1198</span>
+<span id="1199">1199</span>
+<span id="1200">1200</span>
+<span id="1201">1201</span>
+<span id="1202">1202</span>
+<span id="1203">1203</span>
+<span id="1204">1204</span>
+<span id="1205">1205</span>
+<span id="1206">1206</span>
+<span id="1207">1207</span>
+<span id="1208">1208</span>
+<span id="1209">1209</span>
</pre><pre class="rust ">
<span class="kw">extern</span> <span class="kw">crate</span> <span class="ident">base64</span>;
<span class="kw">extern</span> <span class="kw">crate</span> <span class="ident">encoding</span>;
@@ -1076,6 +1261,7 @@
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">error</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">fmt</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">ops</span>::<span class="ident">Deref</span>;
+<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">collections</span>::<span class="ident">BTreeMap</span>;
<span class="kw">use</span> <span class="ident">encoding</span>::<span class="ident">Encoding</span>;
@@ -1217,9 +1403,13 @@
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span> <span class="ident">MailHeader</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span> {
<span class="doccomment">/// Get the name of the header. Note that header names are case-insensitive.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">get_key</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">String</span>, <span class="ident">MailParseError</span><span class="op">&gt;</span> {
- <span class="prelude-val">Ok</span>(<span class="macro">try</span><span class="macro">!</span>(<span class="ident">encoding</span>::<span class="ident">all</span>::<span class="ident">ISO_8859_1</span>.<span class="ident">decode</span>(<span class="self">self</span>.<span class="ident">key</span>, <span class="ident">encoding</span>::<span class="ident">DecoderTrap</span>::<span class="ident">Strict</span>))
- .<span class="ident">trim</span>()
- .<span class="ident">to_string</span>())
+ <span class="prelude-val">Ok</span>(
+ <span class="macro">try</span><span class="macro">!</span>(<span class="ident">encoding</span>::<span class="ident">all</span>::<span class="ident">ISO_8859_1</span>.<span class="ident">decode</span>(
+ <span class="self">self</span>.<span class="ident">key</span>,
+ <span class="ident">encoding</span>::<span class="ident">DecoderTrap</span>::<span class="ident">Strict</span>,
+ )).<span class="ident">trim</span>()
+ .<span class="ident">to_string</span>(),
+ )
}
<span class="kw">fn</span> <span class="ident">decode_word</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">encoded</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>) <span class="op">-&gt;</span> <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span> {
@@ -1238,17 +1428,21 @@
<span class="comment">// whitespace</span>
<span class="kw">let</span> <span class="ident">to_decode</span> <span class="op">=</span> <span class="ident">input</span>.<span class="ident">replace</span>(<span class="string">&quot;_&quot;</span>, <span class="string">&quot; &quot;</span>);
<span class="kw">let</span> <span class="ident">trimmed</span> <span class="op">=</span> <span class="ident">to_decode</span>.<span class="ident">trim_right</span>();
- <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">d</span> <span class="op">=</span> <span class="ident">quoted_printable</span>::<span class="ident">decode_str</span>(<span class="kw-2">&amp;</span><span class="ident">trimmed</span>,
- <span class="ident">quoted_printable</span>::<span class="ident">ParseMode</span>::<span class="ident">Robust</span>);
+ <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">d</span> <span class="op">=</span>
+ <span class="ident">quoted_printable</span>::<span class="ident">decode_str</span>(<span class="kw-2">&amp;</span><span class="ident">trimmed</span>, <span class="ident">quoted_printable</span>::<span class="ident">ParseMode</span>::<span class="ident">Robust</span>);
<span class="kw">if</span> <span class="ident">d</span>.<span class="ident">is_ok</span>() <span class="op">&amp;&amp;</span> <span class="ident">to_decode</span>.<span class="ident">len</span>() <span class="op">!=</span> <span class="ident">trimmed</span>.<span class="ident">len</span>() {
- <span class="ident">d</span>.<span class="ident">as_mut</span>().<span class="ident">unwrap</span>().<span class="ident">extend_from_slice</span>(<span class="ident">to_decode</span>[<span class="ident">trimmed</span>.<span class="ident">len</span>()..].<span class="ident">as_bytes</span>());
+ <span class="ident">d</span>.<span class="ident">as_mut</span>().<span class="ident">unwrap</span>().<span class="ident">extend_from_slice</span>(
+ <span class="ident">to_decode</span>[<span class="ident">trimmed</span>.<span class="ident">len</span>()..].<span class="ident">as_bytes</span>(),
+ );
}
<span class="macro">try_none</span><span class="macro">!</span>(<span class="ident">d</span>.<span class="ident">ok</span>())
}
_ <span class="op">=&gt;</span> <span class="kw">return</span> <span class="prelude-val">None</span>,
};
<span class="kw">let</span> <span class="ident">charset_conv</span> <span class="op">=</span> <span class="macro">try_none</span><span class="macro">!</span>(<span class="ident">encoding</span>::<span class="ident">label</span>::<span class="ident">encoding_from_whatwg_label</span>(<span class="ident">charset</span>));
- <span class="ident">charset_conv</span>.<span class="ident">decode</span>(<span class="kw-2">&amp;</span><span class="ident">decoded</span>, <span class="ident">encoding</span>::<span class="ident">DecoderTrap</span>::<span class="ident">Replace</span>).<span class="ident">ok</span>()
+ <span class="ident">charset_conv</span>
+ .<span class="ident">decode</span>(<span class="kw-2">&amp;</span><span class="ident">decoded</span>, <span class="ident">encoding</span>::<span class="ident">DecoderTrap</span>::<span class="ident">Replace</span>)
+ .<span class="ident">ok</span>()
}
<span class="doccomment">/// Get the value of the header. Any sequences of newlines characters followed</span>
@@ -1266,8 +1460,10 @@
<span class="doccomment">/// ```</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">get_value</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">String</span>, <span class="ident">MailParseError</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">result</span> <span class="op">=</span> <span class="ident">String</span>::<span class="ident">new</span>();
- <span class="kw">let</span> <span class="ident">chars</span> <span class="op">=</span>
- <span class="macro">try</span><span class="macro">!</span>(<span class="ident">encoding</span>::<span class="ident">all</span>::<span class="ident">ISO_8859_1</span>.<span class="ident">decode</span>(<span class="self">self</span>.<span class="ident">value</span>, <span class="ident">encoding</span>::<span class="ident">DecoderTrap</span>::<span class="ident">Strict</span>));
+ <span class="kw">let</span> <span class="ident">chars</span> <span class="op">=</span> <span class="macro">try</span><span class="macro">!</span>(<span class="ident">encoding</span>::<span class="ident">all</span>::<span class="ident">ISO_8859_1</span>.<span class="ident">decode</span>(
+ <span class="self">self</span>.<span class="ident">value</span>,
+ <span class="ident">encoding</span>::<span class="ident">DecoderTrap</span>::<span class="ident">Strict</span>,
+ ));
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">lines</span> <span class="op">=</span> <span class="ident">chars</span>.<span class="ident">lines</span>();
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">add_space</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="kw">loop</span> {
@@ -1372,9 +1568,11 @@
<span class="kw">match</span> <span class="ident">state</span> {
<span class="ident">HeaderParseState</span>::<span class="ident">Initial</span> <span class="op">=&gt;</span> {
<span class="kw">if</span> <span class="ident">c</span> <span class="op">==</span> <span class="string">b&#39; &#39;</span> {
- <span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">MailParseError</span>::<span class="ident">Generic</span>(<span class="string">&quot;Header cannot start with a space; it is \
+ <span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">MailParseError</span>::<span class="ident">Generic</span>(
+ <span class="string">&quot;Header cannot start with a space; it is \
likely an overhanging line from a \
- previous header&quot;</span>));
+ previous header&quot;</span>,
+ ));
};
<span class="ident">state</span> <span class="op">=</span> <span class="ident">HeaderParseState</span>::<span class="ident">Key</span>;
<span class="kw">continue</span>;
@@ -1419,14 +1617,18 @@
}
<span class="kw">match</span> <span class="ident">ix_key_end</span> {
<span class="prelude-val">Some</span>(<span class="ident">v</span>) <span class="op">=&gt;</span> {
- <span class="prelude-val">Ok</span>((<span class="ident">MailHeader</span> {
- <span class="ident">key</span>: <span class="kw-2">&amp;</span><span class="ident">raw_data</span>[<span class="number">0</span>..<span class="ident">v</span>],
- <span class="ident">value</span>: <span class="kw-2">&amp;</span><span class="ident">raw_data</span>[<span class="ident">ix_value_start</span>..<span class="ident">ix_value_end</span>],
- },
- <span class="ident">ix</span>))
+ <span class="prelude-val">Ok</span>((
+ <span class="ident">MailHeader</span> {
+ <span class="ident">key</span>: <span class="kw-2">&amp;</span><span class="ident">raw_data</span>[<span class="number">0</span>..<span class="ident">v</span>],
+ <span class="ident">value</span>: <span class="kw-2">&amp;</span><span class="ident">raw_data</span>[<span class="ident">ix_value_start</span>..<span class="ident">ix_value_end</span>],
+ },
+ <span class="ident">ix</span>,
+ ))
}
- <span class="prelude-val">None</span> <span class="op">=&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">MailParseError</span>::<span class="ident">Generic</span>(<span class="string">&quot;Unable to determine end of the header key component&quot;</span>)),
+ <span class="prelude-val">None</span> <span class="op">=&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">MailParseError</span>::<span class="ident">Generic</span>(
+ <span class="string">&quot;Unable to determine end of the header key component&quot;</span>,
+ )),
}
}
@@ -1527,8 +1729,10 @@
<span class="ident">ix</span> <span class="op">=</span> <span class="ident">ix</span> <span class="op">+</span> <span class="number">2</span>;
<span class="kw">break</span>;
} <span class="kw">else</span> {
- <span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">MailParseError</span>::<span class="ident">Generic</span>(<span class="string">&quot;Headers were followed by an unexpected lone \
- CR character!&quot;</span>));
+ <span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">MailParseError</span>::<span class="ident">Generic</span>(
+ <span class="string">&quot;Headers were followed by an unexpected lone \
+ CR character!&quot;</span>,
+ ));
}
}
<span class="kw">let</span> (<span class="ident">header</span>, <span class="ident">ix_next</span>) <span class="op">=</span> <span class="macro">try</span><span class="macro">!</span>(<span class="ident">parse_header</span>(<span class="kw-2">&amp;</span><span class="ident">raw_data</span>[<span class="ident">ix</span>..]));
@@ -1548,18 +1752,27 @@
<span class="doccomment">/// The charset used to decode the raw byte data, for example &quot;iso-8859-1&quot;</span>
<span class="doccomment">/// or &quot;utf-8&quot;.</span>
<span class="kw">pub</span> <span class="ident">charset</span>: <span class="ident">String</span>,
- <span class="doccomment">/// The boundary used to separate the different parts of a multipart message.</span>
- <span class="doccomment">/// This boundary is taken straight from the Content-Type header, and so</span>
- <span class="doccomment">/// the body will actually contain the boundary string prefixed by two</span>
- <span class="doccomment">/// dashes.</span>
- <span class="kw">pub</span> <span class="ident">boundary</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
- <span class="doccomment">/// The name of the content, if available</span>
- <span class="kw">pub</span> <span class="ident">name</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
+ <span class="doccomment">/// The additional params of Content-Type, e.g. filename and boundary. The</span>
+ <span class="doccomment">/// keys in the map will be lowercased, and the values will have any</span>
+ <span class="doccomment">/// enclosing quotes stripped.</span>
+ <span class="kw">pub</span> <span class="ident">params</span>: <span class="ident">BTreeMap</span><span class="op">&lt;</span><span class="ident">String</span>, <span class="ident">String</span><span class="op">&gt;</span>,
}
-<span class="doccomment">/// Helper method to parse a header value as a Content-Type header. The charset</span>
-<span class="doccomment">/// defaults to &quot;us-ascii&quot; if no charset parameter is provided in the header</span>
-<span class="doccomment">/// value.</span>
+<span class="kw">impl</span> <span class="ident">Default</span> <span class="kw">for</span> <span class="ident">ParsedContentType</span> {
+ <span class="kw">fn</span> <span class="ident">default</span>() <span class="op">-&gt;</span> <span class="self">Self</span> {
+ <span class="ident">ParsedContentType</span> {
+ <span class="ident">mimetype</span>: <span class="string">&quot;text/plain&quot;</span>.<span class="ident">to_string</span>(),
+ <span class="ident">charset</span>: <span class="string">&quot;us-ascii&quot;</span>.<span class="ident">to_string</span>(),
+ <span class="ident">params</span>: <span class="ident">BTreeMap</span>::<span class="ident">new</span>(),
+ }
+ }
+}
+
+<span class="doccomment">/// Helper method to parse a header value as a Content-Type header. Note that</span>
+<span class="doccomment">/// the returned object&#39;s `params` map will contain a charset key if a charset</span>
+<span class="doccomment">/// was explicitly specified in the header; otherwise the `params` map will not</span>
+<span class="doccomment">/// contain a charset key. Regardless, the `charset` field will contain a</span>
+<span class="doccomment">/// charset - either the one explicitly specified or the default of &quot;us-ascii&quot;.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Examples</span>
<span class="doccomment">/// ```</span>
@@ -1567,57 +1780,115 @@
<span class="doccomment">/// let (parsed, _) = parse_header(</span>
<span class="doccomment">/// b&quot;Content-Type: text/html; charset=foo; boundary=\&quot;quotes_are_removed\&quot;&quot;)</span>
<span class="doccomment">/// .unwrap();</span>
-<span class="doccomment">/// let ctype = parse_content_type(&amp;parsed.get_value().unwrap()).unwrap();</span>
+<span class="doccomment">/// let ctype = parse_content_type(&amp;parsed.get_value().unwrap());</span>
<span class="doccomment">/// assert_eq!(ctype.mimetype, &quot;text/html&quot;);</span>
<span class="doccomment">/// assert_eq!(ctype.charset, &quot;foo&quot;);</span>
-<span class="doccomment">/// assert_eq!(ctype.boundary, Some(&quot;quotes_are_removed&quot;.to_string()));</span>
+<span class="doccomment">/// assert_eq!(ctype.params.get(&quot;boundary&quot;), Some(&amp;&quot;quotes_are_removed&quot;.to_string()));</span>
+<span class="doccomment">/// assert_eq!(ctype.params.get(&quot;charset&quot;), Some(&amp;&quot;foo&quot;.to_string()));</span>
<span class="doccomment">/// ```</span>
<span class="doccomment">/// ```</span>
<span class="doccomment">/// use mailparse::{parse_header, parse_content_type};</span>
<span class="doccomment">/// let (parsed, _) = parse_header(b&quot;Content-Type: bogus&quot;).unwrap();</span>
-<span class="doccomment">/// let ctype = parse_content_type(&amp;parsed.get_value().unwrap()).unwrap();</span>
+<span class="doccomment">/// let ctype = parse_content_type(&amp;parsed.get_value().unwrap());</span>
<span class="doccomment">/// assert_eq!(ctype.mimetype, &quot;bogus&quot;);</span>
<span class="doccomment">/// assert_eq!(ctype.charset, &quot;us-ascii&quot;);</span>
-<span class="doccomment">/// assert_eq!(ctype.boundary, None);</span>
+<span class="doccomment">/// assert_eq!(ctype.params.get(&quot;boundary&quot;), None);</span>
+<span class="doccomment">/// assert_eq!(ctype.params.get(&quot;charset&quot;), None);</span>
<span class="doccomment">/// ```</span>
<span class="doccomment">/// ```</span>
<span class="doccomment">/// use mailparse::{parse_header, parse_content_type};</span>
<span class="doccomment">/// let (parsed, _) = parse_header(br#&quot;Content-Type: application/octet-stream;name=&quot;=?utf8?B?6L+O5ai255m95a+M576O?=&quot;;charset=&quot;utf8&quot;&quot;#).unwrap();</span>
-<span class="doccomment">/// let ctype = parse_content_type(&amp;parsed.get_value().unwrap()).unwrap();</span>
+<span class="doccomment">/// let ctype = parse_content_type(&amp;parsed.get_value().unwrap());</span>
<span class="doccomment">/// assert_eq!(ctype.mimetype, &quot;application/octet-stream&quot;);</span>
<span class="doccomment">/// assert_eq!(ctype.charset, &quot;utf8&quot;);</span>
-<span class="doccomment">/// assert_eq!(ctype.boundary, None);</span>
-<span class="doccomment">/// assert_eq!(ctype.name, Some(&quot;迎娶白富美&quot;.to_string()));</span>
+<span class="doccomment">/// assert_eq!(ctype.params.get(&quot;boundary&quot;), None);</span>
+<span class="doccomment">/// assert_eq!(ctype.params.get(&quot;name&quot;), Some(&amp;&quot;迎娶白富美&quot;.to_string()));</span>
<span class="doccomment">/// ```</span>
-<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">parse_content_type</span>(<span class="ident">header</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>) <span class="op">-&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">ParsedContentType</span>, <span class="ident">MailParseError</span><span class="op">&gt;</span> {
- <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">parsed_type</span> <span class="op">=</span> <span class="ident">ParsedContentType</span> {
- <span class="ident">mimetype</span>: <span class="string">&quot;text/plain&quot;</span>.<span class="ident">to_string</span>(),
- <span class="ident">charset</span>: <span class="string">&quot;us-ascii&quot;</span>.<span class="ident">to_string</span>(),
- <span class="ident">boundary</span>: <span class="prelude-val">None</span>,
- <span class="ident">name</span>: <span class="prelude-val">None</span>,
- };
- <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">tokens</span> <span class="op">=</span> <span class="ident">header</span>.<span class="ident">split</span>(<span class="string">&#39;;&#39;</span>);
- <span class="comment">// There must be at least one token produced by split, even if it&#39;s empty.</span>
- <span class="ident">parsed_type</span>.<span class="ident">mimetype</span> <span class="op">=</span> <span class="ident">String</span>::<span class="ident">from</span>(<span class="ident">tokens</span>.<span class="ident">next</span>().<span class="ident">unwrap</span>().<span class="ident">trim</span>()).<span class="ident">to_lowercase</span>();
- <span class="kw">while</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">param</span>) <span class="op">=</span> <span class="ident">tokens</span>.<span class="ident">next</span>() {
- <span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">ix_eq</span>) <span class="op">=</span> <span class="ident">param</span>.<span class="ident">find</span>(<span class="string">&#39;=&#39;</span>) {
- <span class="kw">let</span> <span class="ident">attr</span> <span class="op">=</span> <span class="ident">param</span>[<span class="number">0</span>..<span class="ident">ix_eq</span>].<span class="ident">trim</span>().<span class="ident">to_lowercase</span>();
- <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">value</span> <span class="op">=</span> <span class="ident">param</span>[<span class="ident">ix_eq</span> <span class="op">+</span> <span class="number">1</span>..].<span class="ident">trim</span>();
- <span class="kw">if</span> <span class="ident">value</span>.<span class="ident">starts_with</span>(<span class="string">&#39;&quot;&#39;</span>) <span class="op">&amp;&amp;</span> <span class="ident">value</span>.<span class="ident">ends_with</span>(<span class="string">&#39;&quot;&#39;</span>) {
- <span class="ident">value</span> <span class="op">=</span> <span class="kw-2">&amp;</span><span class="ident">value</span>[<span class="number">1</span>..<span class="ident">value</span>.<span class="ident">len</span>() <span class="op">-</span> <span class="number">1</span>];
- }
+<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">parse_content_type</span>(<span class="ident">header</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>) <span class="op">-&gt;</span> <span class="ident">ParsedContentType</span> {
+ <span class="kw">let</span> <span class="ident">params</span> <span class="op">=</span> <span class="ident">parse_param_content</span>(<span class="ident">header</span>);
+ <span class="kw">let</span> <span class="ident">mimetype</span> <span class="op">=</span> <span class="ident">params</span>.<span class="ident">value</span>.<span class="ident">to_lowercase</span>();
+ <span class="kw">let</span> <span class="ident">charset</span> <span class="op">=</span> <span class="ident">params</span>.<span class="ident">params</span>.<span class="ident">get</span>(<span class="string">&quot;charset&quot;</span>).<span class="ident">cloned</span>().<span class="ident">unwrap_or</span>(
+ <span class="string">&quot;us-ascii&quot;</span>.<span class="ident">to_string</span>(),
+ );
+
+ <span class="ident">ParsedContentType</span> {
+ <span class="ident">mimetype</span>: <span class="ident">mimetype</span>,
+ <span class="ident">charset</span>: <span class="ident">charset</span>,
+ <span class="ident">params</span>: <span class="ident">params</span>.<span class="ident">params</span>,
+ }
+}
- <span class="kw">match</span> <span class="kw-2">&amp;</span><span class="ident">attr</span>[..] {
- <span class="string">&quot;charset&quot;</span> <span class="op">=&gt;</span> <span class="ident">parsed_type</span>.<span class="ident">charset</span> <span class="op">=</span> <span class="ident">String</span>::<span class="ident">from</span>(<span class="ident">value</span>).<span class="ident">to_lowercase</span>(),
- <span class="string">&quot;boundary&quot;</span> <span class="op">=&gt;</span> <span class="ident">parsed_type</span>.<span class="ident">boundary</span> <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">String</span>::<span class="ident">from</span>(<span class="ident">value</span>)),
- <span class="string">&quot;name&quot;</span> <span class="op">=&gt;</span> <span class="ident">parsed_type</span>.<span class="ident">name</span> <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">String</span>::<span class="ident">from</span>(<span class="ident">value</span>)),
- _ <span class="op">=&gt;</span> {}
- }
+<span class="doccomment">/// The possible disposition types in a Content-Disposition header. A more</span>
+<span class="doccomment">/// comprehensive list of IANA-recognized types can be found at</span>
+<span class="doccomment">/// https://www.iana.org/assignments/cont-disp/cont-disp.xhtml. This library</span>
+<span class="doccomment">/// only enumerates the types most commonly found in email messages, and</span>
+<span class="doccomment">/// provides the `Extension` value for holding all other types.</span>
+<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Clone</span>, <span class="ident">PartialEq</span>)]</span>
+<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">DispositionType</span> {
+ <span class="doccomment">/// Default value, indicating the content is to be displayed inline as</span>
+ <span class="doccomment">/// part of the enclosing document.</span>
+ <span class="ident">Inline</span>,
+ <span class="doccomment">/// A disposition indicating the content is not meant for inline display,</span>
+ <span class="doccomment">/// but whose content can be accessed for use.</span>
+ <span class="ident">Attachment</span>,
+ <span class="doccomment">/// A disposition indicating the content contains a form submission.</span>
+ <span class="ident">FormData</span>,
+ <span class="doccomment">/// Extension type to hold any disposition not explicitly enumerated.</span>
+ <span class="ident">Extension</span>(<span class="ident">String</span>),
+}
- } <span class="comment">// else invalid token, ignore. We could throw an error but this</span>
- <span class="comment">// actually happens in some cases that we want to otherwise handle.</span>
+<span class="kw">impl</span> <span class="ident">Default</span> <span class="kw">for</span> <span class="ident">DispositionType</span> {
+ <span class="kw">fn</span> <span class="ident">default</span>() <span class="op">-&gt;</span> <span class="self">Self</span> {
+ <span class="ident">DispositionType</span>::<span class="ident">Inline</span>
+ }
+}
+
+<span class="doccomment">/// Convert the string represented disposition type to enum.</span>
+<span class="kw">fn</span> <span class="ident">parse_disposition_type</span>(<span class="ident">disposition</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>) <span class="op">-&gt;</span> <span class="ident">DispositionType</span> {
+ <span class="kw">match</span> <span class="kw-2">&amp;</span><span class="ident">disposition</span>.<span class="ident">to_lowercase</span>()[..] {
+ <span class="string">&quot;inline&quot;</span> <span class="op">=&gt;</span> <span class="ident">DispositionType</span>::<span class="ident">Inline</span>,
+ <span class="string">&quot;attachment&quot;</span> <span class="op">=&gt;</span> <span class="ident">DispositionType</span>::<span class="ident">Attachment</span>,
+ <span class="string">&quot;form-data&quot;</span> <span class="op">=&gt;</span> <span class="ident">DispositionType</span>::<span class="ident">FormData</span>,
+ <span class="ident">extension</span> <span class="op">=&gt;</span> <span class="ident">DispositionType</span>::<span class="ident">Extension</span>(<span class="ident">extension</span>.<span class="ident">to_string</span>()),
+ }
+}
+
+<span class="doccomment">/// A struct to hold a more structured representation of the Content-Disposition header.</span>
+<span class="doccomment">/// This is provided mostly as a convenience since this metadata is usually</span>
+<span class="doccomment">/// needed to interpret the message body properly.</span>
+<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Default</span>)]</span>
+<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">ParsedContentDisposition</span> {
+ <span class="doccomment">/// The disposition type of the Content-Disposition header. If this</span>
+ <span class="doccomment">/// is an extension type, the string will be lowercased.</span>
+ <span class="kw">pub</span> <span class="ident">disposition</span>: <span class="ident">DispositionType</span>,
+ <span class="doccomment">/// The additional params of Content-Disposition, e.g. filename. The</span>
+ <span class="doccomment">/// keys in the map will be lowercased, and the values will have any</span>
+ <span class="doccomment">/// enclosing quotes stripped.</span>
+ <span class="kw">pub</span> <span class="ident">params</span>: <span class="ident">BTreeMap</span><span class="op">&lt;</span><span class="ident">String</span>, <span class="ident">String</span><span class="op">&gt;</span>,
+}
+
+<span class="doccomment">/// Helper method to parse a header value as a Content-Disposition header. The disposition</span>
+<span class="doccomment">/// defaults to &quot;inline&quot; if no disposition parameter is provided in the header</span>
+<span class="doccomment">/// value.</span>
+<span class="doccomment">///</span>
+<span class="doccomment">/// # Examples</span>
+<span class="doccomment">/// ```</span>
+<span class="doccomment">/// use mailparse::{parse_header, parse_content_disposition, DispositionType};</span>
+<span class="doccomment">/// let (parsed, _) = parse_header(</span>
+<span class="doccomment">/// b&quot;Content-Disposition: attachment; filename=\&quot;yummy dummy\&quot;&quot;)</span>
+<span class="doccomment">/// .unwrap();</span>
+<span class="doccomment">/// let dis = parse_content_disposition(&amp;parsed.get_value().unwrap());</span>
+<