diff options
Diffstat (limited to 'target/doc/src/mailparse/lib.rs.html')
-rw-r--r-- | target/doc/src/mailparse/lib.rs.html | 692 |
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"><</span><span class="lifetime">'a</span><span class="op">></span> <span class="ident">MailHeader</span><span class="op"><</span><span class="lifetime">'a</span><span class="op">></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">&</span><span class="self">self</span>) <span class="op">-></span> <span class="prelude-ty">Result</span><span class="op"><</span><span class="ident">String</span>, <span class="ident">MailParseError</span><span class="op">></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">&</span><span class="self">self</span>, <span class="ident">encoded</span>: <span class="kw-2">&</span><span class="ident">str</span>) <span class="op">-></span> <span class="prelude-ty">Option</span><span class="op"><</span><span class="ident">String</span><span class="op">></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">"_"</span>, <span class="string">" "</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">&</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">&</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">&&</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">=></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">&</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">&</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">&</span><span class="self">self</span>) <span class="op">-></span> <span class="prelude-ty">Result</span><span class="op"><</span><span class="ident">String</span>, <span class="ident">MailParseError</span><span class="op">></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">=></span> { <span class="kw">if</span> <span class="ident">c</span> <span class="op">==</span> <span class="string">b' '</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">"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">"Header cannot start with a space; it is \ likely an overhanging line from a \ - previous header"</span>)); + previous header"</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">=></span> { - <span class="prelude-val">Ok</span>((<span class="ident">MailHeader</span> { - <span class="ident">key</span>: <span class="kw-2">&</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">&</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">&</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">&</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">=></span> <span class="prelude-val">Err</span>(<span class="ident">MailParseError</span>::<span class="ident">Generic</span>(<span class="string">"Unable to determine end of the header key component"</span>)), + <span class="prelude-val">None</span> <span class="op">=></span> <span class="prelude-val">Err</span>(<span class="ident">MailParseError</span>::<span class="ident">Generic</span>( + <span class="string">"Unable to determine end of the header key component"</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">"Headers were followed by an unexpected lone \ - CR character!"</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">"Headers were followed by an unexpected lone \ + CR character!"</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">&</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 "iso-8859-1"</span> <span class="doccomment">/// or "utf-8".</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"><</span><span class="ident">String</span><span class="op">></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"><</span><span class="ident">String</span><span class="op">></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"><</span><span class="ident">String</span>, <span class="ident">String</span><span class="op">></span>, } -<span class="doccomment">/// Helper method to parse a header value as a Content-Type header. The charset</span> -<span class="doccomment">/// defaults to "us-ascii" 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">-></span> <span class="self">Self</span> { + <span class="ident">ParsedContentType</span> { + <span class="ident">mimetype</span>: <span class="string">"text/plain"</span>.<span class="ident">to_string</span>(), + <span class="ident">charset</span>: <span class="string">"us-ascii"</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'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 "us-ascii".</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"Content-Type: text/html; charset=foo; boundary=\"quotes_are_removed\"")</span> <span class="doccomment">/// .unwrap();</span> -<span class="doccomment">/// let ctype = parse_content_type(&parsed.get_value().unwrap()).unwrap();</span> +<span class="doccomment">/// let ctype = parse_content_type(&parsed.get_value().unwrap());</span> <span class="doccomment">/// assert_eq!(ctype.mimetype, "text/html");</span> <span class="doccomment">/// assert_eq!(ctype.charset, "foo");</span> -<span class="doccomment">/// assert_eq!(ctype.boundary, Some("quotes_are_removed".to_string()));</span> +<span class="doccomment">/// assert_eq!(ctype.params.get("boundary"), Some(&"quotes_are_removed".to_string()));</span> +<span class="doccomment">/// assert_eq!(ctype.params.get("charset"), Some(&"foo".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"Content-Type: bogus").unwrap();</span> -<span class="doccomment">/// let ctype = parse_content_type(&parsed.get_value().unwrap()).unwrap();</span> +<span class="doccomment">/// let ctype = parse_content_type(&parsed.get_value().unwrap());</span> <span class="doccomment">/// assert_eq!(ctype.mimetype, "bogus");</span> <span class="doccomment">/// assert_eq!(ctype.charset, "us-ascii");</span> -<span class="doccomment">/// assert_eq!(ctype.boundary, None);</span> +<span class="doccomment">/// assert_eq!(ctype.params.get("boundary"), None);</span> +<span class="doccomment">/// assert_eq!(ctype.params.get("charset"), 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#"Content-Type: application/octet-stream;name="=?utf8?B?6L+O5ai255m95a+M576O?=";charset="utf8""#).unwrap();</span> -<span class="doccomment">/// let ctype = parse_content_type(&parsed.get_value().unwrap()).unwrap();</span> +<span class="doccomment">/// let ctype = parse_content_type(&parsed.get_value().unwrap());</span> <span class="doccomment">/// assert_eq!(ctype.mimetype, "application/octet-stream");</span> <span class="doccomment">/// assert_eq!(ctype.charset, "utf8");</span> -<span class="doccomment">/// assert_eq!(ctype.boundary, None);</span> -<span class="doccomment">/// assert_eq!(ctype.name, Some("迎娶白富美".to_string()));</span> +<span class="doccomment">/// assert_eq!(ctype.params.get("boundary"), None);</span> +<span class="doccomment">/// assert_eq!(ctype.params.get("name"), Some(&"迎娶白富美".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">&</span><span class="ident">str</span>) <span class="op">-></span> <span class="prelude-ty">Result</span><span class="op"><</span><span class="ident">ParsedContentType</span>, <span class="ident">MailParseError</span><span class="op">></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">"text/plain"</span>.<span class="ident">to_string</span>(), - <span class="ident">charset</span>: <span class="string">"us-ascii"</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">';'</span>); - <span class="comment">// There must be at least one token produced by split, even if it'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">'='</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">'"'</span>) <span class="op">&&</span> <span class="ident">value</span>.<span class="ident">ends_with</span>(<span class="string">'"'</span>) { - <span class="ident">value</span> <span class="op">=</span> <span class="kw-2">&</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">&</span><span class="ident">str</span>) <span class="op">-></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">"charset"</span>).<span class="ident">cloned</span>().<span class="ident">unwrap_or</span>( + <span class="string">"us-ascii"</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">&</span><span class="ident">attr</span>[..] { - <span class="string">"charset"</span> <span class="op">=></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">"boundary"</span> <span class="op">=></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">"name"</span> <span class="op">=></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">=></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">-></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">&</span><span class="ident">str</span>) <span class="op">-></span> <span class="ident">DispositionType</span> { + <span class="kw">match</span> <span class="kw-2">&</span><span class="ident">disposition</span>.<span class="ident">to_lowercase</span>()[..] { + <span class="string">"inline"</span> <span class="op">=></span> <span class="ident">DispositionType</span>::<span class="ident">Inline</span>, + <span class="string">"attachment"</span> <span class="op">=></span> <span class="ident">DispositionType</span>::<span class="ident">Attachment</span>, + <span class="string">"form-data"</span> <span class="op">=></span> <span class="ident">DispositionType</span>::<span class="ident">FormData</span>, + <span class="ident">extension</span> <span class="op">=></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"><</span><span class="ident">String</span>, <span class="ident">String</span><span class="op">></span>, +} + +<span class="doccomment">/// Helper method to parse a header value as a Content-Disposition header. The disposition</span> +<span class="doccomment">/// defaults to "inline" 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"Content-Disposition: attachment; filename=\"yummy dummy\"")</span> +<span class="doccomment">/// .unwrap();</span> +<span class="doccomment">/// let dis = parse_content_disposition(&parsed.get_value().unwrap());</span> +< |