Skip to content

Commit 65cd9b7

Browse files
Merge branch 'main' into move-trailers
2 parents cbc6faf + 8d44aec commit 65cd9b7

File tree

16 files changed

+543
-267
lines changed

16 files changed

+543
-267
lines changed

.travis.yml

Lines changed: 0 additions & 13 deletions
This file was deleted.

Cargo.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "http-types"
3-
version = "2.9.0"
3+
version = "3.0.0"
44
license = "MIT OR Apache-2.0"
55
repository = "https://github.com/http-rs/http-types"
66
documentation = "https://docs.rs/http-types"
@@ -21,7 +21,8 @@ docs = ["unstable"]
2121
unstable = []
2222
hyperium_http = ["http"]
2323
async_std = ["fs"]
24-
cookie-secure = ["cookie/secure"]
24+
cookies = ["cookie"]
25+
cookie-secure = ["cookies", "cookie/secure"]
2526
fs = ["async-std"]
2627

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

3637
anyhow = "1.0.26"
37-
cookie = { version = "0.14.0", features = ["percent-encode"] }
38+
39+
# features: cookies
40+
cookie = { version = "0.14.0", features = ["percent-encode"], optional = true }
3841
infer = "0.2.3"
3942
pin-project-lite = "0.2.0"
4043
url = { version = "2.1.1", features = ["serde"] }

