Skip to content

Commit

Permalink
Merge branch 'main' into move-trailers
Browse files Browse the repository at this point in the history
  • Loading branch information
brightly-salty committed Jan 24, 2021
2 parents cbc6faf + 8d44aec commit 65cd9b7
Show file tree
Hide file tree
Showing 16 changed files with 543 additions and 267 deletions.
13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "http-types"
version = "2.9.0"
version = "3.0.0"
license = "MIT OR Apache-2.0"
repository = "https://github.com/http-rs/http-types"
documentation = "https://docs.rs/http-types"
Expand All @@ -21,7 +21,8 @@ docs = ["unstable"]
unstable = []
hyperium_http = ["http"]
async_std = ["fs"]
cookie-secure = ["cookie/secure"]
cookies = ["cookie"]
cookie-secure = ["cookies", "cookie/secure"]
fs = ["async-std"]

[dependencies]
Expand All @@ -34,7 +35,9 @@ async-channel = "1.5.1"
http = { version = "0.2.0", optional = true }

anyhow = "1.0.26"
cookie = { version = "0.14.0", features = ["percent-encode"] }

# features: cookies
cookie = { version = "0.14.0", features = ["percent-encode"], optional = true }
infer = "0.2.3"
pin-project-lite = "0.2.0"
url = { version = "2.1.1", features = ["serde"] }
Expand Down
2 changes: 1 addition & 1 deletion src/conditional/etag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ impl ETag {

if !s
.bytes()
.all(|c| c == 0x21 || (c >= 0x23 && c <= 0x7E) || c >= 0x80)
.all(|c| c == 0x21 || (0x23..=0x7E).contains(&c) || c >= 0x80)
{
return Err(Error::from_str(
StatusCode::BadRequest,
Expand Down
1 change: 1 addition & 0 deletions src/headers/header_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ mod tests {
use super::*;

#[test]
#[allow(clippy::eq_op)]
fn test_header_name_static_non_static() {
let static_header = HeaderName::from_lowercase_str("hello");
let non_static_header = HeaderName::from_str("hello").unwrap();
Expand Down
5 changes: 4 additions & 1 deletion src/headers/header_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ use std::fmt::{self, Debug, Display};
use std::str::FromStr;

use crate::headers::HeaderValues;
#[cfg(feature = "cookies")]
use crate::Cookie;
use crate::Error;
use crate::{Cookie, Mime};
use crate::Mime;

/// A header value.
#[derive(Clone, Eq, PartialEq, Hash)]
Expand Down Expand Up @@ -54,6 +56,7 @@ impl From<Mime> for HeaderValue {
}
}

#[cfg(feature = "cookies")]
impl From<Cookie<'_>> for HeaderValue {
fn from(cookie: Cookie<'_>) -> Self {
HeaderValue {
Expand Down
6 changes: 4 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
//! ```
//! # fn main() -> Result<(), http_types::url::ParseError> {
//! #
//! use http_types::{Url, Method, Request, Response, StatusCode};
//! use http_types::{Method, Request, Response, StatusCode};
//!
//! let mut req = Request::new(Method::Get, Url::parse("https://example.com")?);
//! let mut req = Request::new(Method::Get, "https://example.com");
//! req.set_body("Hello, Nori!");
//!
//! let mut res = Response::new(StatusCode::Ok);
Expand Down Expand Up @@ -102,6 +102,7 @@
#![doc(html_logo_url = "https://yoshuawuyts.com/assets/http-rs/logo-rounded.png")]

/// HTTP cookies.
#[cfg(feature = "cookies")]
pub mod cookies {
pub use cookie::*;
}
Expand Down Expand Up @@ -163,6 +164,7 @@ pub use headers::Headers;
#[doc(inline)]
pub use crate::url::Url;

#[cfg(feature = "cookies")]
#[doc(inline)]
pub use crate::cookies::Cookie;

Expand Down
24 changes: 11 additions & 13 deletions src/mime/constants.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::ParamKind;
use crate::Mime;
use std::borrow::Cow;

macro_rules! utf8_mime_const {
($name:ident, $desc:expr, $base:expr, $sub:expr) => {
Expand All @@ -9,18 +9,18 @@ macro_rules! utf8_mime_const {
$desc,
$base,
$sub,
Some(ParamKind::Utf8),
true,
";charset=utf-8"
);
};
}
macro_rules! mime_const {
($name:ident, $desc:expr, $base:expr, $sub:expr) => {
mime_const!(with_params, $name, $desc, $base, $sub, None, "");
mime_const!(with_params, $name, $desc, $base, $sub, false, "");
};

(with_params, $name:ident, $desc:expr, $base:expr, $sub:expr, $params:expr, $doccomment:expr) => {
mime_const!(doc_expanded, $name, $desc, $base, $sub, $params,
(with_params, $name:ident, $desc:expr, $base:expr, $sub:expr, $is_utf8:expr, $doccomment:expr) => {
mime_const!(doc_expanded, $name, $desc, $base, $sub, $is_utf8,
concat!(
"Content-Type for ",
$desc,
Expand All @@ -29,16 +29,14 @@ macro_rules! mime_const {
);
};

(doc_expanded, $name:ident, $desc:expr, $base:expr, $sub:expr, $params:expr, $doccomment:expr) => {
(doc_expanded, $name:ident, $desc:expr, $base:expr, $sub:expr, $is_utf8:expr, $doccomment:expr) => {
#[doc = $doccomment]
pub const $name: Mime = Mime {
essence: String::new(),
basetype: String::new(),
subtype: String::new(),
params: $params,
static_essence: Some(concat!($base, "/", $sub)),
static_basetype: Some($base),
static_subtype: Some($sub),
essence: Cow::Borrowed(concat!($base, "/", $sub)),
basetype: Cow::Borrowed($base),
subtype: Cow::Borrowed($sub),
is_utf8: $is_utf8,
params: vec![],
};
};
}
Expand Down
116 changes: 29 additions & 87 deletions src/mime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ 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, PartialEq, Eq, Debug)]
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) params: Option<ParamKind>,
pub(crate) essence: Cow<'static, str>,
pub(crate) basetype: Cow<'static, str>,
pub(crate) subtype: Cow<'static, str>,
// NOTE(yosh): this is a hack because we can't populate vecs in const yet.
// This enables us to encode media types as utf-8 at compilation.
pub(crate) is_utf8: bool,
pub(crate) params: Vec<(ParamName, ParamValue)>,
}

impl Mime {
Expand Down Expand Up @@ -68,87 +68,40 @@ 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.
pub fn param(&self, name: impl Into<ParamName>) -> Option<&ParamValue> {
let name: ParamName = name.into();
self.params
.as_ref()
.map(|inner| match inner {
ParamKind::Vec(v) => v
.iter()
.find_map(|(k, v)| if k == &name { Some(v) } else { None }),
ParamKind::Utf8 => match name {
ParamName(Cow::Borrowed("charset")) => Some(&ParamValue(Cow::Borrowed("utf8"))),
_ => None,
},
})
.flatten()
if name.as_str() == "charset" && self.is_utf8 {
return Some(&ParamValue(Cow::Borrowed("utf-8")));
}

self.params.iter().find(|(k, _)| k == &name).map(|(_, v)| v)
}

/// Remove a param from the set. Returns the `ParamValue` if it was contained within the set.
pub fn remove_param(&mut self, name: impl Into<ParamName>) -> Option<ParamValue> {
let name: ParamName = name.into();
let mut unset_params = false;
let ret = self
.params
.as_mut()
.map(|inner| match inner {
ParamKind::Vec(v) => match v.iter().position(|(k, _)| k == &name) {
Some(index) => Some(v.remove(index).1),
None => None,
},
ParamKind::Utf8 => match name {
ParamName(Cow::Borrowed("charset")) => {
unset_params = true;
Some(ParamValue(Cow::Borrowed("utf8")))
}
_ => None,
},
})
.flatten();
if unset_params {
self.params = None;
if name.as_str() == "charset" && self.is_utf8 {
self.is_utf8 = false;
return Some(ParamValue(Cow::Borrowed("utf-8")));
}
ret
}
}

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
self.params
.iter()
.position(|(k, _)| k == &name)
.map(|pos| self.params.remove(pos).1)
}
}

Expand All @@ -158,15 +111,11 @@ 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)
}
}
}
// impl Debug for Mime {
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Debug::fmt(&self.essence, f)
// }
// }

impl FromStr for Mime {
type Err = crate::Error;
Expand Down Expand Up @@ -196,6 +145,7 @@ impl ToHeaderValues for Mime {
Ok(header.to_header_values().unwrap())
}
}

/// A parameter name.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ParamName(Cow<'static, str>);
Expand Down Expand Up @@ -259,11 +209,3 @@ impl PartialEq<str> for ParamValue {
self.0 == other
}
}

/// This is a hack that allows us to mark a trait as utf8 during compilation. We
/// can remove this once we can construct HashMap during compilation.
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum ParamKind {
Utf8,
Vec(Vec<(ParamName, ParamValue)>),
}
Loading

0 comments on commit 65cd9b7

Please sign in to comment.