refactor(lib): use type macro to detect impl Trait

This commit is contained in:
Sean McArthur
2018-08-07 19:39:36 -07:00
parent 9f8add6056
commit 6e8417e08f
7 changed files with 36 additions and 77 deletions

View File

@@ -2,13 +2,12 @@ extern crate rustc_version;
use rustc_version::{version, Version}; use rustc_version::{version, Version};
fn main() { fn main() {
// Check for a minimum version to see if new rust features can be used // Check for a minimum version to see if new rust features can be used
let version = version().unwrap(); let version = version().unwrap();
if version >= Version::parse("1.26.0").unwrap() { if version >= Version::parse("1.26.0").unwrap() {
println!("cargo:rustc-cfg=impl_trait_available"); println!("cargo:rustc-cfg=__hyper_impl_trait_available");
} }
if version >= Version::parse("1.23.0").unwrap() { if version >= Version::parse("1.23.0").unwrap() {
println!("cargo:rustc-cfg=inherent_ascii"); println!("cargo:rustc-cfg=__hyper_inherent_ascii");
} }
} }

View File

@@ -238,12 +238,11 @@ where
} }
} }
#[cfg(impl_trait_available)] pub(crate) fn send_request_retryable(&mut self, req: Request<B>) -> impl_trait!(ty: Future<Item = Response<Body>, Error = (::Error, Option<Request<B>>)> + Send)
pub(crate) fn send_request_retryable(&mut self, req: Request<B>) -> impl Future<Item = Response<Body>, Error = (::Error, Option<Request<B>>)> + Send
where where
B: Send, B: Send,
{ {
match self.dispatch.try_send(req) { impl_trait!(e: match self.dispatch.try_send(req) {
Ok(rx) => { Ok(rx) => {
Either::A(rx.then(move |res| { Either::A(rx.then(move |res| {
match res { match res {
@@ -259,32 +258,7 @@ where
let err = ::Error::new_canceled(Some("connection was not ready")); let err = ::Error::new_canceled(Some("connection was not ready"));
Either::B(future::err((err, Some(req)))) Either::B(future::err((err, Some(req))))
} }
} })
}
#[cfg(not(impl_trait_available))]
pub(super) fn send_request_retryable(&mut self, req: Request<B>) -> Box<Future<Item=Response<Body>, Error=(::Error, Option<Request<B>>)> + Send>
where
B: Send,
{
let inner = match self.dispatch.try_send(req) {
Ok(rx) => {
Either::A(rx.then(move |res| {
match res {
Ok(Ok(res)) => Ok(res),
Ok(Err(err)) => Err(err),
// this is definite bug if it happens, but it shouldn't happen!
Err(_) => panic!("dispatch dropped without returning error"),
}
}))
},
Err(req) => {
debug!("connection was not ready");
let err = ::Error::new_canceled(Some("connection was not ready"));
Either::B(future::err((err, Some(req))))
}
};
Box::new(inner)
} }
} }
@@ -324,12 +298,11 @@ impl<B> Http2SendRequest<B>
where where
B: Payload + 'static, B: Payload + 'static,
{ {
#[cfg(impl_trait_available)] pub(super) fn send_request_retryable(&mut self, req: Request<B>) -> impl_trait!(ty: Future<Item=Response<Body>, Error=(::Error, Option<Request<B>>)> + Send)
pub(super) fn send_request_retryable(&mut self, req: Request<B>) -> impl Future<Item=Response<Body>, Error=(::Error, Option<Request<B>>)> + Send
where where
B: Send, B: Send,
{ {
match self.dispatch.try_send(req) { impl_trait!(e: match self.dispatch.try_send(req) {
Ok(rx) => { Ok(rx) => {
Either::A(rx.then(move |res| { Either::A(rx.then(move |res| {
match res { match res {
@@ -345,32 +318,7 @@ where
let err = ::Error::new_canceled(Some("connection was not ready")); let err = ::Error::new_canceled(Some("connection was not ready"));
Either::B(future::err((err, Some(req)))) Either::B(future::err((err, Some(req))))
} }
} })
}
#[cfg(not(impl_trait_available))]
pub(crate) fn send_request_retryable(&mut self, req: Request<B>) -> Box<Future<Item=Response<Body>, Error=(::Error, Option<Request<B>>)> + Send>
where
B: Send,
{
let inner = match self.dispatch.try_send(req) {
Ok(rx) => {
Either::A(rx.then(move |res| {
match res {
Ok(Ok(res)) => Ok(res),
Ok(Err(err)) => Err(err),
// this is definite bug if it happens, but it shouldn't happen!
Err(_) => panic!("dispatch dropped without returning error"),
}
}))
},
Err(req) => {
debug!("connection was not ready");
let err = ::Error::new_canceled(Some("connection was not ready"));
Either::B(future::err((err, Some(req))))
}
};
Box::new(inner)
} }
} }

View File

@@ -623,26 +623,14 @@ impl<B> PoolClient<B> {
} }
impl<B: Payload + 'static> PoolClient<B> { impl<B: Payload + 'static> PoolClient<B> {
#[cfg(impl_trait_available)] fn send_request_retryable(&mut self, req: Request<B>) -> impl_trait!(ty: Future<Item = Response<Body>, Error = (::Error, Option<Request<B>>)> + Send)
fn send_request_retryable(&mut self, req: Request<B>) -> impl Future<Item = Response<Body>, Error = (::Error, Option<Request<B>>)> + Send
where where
B: Send, B: Send,
{ {
match self.tx { impl_trait!(e: match self.tx {
PoolTx::Http1(ref mut tx) => Either::A(tx.send_request_retryable(req)), PoolTx::Http1(ref mut tx) => Either::A(tx.send_request_retryable(req)),
PoolTx::Http2(ref mut tx) => Either::B(tx.send_request_retryable(req)), PoolTx::Http2(ref mut tx) => Either::B(tx.send_request_retryable(req)),
} })
}
#[cfg(not(impl_trait_available))]
fn send_request_retryable(&mut self, req: Request<B>) -> Box<Future<Item=Response<Body>, Error=(::Error, Option<Request<B>>)> + Send>
where
B: Send,
{
match self.tx {
PoolTx::Http1(ref mut tx) => tx.send_request_retryable(req),
PoolTx::Http2(ref mut tx) => tx.send_request_retryable(req),
}
} }
} }

21
src/common/macros.rs Normal file
View File

@@ -0,0 +1,21 @@
#[macro_export]
#[cfg(__hyper_impl_trait_available)]
macro_rules! impl_trait {
(ty: $($t:tt)+) => {
impl $($t)+
};
(e: $e:expr) => {
$e
}
}
#[macro_export]
#[cfg(not(__hyper_impl_trait_available))]
macro_rules! impl_trait {
(ty: $($t:tt)+) => {
Box<$($t)+>
};
(e: $e:expr) => {
Box::new($e)
}
}

View File

@@ -2,6 +2,8 @@ mod buf;
mod exec; mod exec;
pub(crate) mod io; pub(crate) mod io;
mod lazy; mod lazy;
#[macro_use]
mod macros;
mod never; mod never;
pub(crate) use self::buf::StaticBuf; pub(crate) use self::buf::StaticBuf;

View File

@@ -2,7 +2,7 @@ use bytes::BytesMut;
use http::HeaderMap; use http::HeaderMap;
use http::header::{CONTENT_LENGTH, TRANSFER_ENCODING}; use http::header::{CONTENT_LENGTH, TRANSFER_ENCODING};
use http::header::{HeaderValue, OccupiedEntry, ValueIter}; use http::header::{HeaderValue, OccupiedEntry, ValueIter};
#[cfg(not(inherent_ascii))] #[cfg(not(__hyper_inherent_ascii))]
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
pub fn connection_keep_alive(value: &HeaderValue) -> bool { pub fn connection_keep_alive(value: &HeaderValue) -> bool {

View File

@@ -52,6 +52,7 @@ pub use error::{Result, Error};
pub use body::{Body, Chunk}; pub use body::{Body, Chunk};
pub use server::Server; pub use server::Server;
#[macro_use]
mod common; mod common;
#[cfg(test)] #[cfg(test)]
mod mock; mod mock;