Refactor media type internals to use Cow

This commit is contained in:
Yoshua Wuyts 2020-12-24 17:40:10 +01:00
parent f18821e3c3
commit 27950ea301
3 changed files with 24 additions and 58 deletions

View File

@ -1,5 +1,6 @@
use super::ParamKind;
use crate::Mime;
use std::borrow::Cow;
macro_rules! utf8_mime_const {
($name:ident, $desc:expr, $base:expr, $sub:expr) => {
@ -32,13 +33,10 @@ macro_rules! mime_const {
(doc_expanded, $name:ident, $desc:expr, $base:expr, $sub:expr, $params:expr, $doccomment:expr) => {
#[doc = $doccomment]
pub const $name: Mime = Mime {
essence: String::new(),
basetype: String::new(),
subtype: String::new(),
essence: Cow::Borrowed(concat!($base, "/", $sub)),
basetype: Cow::Borrowed($base),
subtype: Cow::Borrowed($sub),
params: $params,
static_essence: Some(concat!($base, "/", $sub)),
static_basetype: Some($base),
static_subtype: Some($sub),
};
};
}

View File

@ -28,14 +28,11 @@ use infer::Infer;
/// ```
// NOTE: we cannot statically initialize Strings with values yet, so we keep dedicated static
// fields for the static strings.
#[derive(Clone)]
#[derive(Clone, Eq)]
pub struct Mime {
pub(crate) essence: String,
pub(crate) basetype: String,
pub(crate) subtype: String,
pub(crate) static_essence: Option<&'static str>,
pub(crate) static_basetype: Option<&'static str>,
pub(crate) static_subtype: Option<&'static str>,
pub(crate) essence: Cow<'static, str>,
pub(crate) basetype: Cow<'static, str>,
pub(crate) subtype: Cow<'static, str>,
pub(crate) params: Option<ParamKind>,
}
@ -68,29 +65,17 @@ impl Mime {
/// According to the spec this method should be named `type`, but that's a reserved keyword in
/// Rust so hence prefix with `base` instead.
pub fn basetype(&self) -> &str {
if let Some(basetype) = self.static_basetype {
&basetype
} else {
&self.basetype
}
&self.basetype
}
/// Access the Mime's `subtype` value.
pub fn subtype(&self) -> &str {
if let Some(subtype) = self.static_subtype {
&subtype
} else {
&self.subtype
}
&self.subtype
}
/// Access the Mime's `essence` value.
pub fn essence(&self) -> &str {
if let Some(essence) = self.static_essence {
&essence
} else {
&self.essence
}
&self.essence
}
/// Get a reference to a param.
@ -138,20 +123,6 @@ impl Mime {
}
}
impl PartialEq<Mime> for Mime {
fn eq(&self, other: &Mime) -> bool {
let left = match self.static_essence {
Some(essence) => essence,
None => &self.essence,
};
let right = match other.static_essence {
Some(essence) => essence,
None => &other.essence,
};
left == right
}
}
impl Display for Mime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
parse::format(self, f)
@ -160,11 +131,7 @@ impl Display for Mime {
impl Debug for Mime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(essence) = self.static_essence {
Debug::fmt(essence, f)
} else {
Debug::fmt(&self.essence, f)
}
Debug::fmt(&self.essence, f)
}
}
@ -196,6 +163,13 @@ impl ToHeaderValues for Mime {
Ok(header.to_header_values().unwrap())
}
}
impl PartialEq<Mime> for Mime {
fn eq(&self, other: &Mime) -> bool {
self.essence == other.essence
}
}
/// A parameter name.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ParamName(Cow<'static, str>);

View File

@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::fmt;
use super::{Mime, ParamKind, ParamName, ParamValue};
@ -107,13 +108,10 @@ pub(crate) fn parse(input: &str) -> crate::Result<Mime> {
}
Ok(Mime {
essence: format!("{}/{}", &basetype, &subtype),
basetype,
subtype,
essence: Cow::Owned(format!("{}/{}", &basetype, &subtype)),
basetype: basetype.into(),
subtype: subtype.into(),
params: params.map(ParamKind::Vec),
static_essence: None,
static_basetype: None,
static_subtype: None,
})
}
@ -205,11 +203,7 @@ fn collect_http_quoted_string(mut input: &str) -> (String, &str) {
/// Implementation of [WHATWG MIME serialization algorithm](https://mimesniff.spec.whatwg.org/#serializing-a-mime-type)
pub(crate) fn format(mime_type: &Mime, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(essence) = mime_type.static_essence {
write!(f, "{}", essence)?
} else {
write!(f, "{}", &mime_type.essence)?
}
write!(f, "{}", &mime_type.essence)?;
if let Some(params) = &mime_type.params {
match params {
ParamKind::Utf8 => write!(f, ";charset=utf-8")?,