base_web_multipart/parameter_rules.rs
1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4use base_web_media_type::MediaType;
5
6/// The rules for a `Content-Disposition` field's extended parameters, such as `filename*`, when reading its name or filename. Forms and other MIME parts follow different RFCs, so a disposition does not choose for you.
7///
8/// ```
9/// use base_web_multipart::{ContentDisposition, ParameterRules};
10/// use base_web_media_type::MediaType;
11/// use base_message::FieldType;
12///
13/// let disposition = ContentDisposition::parse(b"attachment; filename=\"EURO rates\"; filename*=utf-8''%e2%82%ac%20rates")?;
14/// assert_eq!(disposition.filename(ParameterRules::Mime)?.as_deref(), Some("€ rates"));
15/// assert!(disposition.filename(ParameterRules::FormData).is_err());
16///
17/// let rules = ParameterRules::for_media_type(&MediaType::parse("multipart/form-data; boundary=x")?);
18/// assert_eq!(rules, ParameterRules::FormData);
19/// # Ok::<(), Box<dyn std::error::Error>>(())
20/// ```
21#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22pub enum ParameterRules {
23 /// RFC 7578, for `multipart/form-data`: extended parameters must not be used, so a disposition with any, including a continuation such as `filename*0`, is an error. Readers disagree about which of `filename` and `filename*` applies, so refusing both keeps them from seeing different names.
24 FormData,
25 /// RFC 2231, for other MIME parts, such as an email's attachments: an extended parameter, such as `filename*`, is decoded and takes the place of the plain one. Its character set must be UTF-8 or US-ASCII, and its percent-encoding valid; the language is ignored. Continuations, such as `filename*0`, are not supported yet and are an error.
26 Mime,
27}
28
29impl ParameterRules {
30 /// The rules for a body of this media type: `FormData` for `multipart/form-data`, and `Mime` for any other.
31 pub fn for_media_type(media_type: &MediaType) -> Self {
32 if media_type
33 .essence()
34 .eq_ignore_ascii_case("multipart/form-data")
35 {
36 Self::FormData
37 } else {
38 Self::Mime
39 }
40 }
41}