Skip to content

Commit c284eae

Browse files
committed
Fix rwf2#1067 by importing typed headers from hyperx
1 parent c24f15c commit c284eae

File tree

3 files changed

+120
-13
lines changed

3 files changed

+120
-13
lines changed

core/codegen/tests/ui-fail-stable/responder-types.stderr

+21-12
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@ error[E0277]: the trait bound `u8: Responder<'_, '_>` is not satisfied
66
|
77
= note: required by `respond_to`
88

9-
error[E0277]: the trait bound `Header<'_>: From<u8>` is not satisfied
9+
error[E0277]: the trait bound `Header<'_>: std::convert::From<u8>` is not satisfied
1010
--> $DIR/responder-types.rs:11:5
1111
|
1212
11 | other: u8,
13-
| ^^^^^ the trait `From<u8>` is not implemented for `Header<'_>`
13+
| ^^^^^ the trait `std::convert::From<u8>` is not implemented for `Header<'_>`
1414
|
1515
= help: the following implementations were found:
16-
<Header<'static> as From<&Cookie<'_>>>
17-
<Header<'static> as From<Cookie<'_>>>
16+
<Header<'static> as std::convert::From<&rocket::http::Cookie<'_>>>
17+
<Header<'static> as std::convert::From<AcceptCharset>>
18+
<Header<'static> as std::convert::From<AcceptEncoding>>
19+
<Header<'static> as std::convert::From<AcceptLanguage>>
20+
and 55 others
1821
= note: required because of the requirements on the impl of `Into<Header<'_>>` for `u8`
1922

2023
error[E0277]: the trait bound `u8: Responder<'_, '_>` is not satisfied
@@ -25,26 +28,32 @@ error[E0277]: the trait bound `u8: Responder<'_, '_>` is not satisfied
2528
|
2629
= note: required by `respond_to`
2730

28-
error[E0277]: the trait bound `Header<'_>: From<u8>` is not satisfied
31+
error[E0277]: the trait bound `Header<'_>: std::convert::From<u8>` is not satisfied
2932
--> $DIR/responder-types.rs:17:5
3033
|
3134
17 | other: u8,
32-
| ^^^^^ the trait `From<u8>` is not implemented for `Header<'_>`
35+
| ^^^^^ the trait `std::convert::From<u8>` is not implemented for `Header<'_>`
3336
|
3437
= help: the following implementations were found:
35-
<Header<'static> as From<&Cookie<'_>>>
36-
<Header<'static> as From<Cookie<'_>>>
38+
<Header<'static> as std::convert::From<&rocket::http::Cookie<'_>>>
39+
<Header<'static> as std::convert::From<AcceptCharset>>
40+
<Header<'static> as std::convert::From<AcceptEncoding>>
41+
<Header<'static> as std::convert::From<AcceptLanguage>>
42+
and 55 others
3743
= note: required because of the requirements on the impl of `Into<Header<'_>>` for `u8`
3844

39-
error[E0277]: the trait bound `Header<'_>: From<std::string::String>` is not satisfied
45+
error[E0277]: the trait bound `Header<'_>: std::convert::From<std::string::String>` is not satisfied
4046
--> $DIR/responder-types.rs:24:5
4147
|
4248
24 | then: String,
43-
| ^^^^ the trait `From<std::string::String>` is not implemented for `Header<'_>`
49+
| ^^^^ the trait `std::convert::From<std::string::String>` is not implemented for `Header<'_>`
4450
|
4551
= help: the following implementations were found:
46-
<Header<'static> as From<&Cookie<'_>>>
47-
<Header<'static> as From<Cookie<'_>>>
52+
<Header<'static> as std::convert::From<&rocket::http::Cookie<'_>>>
53+
<Header<'static> as std::convert::From<AcceptCharset>>
54+
<Header<'static> as std::convert::From<AcceptEncoding>>
55+
<Header<'static> as std::convert::From<AcceptLanguage>>
56+
and 55 others
4857
= note: required because of the requirements on the impl of `Into<Header<'_>>` for `std::string::String`
4958

5059
error[E0277]: the trait bound `usize: Responder<'_, '_>` is not satisfied

core/http/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ private-cookies = ["cookie/private", "cookie/key-expansion"]
2323
smallvec = "1.0"
2424
percent-encoding = "2"
2525
hyper = { version = "0.14", default-features = false, features = ["http1", "http2", "runtime", "server", "stream"] }
26+
hyperx = { version = "1.3.0" }
2627
http = "0.2"
2728
mime = "0.3.13"
2829
time = "0.2.11"

core/http/src/hyper.rs

+98-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! Re-exported hyper HTTP library types.
1+
//! Re-exported hyper HTTP library types and hyperx typed headers.
22
//!
33
//! All types that are re-exported from Hyper reside inside of this module.
44
//! These types will, with certainty, be removed with time, but they reside here
@@ -21,6 +21,9 @@
2121

