mirror of
https://github.com/tower-rs/tower.git
synced 2025-10-02 23:34:59 +00:00
make all combinator futures opaque (#509)
* make all combinator futures opaque For stability reasons, we probably don't want to expose future combinator types from the `futures_util` crate in public APIs. If we were to change which combinators are used to implement these futures, or if `futures_util` made breaking changes, this could cause API breakage. This branch wraps all publicly exposed `futures_util` types in the `opaque_future!` macro added in #508, to wrap them in newtypes that hide their internal details. This way, we can change these futures' internals whenever we like. Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This commit is contained in:
parent
2a7d47adda
commit
3b7c91ed58
@ -33,7 +33,6 @@ pub use self::{
|
|||||||
|
|
||||||
use self::future::{AsyncResponseFuture, ResponseFuture};
|
use self::future::{AsyncResponseFuture, ResponseFuture};
|
||||||
use crate::BoxError;
|
use crate::BoxError;
|
||||||
use futures_core::ready;
|
|
||||||
use futures_util::{future::Either, TryFutureExt};
|
use futures_util::{future::Either, TryFutureExt};
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use tower_service::Service;
|
use tower_service::Service;
|
||||||
|
@ -20,6 +20,13 @@ pub struct BackgroundReady<T, Request> {
|
|||||||
_req: PhantomData<Request>,
|
_req: PhantomData<Request>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opaque_future! {
|
||||||
|
/// Response future from [`SpawnReady`] services.
|
||||||
|
///
|
||||||
|
/// [`SpawnReady`]: crate::spawn_ready::SpawnReady
|
||||||
|
pub type ResponseFuture<F, E> = futures_util::future::MapErr<F, fn(E) -> crate::BoxError>;
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn background_ready<T, Request>(
|
pub(crate) fn background_ready<T, Request>(
|
||||||
service: T,
|
service: T,
|
||||||
) -> (
|
) -> (
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::future::background_ready;
|
use super::future::{background_ready, ResponseFuture};
|
||||||
use futures_core::ready;
|
use futures_core::ready;
|
||||||
use futures_util::future::{MapErr, TryFutureExt};
|
use futures_util::future::TryFutureExt;
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
future::Future,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
@ -40,7 +40,7 @@ where
|
|||||||
{
|
{
|
||||||
type Response = T::Response;
|
type Response = T::Response;
|
||||||
type Error = crate::BoxError;
|
type Error = crate::BoxError;
|
||||||
type Future = MapErr<T::Future, fn(T::Error) -> crate::BoxError>;
|
type Future = ResponseFuture<T::Future, T::Error>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
loop {
|
loop {
|
||||||
@ -66,7 +66,9 @@ where
|
|||||||
|
|
||||||
fn call(&mut self, request: Request) -> Self::Future {
|
fn call(&mut self, request: Request) -> Self::Future {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
Inner::Service(Some(ref mut svc)) => svc.call(request).map_err(Into::into),
|
Inner::Service(Some(ref mut svc)) => {
|
||||||
|
ResponseFuture(svc.call(request).map_err(Into::into))
|
||||||
|
}
|
||||||
_ => unreachable!("poll_ready must be called"),
|
_ => unreachable!("poll_ready must be called"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
use futures_util::TryFutureExt;
|
use futures_util::{future, TryFutureExt};
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use tower_layer::Layer;
|
use tower_layer::Layer;
|
||||||
use tower_service::Service;
|
use tower_service::Service;
|
||||||
|
|
||||||
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
|
|
||||||
pub use futures_util::future::MapErr as MapErrFuture;
|
|
||||||
|
|
||||||
/// Service returned by the [`map_err`] combinator.
|
/// Service returned by the [`map_err`] combinator.
|
||||||
///
|
///
|
||||||
/// [`map_err`]: crate::util::ServiceExt::map_err
|
/// [`map_err`]: crate::util::ServiceExt::map_err
|
||||||
@ -23,6 +20,13 @@ pub struct MapErrLayer<F> {
|
|||||||
f: F,
|
f: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opaque_future! {
|
||||||
|
/// Response future from [`MapErr`] services.
|
||||||
|
///
|
||||||
|
/// [`MapErr`]: crate::util::MapErr
|
||||||
|
pub type MapErrFuture<F, N> = future::MapErr<F, N>;
|
||||||
|
}
|
||||||
|
|
||||||
impl<S, F> MapErr<S, F> {
|
impl<S, F> MapErr<S, F> {
|
||||||
/// Creates a new [`MapErr`] service.
|
/// Creates a new [`MapErr`] service.
|
||||||
pub fn new(inner: S, f: F) -> Self {
|
pub fn new(inner: S, f: F) -> Self {
|
||||||
@ -46,7 +50,7 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn call(&mut self, request: Request) -> Self::Future {
|
fn call(&mut self, request: Request) -> Self::Future {
|
||||||
self.inner.call(request).map_err(self.f.clone())
|
MapErrFuture(self.inner.call(request).map_err(self.f.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
use futures_util::TryFutureExt;
|
use futures_util::{future::MapOk, TryFutureExt};
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use tower_layer::Layer;
|
use tower_layer::Layer;
|
||||||
use tower_service::Service;
|
use tower_service::Service;
|
||||||
|
|
||||||
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
|
|
||||||
pub use futures_util::future::MapOk as MapResponseFuture;
|
|
||||||
|
|
||||||
/// Service returned by the [`map_response`] combinator.
|
/// Service returned by the [`map_response`] combinator.
|
||||||
///
|
///
|
||||||
/// [`map_response`]: crate::util::ServiceExt::map_response
|
/// [`map_response`]: crate::util::ServiceExt::map_response
|
||||||
@ -23,6 +20,13 @@ pub struct MapResponseLayer<F> {
|
|||||||
f: F,
|
f: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opaque_future! {
|
||||||
|
/// Response future from [`MapResponse`] services.
|
||||||
|
///
|
||||||
|
/// [`MapResponse`]: crate::util::MapResponse
|
||||||
|
pub type MapResponseFuture<F, N> = MapOk<F, N>;
|
||||||
|
}
|
||||||
|
|
||||||
impl<S, F> MapResponse<S, F> {
|
impl<S, F> MapResponse<S, F> {
|
||||||
/// Creates a new `MapResponse` service.
|
/// Creates a new `MapResponse` service.
|
||||||
pub fn new(inner: S, f: F) -> Self {
|
pub fn new(inner: S, f: F) -> Self {
|
||||||
@ -46,7 +50,7 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn call(&mut self, request: Request) -> Self::Future {
|
fn call(&mut self, request: Request) -> Self::Future {
|
||||||
self.inner.call(request).map_ok(self.f.clone())
|
MapResponseFuture(self.inner.call(request).map_ok(self.f.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
use futures_util::FutureExt;
|
use futures_util::{future::Map, FutureExt};
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use tower_layer::Layer;
|
use tower_layer::Layer;
|
||||||
use tower_service::Service;
|
use tower_service::Service;
|
||||||
|
|
||||||
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
|
|
||||||
pub use futures_util::future::Map as MapResultFuture;
|
|
||||||
|
|
||||||
/// Service returned by the [`map_result`] combinator.
|
/// Service returned by the [`map_result`] combinator.
|
||||||
///
|
///
|
||||||
/// [`map_result`]: crate::util::ServiceExt::map_result
|
/// [`map_result`]: crate::util::ServiceExt::map_result
|
||||||
@ -23,6 +20,13 @@ pub struct MapResultLayer<F> {
|
|||||||
f: F,
|
f: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opaque_future! {
|
||||||
|
/// Response future from [`MapResult`] services.
|
||||||
|
///
|
||||||
|
/// [`MapResult`]: crate::util::MapResult
|
||||||
|
pub type MapResultFuture<F, N> = Map<F, N>;
|
||||||
|
}
|
||||||
|
|
||||||
impl<S, F> MapResult<S, F> {
|
impl<S, F> MapResult<S, F> {
|
||||||
/// Creates a new `MapResult` service.
|
/// Creates a new `MapResult` service.
|
||||||
pub fn new(inner: S, f: F) -> Self {
|
pub fn new(inner: S, f: F) -> Self {
|
||||||
@ -47,7 +51,7 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn call(&mut self, request: Request) -> Self::Future {
|
fn call(&mut self, request: Request) -> Self::Future {
|
||||||
self.inner.call(request).map(self.f.clone())
|
MapResultFuture(self.inner.call(request).map(self.f.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use futures_util::FutureExt;
|
use futures_util::{future, FutureExt};
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
future::Future,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
@ -6,9 +6,6 @@ use std::{
|
|||||||
use tower_layer::Layer;
|
use tower_layer::Layer;
|
||||||
use tower_service::Service;
|
use tower_service::Service;
|
||||||
|
|
||||||
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
|
|
||||||
pub use futures_util::future::Then as ThenFuture;
|
|
||||||
|
|
||||||
/// Service returned by the [`then`] combinator.
|
/// Service returned by the [`then`] combinator.
|
||||||
///
|
///
|
||||||
/// [`then`]: crate::util::ServiceExt::then
|
/// [`then`]: crate::util::ServiceExt::then
|
||||||
@ -33,6 +30,13 @@ impl<S, F> Then<S, F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opaque_future! {
|
||||||
|
/// Response future from [`Then`] services.
|
||||||
|
///
|
||||||
|
/// [`Then`]: crate::util::Then
|
||||||
|
pub type ThenFuture<F1, F2, N> = future::Then<F1, F2, N>;
|
||||||
|
}
|
||||||
|
|
||||||
impl<S, F, Request, Response, Error, Fut> Service<Request> for Then<S, F>
|
impl<S, F, Request, Response, Error, Fut> Service<Request> for Then<S, F>
|
||||||
where
|
where
|
||||||
S: Service<Request>,
|
S: Service<Request>,
|
||||||
@ -51,7 +55,7 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn call(&mut self, request: Request) -> Self::Future {
|
fn call(&mut self, request: Request) -> Self::Future {
|
||||||
self.inner.call(request).then(self.f.clone())
|
ThenFuture(self.inner.call(request).then(self.f.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user