use super::content_type;
use super::header_parameter::leading_token;
use super::header_parameter::parse_parameters;
pub(in crate::formats::http) struct MultipartPartMetadata<'a> {
name: Option<String>,
filename: Option<String>,
content_type: Option<&'a str>,
}
impl<'a> MultipartPartMetadata<'a> {
#[must_use]
#[inline]
pub(super) fn parse(
disposition: Option<&str>,
content_type: Option<&'a str>,
require_form_data: bool,
) -> Option<Self> {
if content_type.is_some_and(|value| !content_type::is_valid(value)) {
return None;
}
let [name, filename, extended] = match disposition {
Some(disposition) => {
let disposition_kind = leading_token(disposition)?;
if require_form_data && !disposition_kind.eq_ignore_ascii_case("form-data") {
return None;
}
parse_parameters(disposition, ["name", "filename", "filename*"])?
}
None if require_form_data => return None,
None => [None, None, None],
};
Some(Self {
name: name.filter(|value| !value.trim().is_empty()),
filename: filename.or(extended),
content_type,
})
}
#[must_use]
#[inline(always)]
pub(super) fn name(&self) -> Option<&str> {
self.name.as_deref()
}
#[must_use]
#[inline(always)]
pub(super) fn filename(&self) -> Option<&str> {
self.filename.as_deref()
}
#[must_use]
#[inline(always)]
pub(super) const fn content_type(&self) -> Option<&'a str> {
self.content_type
}
}