2222
/// Reexported http header types.
2323
pub mod header {
24+
use super::super::header::Header;
25+
pub use hyperx::header::Header as HyperxHeaderTrait;
26+
2427
macro_rules! import_http_headers {
2528
($($name:ident),*) => ($(
2629
pub use http::header::$name as $name;
@@ -43,4 +46,98 @@ pub mod header {
4346
STRICT_TRANSPORT_SECURITY, TE, TRANSFER_ENCODING, UPGRADE, USER_AGENT,
4447
VARY
4548
}
49+
50+
macro_rules! import_hyperx_items {
51+
($($item:ident),*) => ($(pub use hyperx::header::$item as $item;)*)
52+
}
53+
54+
macro_rules! import_hyperx_headers {
55+
($($name:ident),*) => ($(
56+
impl ::std::convert::From<self::$name> for Header<'static> {
57+
fn from(header: self::$name) -> Header<'static> {
58+
Header::new($name::header_name(), header.to_string())
59+
}
60+
}
61+
)*)
62+
}
63+
64+
macro_rules! import_generic_hyperx_headers {
65+
($($name:ident<$bound:ident>),*) => ($(
66+
impl <T1: 'static + $bound> ::std::convert::From<self::$name<T1>>
67+
for Header<'static> {
68+
fn from(header: self::$name<T1>) -> Header<'static> {
69+
Header::new($name::<T1>::header_name(), header.to_string())
70+
}
71+
}
72+
)*)
73+
}
74+
75+
import_hyperx_items! {
76+
Accept, AcceptCharset, AcceptEncoding, AcceptLanguage, AcceptRanges,
77+
AccessControlAllowCredentials, AccessControlAllowHeaders,
78+
AccessControlAllowMethods, AccessControlAllowOrigin,
79+
AccessControlExposeHeaders, AccessControlMaxAge,
80+
AccessControlRequestHeaders, AccessControlRequestMethod, Allow,
81+
Authorization, Basic, Bearer, ByteRangeSpec, CacheControl,
82+
CacheDirective, Charset, Connection, ConnectionOption,
83+
ContentDisposition, ContentEncoding, ContentLanguage, ContentLength,
84+
ContentLocation, ContentRange, ContentRangeSpec, ContentType, Cookie,
85+
Date, DispositionParam, DispositionType, Encoding, EntityTag, ETag,
86+
Expect, Expires, From, Host, HttpDate, IfMatch, IfModifiedSince,
87+
IfNoneMatch, IfRange, IfUnmodifiedSince, LastEventId, LastModified,
88+
Link, LinkValue, Location, Origin, Pragma, Prefer, Preference,
89+
PreferenceApplied, Protocol, ProtocolName, ProxyAuthorization, Quality,
90+
QualityItem, Range, RangeUnit, Referer, ReferrerPolicy, RetryAfter,
91+
Scheme, Server, SetCookie, StrictTransportSecurity,
92+
Te, TransferEncoding, Upgrade, UserAgent, Vary, Warning, q, qitem
93+
}
94+
95+
import_hyperx_headers! {
96+
Accept, AcceptCharset, AcceptEncoding, AcceptLanguage, AcceptRanges,
97+
AccessControlAllowCredentials, AccessControlAllowHeaders,
98+
AccessControlAllowMethods, AccessControlAllowOrigin,
99+
AccessControlExposeHeaders, AccessControlMaxAge,
100+
AccessControlRequestHeaders, AccessControlRequestMethod, Allow,
101+
CacheControl, Connection, ContentDisposition, ContentEncoding,
102+
ContentLanguage, ContentLength, ContentLocation, ContentRange,
103+
ContentType, Cookie, Date, ETag, Expires, Expect, From, Host, IfMatch,
104+
IfModifiedSince, IfNoneMatch, IfUnmodifiedSince, IfRange, LastEventId,
105+
LastModified, Link, Location, Origin, Pragma, Prefer, PreferenceApplied,
106+
Range, Referer, ReferrerPolicy, RetryAfter, Server,
107+
StrictTransportSecurity, Te, TransferEncoding, Upgrade, UserAgent, Vary,
108+
Warning
109+
}
110+
import_generic_hyperx_headers! {
111+
Authorization<Scheme>,
112+
ProxyAuthorization<Scheme>
113+
}
114+
// Note: SetCookie is missing, since it must be formatted as separate header lines...
115+
}
116+
117+
#[cfg(test)]
118+
mod tests {
119+
use crate::header::HeaderMap;
120+
use super::header::HyperxHeaderTrait; // Needed for Accept::header_name() below?!?!
121+
122+
#[test]
123+
fn add_typed_header() {
124+
use super::header::{Accept, QualityItem, q, qitem};
125+
let mut map = HeaderMap::new();
126+
map.add(Accept(vec![
127+
QualityItem::new("audio/*".parse().unwrap(), q(200)),
128+
qitem("audio/basic".parse().unwrap()),
129+
]));
130+
assert_eq!(map.get_one(Accept::header_name()), Some("audio/*; q=0.2, audio/basic"));
131+
}
132+
133+
#[test]
134+
fn add_typed_header_with_type_params() {
135+
use super::header::{Authorization, Basic};
136+
let mut map = HeaderMap::new();
137+
map.add(Authorization(Basic {
138+
username: "admin".to_owned(),
139+
password: Some("12345678".to_owned())}));
140+
assert_eq!(map.get_one("Authorization"), Some("Basic YWRtaW46MTIzNDU2Nzg="));
141+
}
142+
46143
}

0 commit comments

Comments
 (0)