feat(lib): update to std::future::Future

BREAKING CHANGE: All usage of async traits (`Future`, `Stream`,
`AsyncRead`, `AsyncWrite`, etc) are updated to newer versions.
This commit is contained in:
Sean McArthur
2019-07-09 15:37:43 -07:00
parent da9b0319ef
commit 8f4b05ae78
37 changed files with 1526 additions and 1548 deletions

View File

@@ -1,13 +1,12 @@
use std::error::Error as StdError;
use std::fmt;
use futures::{Async, Future, IntoFuture, Poll};
use crate::body::Payload;
use crate::common::{Future, Poll, task};
use super::Service;
/// An asynchronous constructor of `Service`s.
pub trait MakeService<Ctx> {
pub trait MakeService<Target> {
/// The `Payload` body of the `http::Request`.
type ReqBody: Payload;
@@ -25,7 +24,7 @@ pub trait MakeService<Ctx> {
>;
/// The future returned from `new_service` of a `Service`.
type Future: Future<Item=Self::Service, Error=Self::MakeError>;
type Future: Future<Output=Result<Self::Service, Self::MakeError>>;
/// The error type that can be returned when creating a new `Service`.
type MakeError: Into<Box<dyn StdError + Send + Sync>>;
@@ -35,18 +34,18 @@ pub trait MakeService<Ctx> {
/// The implementation of this method is allowed to return a `Ready` even if
/// the factory is not ready to create a new service. In this case, the future
/// returned from `make_service` will resolve to an error.
fn poll_ready(&mut self) -> Poll<(), Self::MakeError> {
Ok(Async::Ready(()))
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::MakeError>> {
Poll::Ready(Ok(()))
}
/// Create a new `Service`.
fn make_service(&mut self, ctx: Ctx) -> Self::Future;
fn make_service(&mut self, target: Target) -> Self::Future;
}
// Just a sort-of "trait alias" of `MakeService`, not to be implemented
// by anyone, only used as bounds.
#[doc(hidden)]
pub trait MakeServiceRef<Ctx>: self::sealed::Sealed<Ctx> {
pub trait MakeServiceRef<Target>: self::sealed::Sealed<Target> {
type ReqBody: Payload;
type ResBody: Payload;
type Error: Into<Box<dyn StdError + Send + Sync>>;
@@ -56,7 +55,7 @@ pub trait MakeServiceRef<Ctx>: self::sealed::Sealed<Ctx> {
Error=Self::Error,
>;
type MakeError: Into<Box<dyn StdError + Send + Sync>>;
type Future: Future<Item=Self::Service, Error=Self::MakeError>;
type Future: Future<Output=Result<Self::Service, Self::MakeError>>;
// Acting like a #[non_exhaustive] for associated types of this trait.
//
@@ -69,18 +68,18 @@ pub trait MakeServiceRef<Ctx>: self::sealed::Sealed<Ctx> {
// if necessary.
type __DontNameMe: self::sealed::CantImpl;
fn poll_ready_ref(&mut self) -> Poll<(), Self::MakeError>;
fn poll_ready_ref(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::MakeError>>;
fn make_service_ref(&mut self, ctx: &Ctx) -> Self::Future;
fn make_service_ref(&mut self, target: &Target) -> Self::Future;
}
impl<T, Ctx, E, ME, S, F, IB, OB> MakeServiceRef<Ctx> for T
impl<T, Target, E, ME, S, F, IB, OB> MakeServiceRef<Target> for T
where
T: for<'a> MakeService<&'a Ctx, Error=E, MakeError=ME, Service=S, Future=F, ReqBody=IB, ResBody=OB>,
T: for<'a> MakeService<&'a Target, Error=E, MakeError=ME, Service=S, Future=F, ReqBody=IB, ResBody=OB>,
E: Into<Box<dyn StdError + Send + Sync>>,
ME: Into<Box<dyn StdError + Send + Sync>>,
S: Service<ReqBody=IB, ResBody=OB, Error=E>,
F: Future<Item=S, Error=ME>,
F: Future<Output=Result<S, ME>>,
IB: Payload,
OB: Payload,
{
@@ -93,22 +92,22 @@ where
type __DontNameMe = self::sealed::CantName;
fn poll_ready_ref(&mut self) -> Poll<(), Self::MakeError> {
self.poll_ready()
fn poll_ready_ref(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::MakeError>> {
self.poll_ready(cx)
}
fn make_service_ref(&mut self, ctx: &Ctx) -> Self::Future {
self.make_service(ctx)
fn make_service_ref(&mut self, target: &Target) -> Self::Future {
self.make_service(target)
}
}
impl<T, Ctx, E, ME, S, F, IB, OB> self::sealed::Sealed<Ctx> for T
impl<T, Target, E, ME, S, F, IB, OB> self::sealed::Sealed<Target> for T
where
T: for<'a> MakeService<&'a Ctx, Error=E, MakeError=ME, Service=S, Future=F, ReqBody=IB, ResBody=OB>,
T: for<'a> MakeService<&'a Target, Error=E, MakeError=ME, Service=S, Future=F, ReqBody=IB, ResBody=OB>,
E: Into<Box<dyn StdError + Send + Sync>>,
ME: Into<Box<dyn StdError + Send + Sync>>,
S: Service<ReqBody=IB, ResBody=OB, Error=E>,
F: Future<Item=S, Error=ME>,
F: Future<Output=Result<S, ME>>,
IB: Payload,
OB: Payload,
{}
@@ -146,10 +145,10 @@ where
/// # }
/// # #[cfg(not(feature = "runtime"))] fn main() {}
/// ```
pub fn make_service_fn<F, Ctx, Ret>(f: F) -> MakeServiceFn<F>
pub fn make_service_fn<F, Target, Ret>(f: F) -> MakeServiceFn<F>
where
F: FnMut(&Ctx) -> Ret,
Ret: IntoFuture,
F: FnMut(&Target) -> Ret,
Ret: Future,
{
MakeServiceFn {
f,
@@ -161,24 +160,24 @@ pub struct MakeServiceFn<F> {
f: F,
}
impl<'c, F, Ctx, Ret, ReqBody, ResBody> MakeService<&'c Ctx> for MakeServiceFn<F>
impl<'t, F, Target, Ret, ReqBody, ResBody, Svc, MkErr> MakeService<&'t Target> for MakeServiceFn<F>
where
F: FnMut(&Ctx) -> Ret,
Ret: IntoFuture,
Ret::Item: Service<ReqBody=ReqBody, ResBody=ResBody>,
Ret::Error: Into<Box<dyn StdError + Send + Sync>>,
F: FnMut(&Target) -> Ret,
Ret: Future<Output=Result<Svc, MkErr>>,
Svc: Service<ReqBody=ReqBody, ResBody=ResBody>,
MkErr: Into<Box<dyn StdError + Send + Sync>>,
ReqBody: Payload,
ResBody: Payload,
{
type ReqBody = ReqBody;
type ResBody = ResBody;
type Error = <Ret::Item as Service>::Error;
type Service = Ret::Item;
type Future = Ret::Future;
type MakeError = Ret::Error;
type Error = Svc::Error;
type Service = Svc;
type Future = Ret;
type MakeError = MkErr;
fn make_service(&mut self, ctx: &'c Ctx) -> Self::Future {
(self.f)(ctx).into_future()
fn make_service(&mut self, target: &'t Target) -> Self::Future {
(self.f)(target)
}
}

View File

@@ -31,11 +31,7 @@
//! is called.
mod make_service;
mod new_service;
mod service;
pub use self::make_service::{make_service_fn, MakeService, MakeServiceRef};
// NewService is soft-deprecated.
#[doc(hidden)]
pub use self::new_service::NewService;
pub use self::service::{service_fn, service_fn_ok, Service};
pub use self::service::{service_fn, Service};

View File

@@ -1,79 +0,0 @@
use std::error::Error as StdError;
use futures::{Async, Future, IntoFuture, Poll};
use crate::body::Payload;
use super::{MakeService, Service};
/// An asynchronous constructor of `Service`s.
pub trait NewService {
/// The `Payload` body of the `http::Request`.
type ReqBody: Payload;
/// The `Payload` body of the `http::Response`.
type ResBody: Payload;
/// The error type that can be returned by `Service`s.
type Error: Into<Box<dyn StdError + Send + Sync>>;
/// The resolved `Service` from `new_service()`.
type Service: Service<
ReqBody=Self::ReqBody,
ResBody=Self::ResBody,
Error=Self::Error,
>;
/// The future returned from `new_service` of a `Service`.
type Future: Future<Item=Self::Service, Error=Self::InitError>;
/// The error type that can be returned when creating a new `Service`.
type InitError: Into<Box<dyn StdError + Send + Sync>>;
#[doc(hidden)]
fn poll_ready(&mut self) -> Poll<(), Self::InitError> {
Ok(Async::Ready(()))
}
/// Create a new `Service`.
fn new_service(&self) -> Self::Future;
}
impl<F, R, S> NewService for F
where
F: Fn() -> R,
R: IntoFuture<Item=S>,
R::Error: Into<Box<dyn StdError + Send + Sync>>,
S: Service,
{
type ReqBody = S::ReqBody;
type ResBody = S::ResBody;
type Error = S::Error;
type Service = S;
type Future = R::Future;
type InitError = R::Error;
fn new_service(&self) -> Self::Future {
(*self)().into_future()
}
}
impl<N, Ctx> MakeService<Ctx> for N
where
N: NewService,
{
type ReqBody = N::ReqBody;
type ResBody = N::ResBody;
type Error = N::Error;
type Service = N::Service;
type Future = N::Future;
type MakeError = N::InitError;
fn poll_ready(&mut self) -> Poll<(), Self::MakeError> {
NewService::poll_ready(self)
}
fn make_service(&mut self, _: Ctx) -> Self::Future {
self.new_service()
}
}

View File

@@ -2,10 +2,8 @@ use std::error::Error as StdError;
use std::fmt;
use std::marker::PhantomData;
use futures::{future, Async, Future, IntoFuture, Poll};
use crate::body::Payload;
use crate::common::Never;
use crate::common::{Future, Never, Poll, task};
use crate::{Request, Response};
/// An asynchronous function from `Request` to `Response`.
@@ -24,15 +22,15 @@ pub trait Service {
type Error: Into<Box<dyn StdError + Send + Sync>>;
/// The `Future` returned by this `Service`.
type Future: Future<Item=Response<Self::ResBody>, Error=Self::Error>;
type Future: Future<Output=Result<Response<Self::ResBody>, Self::Error>>;
/// Returns `Ready` when the service is able to process requests.
///
/// The implementation of this method is allowed to return a `Ready` even if
/// the service is not ready to process. In this case, the future returned
/// from `call` will resolve to an error.
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(Async::Ready(()))
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
/// Calls this `Service` with a request, returning a `Future` of the response.
@@ -61,7 +59,7 @@ pub trait Service {
pub fn service_fn<F, R, S>(f: F) -> ServiceFn<F, R>
where
F: FnMut(Request<R>) -> S,
S: IntoFuture,
S: Future,
{
ServiceFn {
f,
@@ -69,61 +67,27 @@ where
}
}
/// Create a `Service` from a function that never errors.
///
/// # Example
///
/// ```rust
/// use hyper::{Body, Request, Response};
/// use hyper::service::service_fn_ok;
///
/// let service = service_fn_ok(|req: Request<Body>| {
/// println!("request: {} {}", req.method(), req.uri());
/// Response::new(Body::from("Hello World"))
/// });
/// ```
pub fn service_fn_ok<F, R, S>(f: F) -> ServiceFnOk<F, R>
where
F: FnMut(Request<R>) -> Response<S>,
S: Payload,
{
ServiceFnOk {
f,
_req: PhantomData,
}
}
// Not exported from crate as this will likely be replaced with `impl Service`.
pub struct ServiceFn<F, R> {
f: F,
_req: PhantomData<fn(R)>,
}
impl<F, ReqBody, Ret, ResBody> Service for ServiceFn<F, ReqBody>
impl<F, ReqBody, Ret, ResBody, E> Service for ServiceFn<F, ReqBody>
where
F: FnMut(Request<ReqBody>) -> Ret,
ReqBody: Payload,
Ret: IntoFuture<Item=Response<ResBody>>,
Ret::Error: Into<Box<dyn StdError + Send + Sync>>,
Ret: Future<Output=Result<Response<ResBody>, E>>,
E: Into<Box<dyn StdError + Send + Sync>>,
ResBody: Payload,
{
type ReqBody = ReqBody;
type ResBody = ResBody;
type Error = Ret::Error;
type Future = Ret::Future;
type Error = E;
type Future = Ret;
fn call(&mut self, req: Request<Self::ReqBody>) -> Self::Future {
(self.f)(req).into_future()
}
}
impl<F, R> IntoFuture for ServiceFn<F, R> {
type Future = future::FutureResult<Self::Item, Self::Error>;
type Item = Self;
type Error = Never;
fn into_future(self) -> Self::Future {
future::ok(self)
(self.f)(req)
}
}
@@ -133,63 +97,3 @@ impl<F, R> fmt::Debug for ServiceFn<F, R> {
.finish()
}
}
// Not exported from crate as this will likely be replaced with `impl Service`.
pub struct ServiceFnOk<F, R> {
f: F,
_req: PhantomData<fn(R)>,
}
impl<F, ReqBody, ResBody> Service for ServiceFnOk<F, ReqBody>
where
F: FnMut(Request<ReqBody>) -> Response<ResBody>,
ReqBody: Payload,
ResBody: Payload,
{
type ReqBody = ReqBody;
type ResBody = ResBody;
type Error = Never;
type Future = future::FutureResult<Response<ResBody>, Never>;
fn call(&mut self, req: Request<Self::ReqBody>) -> Self::Future {
future::ok((self.f)(req))
}
}
impl<F, R> IntoFuture for ServiceFnOk<F, R> {
type Future = future::FutureResult<Self::Item, Self::Error>;
type Item = Self;
type Error = Never;
fn into_future(self) -> Self::Future {
future::ok(self)
}
}
impl<F, R> fmt::Debug for ServiceFnOk<F, R> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("impl Service")
.finish()
}
}
//#[cfg(test)]
fn _assert_fn_mut() {
fn assert_service<T: Service>(_t: &T) {}
let mut val = 0;
let svc = service_fn(move |_req: Request<crate::Body>| {
val += 1;
future::ok::<_, Never>(Response::new(crate::Body::empty()))
});
assert_service(&svc);
let svc = service_fn_ok(move |_req: Request<crate::Body>| {
val += 1;
Response::new(crate::Body::empty())
});
assert_service(&svc);
}