src/conditional/etag.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl ETag {
117117

118118
if !s
119119
.bytes()
120-
.all(|c| c == 0x21 || (c >= 0x23 && c <= 0x7E) || c >= 0x80)
120+
.all(|c| c == 0x21 || (0x23..=0x7E).contains(&c) || c >= 0x80)
121121
{
122122
return Err(Error::from_str(
123123
StatusCode::BadRequest,

src/headers/header_name.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ mod tests {
135135
use super::*;
136136

137137
#[test]
138+
#[allow(clippy::eq_op)]
138139
fn test_header_name_static_non_static() {
139140
let static_header = HeaderName::from_lowercase_str("hello");
140141
let non_static_header = HeaderName::from_str("hello").unwrap();

src/headers/header_value.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ use std::fmt::{self, Debug, Display};
33
use std::str::FromStr;
44

55
use crate::headers::HeaderValues;
6+
#[cfg(feature = "cookies")]
7+
use crate::Cookie;
68
use crate::Error;
7-
use crate::{Cookie, Mime};
9+
use crate::Mime;
810

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

59+
#[cfg(feature = "cookies")]
5760
impl From<Cookie<'_>> for HeaderValue {
5861
fn from(cookie: Cookie<'_>) -> Self {
5962
HeaderValue {

src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
//! ```
99
//! # fn main() -> Result<(), http_types::url::ParseError> {
1010
//! #
11-
//! use http_types::{Url, Method, Request, Response, StatusCode};
11+
//! use http_types::{Method, Request, Response, StatusCode};
1212
//!
13-
//! let mut req = Request::new(Method::Get, Url::parse("https://example.com")?);
13+
//! let mut req = Request::new(Method::Get, "https://example.com");
1414
//! req.set_body("Hello, Nori!");
1515
//!
1616
//! let mut res = Response::new(StatusCode::Ok);
@@ -102,6 +102,7 @@
102102
#![doc(html_logo_url = "https://yoshuawuyts.com/assets/http-rs/logo-rounded.png")]
103103

104104
/// HTTP cookies.
105+
#[cfg(feature = "cookies")]
105106
pub mod cookies {
106107
pub use cookie::*;
107108
}
@@ -163,6 +164,7 @@ pub use headers::Headers;
163164
#[doc(inline)]
164165
pub use crate::url::Url;
165166

167+
#[cfg(feature = "cookies")]
166168
#[doc(inline)]
167169
pub use crate::cookies::Cookie;
168170

src/mime/constants.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use super::ParamKind;
21
use crate::Mime;
2+
use std::borrow::Cow;
33

44
macro_rules! utf8_mime_const {
55
($name:ident, $desc:expr, $base:expr, $sub:expr) => {
@@ -9,18 +9,18 @@ macro_rules! utf8_mime_const {
99
$desc,
1010
$base,
1111
$sub,
12-
Some(ParamKind::Utf8),
12+
true,
1313
";charset=utf-8"
1414
);
1515
};
1616
}
1717
macro_rules! mime_const {
1818
($name:ident, $desc:expr, $base:expr, $sub:expr) => {
19-
mime_const!(with_params, $name, $desc, $base, $sub, None, "");
19+
mime_const!(with_params, $name, $desc, $base, $sub, false, "");
2020
};
2121

22-
(with_params, $name:ident, $desc:expr, $base:expr, $sub:expr, $params:expr, $doccomment:expr) => {
23-
mime_const!(doc_expanded, $name, $desc, $base, $sub, $params,
22+
(with_params, $name:ident, $desc:expr, $base:expr, $sub:expr, $is_utf8:expr, $doccomment:expr) => {
23+
mime_const!(doc_expanded, $name, $desc, $base, $sub, $is_utf8,
2424
concat!(
2525
"Content-Type for ",
2626
$desc,
@@ -29,16 +29,14 @@ macro_rules! mime_const {
2929
);
3030
};
3131

32-
(doc_expanded, $name:ident, $desc:expr, $base:expr, $sub:expr, $params:expr, $doccomment:expr) => {
32+
(doc_expanded, $name:ident, $desc:expr, $base:expr, $sub:expr, $is_utf8:expr, $doccomment:expr) => {
3333
#[doc = $doccomment]
3434
pub const $name: Mime = Mime {
35-
essence: String::new(),
36-
basetype: String::new(),
37-
subtype: String::new(),
38-
params: $params,
39-
static_essence: Some(concat!($base, "/", $sub)),
40-
static_basetype: Some($base),
41-
static_subtype: Some($sub),
35+
essence: Cow::Borrowed(concat!($base, "/", $sub)),
36+
basetype: Cow::Borrowed($base),
37+
subtype: Cow::Borrowed($sub),
38+
is_utf8: $is_utf8,
39+
params: vec![],
4240
};
4341
};
4442
}

src/mime/mod.rs

Lines changed: 29 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ use infer::Infer;
2828
/// ```
2929
// NOTE: we cannot statically initialize Strings with values yet, so we keep dedicated static
3030
// fields for the static strings.
31-
#[derive(Clone)]
31+
#[derive(Clone, PartialEq, Eq, Debug)]
3232
pub struct Mime {
33-
pub(crate) essence: String,
34-
pub(crate) basetype: String,
35-
pub(crate) subtype: String,
36-
pub(crate) static_essence: Option<&'static str>,
37-
pub(crate) static_basetype: Option<&'static str>,
38-
pub(crate) static_subtype: Option<&'static str>,
39-
pub(crate) params: Option<ParamKind>,
33+
pub(crate) essence: Cow<'static, str>,
34+
pub(crate) basetype: Cow<'static, str>,
35+
pub(crate) subtype: Cow<'static, str>,
36+
// NOTE(yosh): this is a hack because we can't populate vecs in const yet.
37+
// This enables us to encode media types as utf-8 at compilation.
38+
pub(crate) is_utf8: bool,
39+
pub(crate) params: Vec<(ParamName, ParamValue)>,
4040
}
4141

4242
impl Mime {
@@ -68,87 +68,40 @@ impl Mime {
6868
/// According to the spec this method should be named `type`, but that's a reserved keyword in
6969
/// Rust so hence prefix with `base` instead.
7070
pub fn basetype(&self) -> &str {
71-
if let Some(basetype) = self.static_basetype {
72-
&basetype
73-
} else {
74-
&self.basetype
75-
}
71+
&self.basetype
7672
}
7773

7874
/// Access the Mime's `subtype` value.
7975
pub fn subtype(&self) -> &str {
80-
if let Some(subtype) = self.static_subtype {
81-
&subtype
82-
} else {
83-
&self.subtype
84-
}
76+
&self.subtype
8577
}
8678

8779
/// Access the Mime's `essence` value.
8880
pub fn essence(&self) -> &str {
89-
if let Some(essence) = self.static_essence {
90-
&essence
91-
} else {
92-
&self.essence
93-
}
81+
&self.essence
9482
}
9583

9684
/// Get a reference to a param.
9785
pub fn param(&self, name: impl Into<ParamName>) -> Option<&ParamValue> {
9886
let name: ParamName = name.into();
99-
self.params
100-
.as_ref()
101-
.map(|inner| match inner {
102-
ParamKind::Vec(v) => v
103-
.iter()
104-
.find_map(|(k, v)| if k == &name { Some(v) } else { None }),
105-
ParamKind::Utf8 => match name {
106-
ParamName(Cow::Borrowed("charset")) => Some(&ParamValue(Cow::Borrowed("utf8"))),
107-
_ => None,
108-
},
109-
})
110-
.flatten()
87+
if name.as_str() == "charset" && self.is_utf8 {
88+
return Some(&ParamValue(Cow::Borrowed("utf-8")));
89+
}
90+
91+
self.params.iter().find(|(k, _)| k == &name).map(|(_, v)| v)
11192
}
11293

11394
/// Remove a param from the set. Returns the `ParamValue` if it was contained within the set.
11495
pub fn remove_param(&mut self, name: impl Into<ParamName>) -> Option<ParamValue> {
11596
let name: ParamName = name.into();
116-
let mut unset_params = false;
117-
let ret = self
118-
.params
119-
.as_mut()
120-
.map(|inner| match inner {
121-
ParamKind::Vec(v) => match v.iter().position(|(k, _)| k == &name) {
122-
Some(index) => Some(v.remove(index).1),
123-
None => None,
124-
},
125-
ParamKind::Utf8 => match name {
126-
ParamName(Cow::Borrowed("charset")) => {
127-
unset_params = true;
128-
Some(ParamValue(Cow::Borrowed("utf8")))
129-
}
130-
_ => None,
131-
},
132-
})
133-
.flatten();
134-
if unset_params {
135-
self.params = None;
97+
if name.as_str() == "charset" && self.is_utf8 {
98+
self.is_utf8 = false;
99+
return Some(ParamValue(Cow::Borrowed("utf-8")));
136100
}
137-
ret
138-
}
139-
}
140-
141-
impl PartialEq<Mime> for Mime {
142-
fn eq(&self, other: &Mime) -> bool {
143-
let left = match self.static_essence {
144-
Some(essence) => essence,
145-
None => &self.essence,
146-
};
147-
let right = match other.static_essence {
148-
Some(essence) => essence,
149-
None => &other.essence,
150-
};
151-
left == right
101+
self.params
102+
.iter()
103+
.position(|(k, _)| k == &name)
104+
.map(|pos| self.params.remove(pos).1)
152105
}
153106
}
154107

@@ -158,15 +111,11 @@ impl Display for Mime {
158111
}
159112
}
160113

161-
impl Debug for Mime {
162-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163-
if let Some(essence) = self.static_essence {
164-
Debug::fmt(essence, f)
165-
} else {
166-
Debug::fmt(&self.essence, f)
167-
}
168-
}
169-
}
114+
// impl Debug for Mime {
115+
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116+
// Debug::fmt(&self.essence, f)
117+
// }
118+
// }
170119

171120
impl FromStr for Mime {
172121
type Err = crate::Error;
@@ -196,6 +145,7 @@ impl ToHeaderValues for Mime {
196145
Ok(header.to_header_values().unwrap())
197146
}
198147
}
148+
199149
/// A parameter name.
200150
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
201151
pub struct ParamName(Cow<'static, str>);
@@ -259,11 +209,3 @@ impl PartialEq<str> for ParamValue {
259209
self.0 == other
260210
}
261211
}
262-
263-
/// This is a hack that allows us to mark a trait as utf8 during compilation. We
264-
/// can remove this once we can construct HashMap during compilation.
265-
#[derive(Debug, Clone, PartialEq, Eq)]
266-
pub(crate) enum ParamKind {
267-
Utf8,
268-
Vec(Vec<(ParamName, ParamValue)>),
269-
}

0 commit comments

Comments
 (0)