1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-30 19:54:36 +01:00

use concrete types

This commit is contained in:
Nikolay Kim 2019-11-18 14:30:04 +06:00
parent c1cdc9908a
commit 7404d82a9b
25 changed files with 568 additions and 746 deletions

View File

@ -216,11 +216,8 @@ impl<T, U> Framed<T, U> {
} }
impl<T, U> Framed<T, U> { impl<T, U> Framed<T, U> {
/// Force send item /// Serialize item and Write to the inner buffer
pub fn force_send( pub fn write(&mut self, item: <U as Encoder>::Item) -> Result<(), <U as Encoder>::Error>
&mut self,
item: <U as Encoder>::Item,
) -> Result<(), <U as Encoder>::Error>
where where
T: AsyncWrite + Unpin, T: AsyncWrite + Unpin,
U: Encoder + Unpin, U: Encoder + Unpin,

View File

@ -6,7 +6,7 @@ use std::net::SocketAddr;
use either::Either; use either::Either;
/// Connect request /// Connect request
pub trait Address { pub trait Address: Unpin {
/// Host name of the request /// Host name of the request
fn host(&self) -> &str; fn host(&self) -> &str;

View File

@ -20,6 +20,10 @@ pub mod ssl;
#[cfg(feature = "uri")] #[cfg(feature = "uri")]
mod uri; mod uri;
use actix_rt::Arbiter;
use actix_service::{pipeline, pipeline_factory, Service, ServiceFactory};
use tokio_net::tcp::TcpStream;
pub use trust_dns_resolver::config::{ResolverConfig, ResolverOpts}; pub use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
pub use trust_dns_resolver::system_conf::read_system_conf; pub use trust_dns_resolver::system_conf::read_system_conf;
pub use trust_dns_resolver::{error::ResolveError, AsyncResolver}; pub use trust_dns_resolver::{error::ResolveError, AsyncResolver};
@ -30,10 +34,6 @@ pub use self::error::ConnectError;
pub use self::resolver::{Resolver, ResolverFactory}; pub use self::resolver::{Resolver, ResolverFactory};
pub use self::service::{ConnectService, ConnectServiceFactory, TcpConnectService}; pub use self::service::{ConnectService, ConnectServiceFactory, TcpConnectService};
use actix_rt::Arbiter;
use actix_service::{pipeline, pipeline_factory, Service, ServiceFactory};
use tokio_net::tcp::TcpStream;
pub fn start_resolver(cfg: ResolverConfig, opts: ResolverOpts) -> AsyncResolver { pub fn start_resolver(cfg: ResolverConfig, opts: ResolverOpts) -> AsyncResolver {
let (resolver, bg) = AsyncResolver::new(cfg, opts); let (resolver, bg) = AsyncResolver::new(cfg, opts);
tokio_executor::current_thread::spawn(bg); tokio_executor::current_thread::spawn(bg);
@ -70,7 +70,7 @@ pub fn start_default_resolver() -> AsyncResolver {
pub fn new_connector<T: Address>( pub fn new_connector<T: Address>(
resolver: AsyncResolver, resolver: AsyncResolver,
) -> impl Service<Request = Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError> ) -> impl Service<Request = Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError>
{ + Clone {
pipeline(Resolver::new(resolver)).and_then(TcpConnector::new()) pipeline(Resolver::new(resolver)).and_then(TcpConnector::new())
} }
@ -83,14 +83,14 @@ pub fn new_connector_factory<T: Address>(
Response = Connection<T, TcpStream>, Response = Connection<T, TcpStream>,
Error = ConnectError, Error = ConnectError,
InitError = (), InitError = (),
> { > + Clone {
pipeline_factory(ResolverFactory::new(resolver)).and_then(TcpConnectorFactory::new()) pipeline_factory(ResolverFactory::new(resolver)).and_then(TcpConnectorFactory::new())
} }
/// Create connector service with default parameters /// Create connector service with default parameters
pub fn default_connector<T: Address>( pub fn default_connector<T: Address>(
) -> impl Service<Request = Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError> ) -> impl Service<Request = Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError>
{ + Clone {
pipeline(Resolver::default()).and_then(TcpConnector::new()) pipeline(Resolver::default()).and_then(TcpConnector::new())
} }
@ -101,6 +101,6 @@ pub fn default_connector_factory<T: Address>() -> impl ServiceFactory<
Response = Connection<T, TcpStream>, Response = Connection<T, TcpStream>,
Error = ConnectError, Error = ConnectError,
InitError = (), InitError = (),
> { > + Clone {
pipeline_factory(ResolverFactory::default()).and_then(TcpConnectorFactory::new()) pipeline_factory(ResolverFactory::default()).and_then(TcpConnectorFactory::new())
} }

View File

@ -330,7 +330,7 @@ where
if !buf_empty { if !buf_empty {
match inner.buf.pop_front().unwrap() { match inner.buf.pop_front().unwrap() {
Ok(msg) => { Ok(msg) => {
if let Err(err) = framed.force_send(msg) { if let Err(err) = framed.write(msg) {
*dispatch_state = *dispatch_state =
FramedState::FramedError(ServiceError::Encoder(err)); FramedState::FramedError(ServiceError::Encoder(err));
return true; return true;
@ -347,7 +347,7 @@ where
if !rx_done && rx.is_some() { if !rx_done && rx.is_some() {
match Pin::new(rx.as_mut().unwrap()).poll_next(cx) { match Pin::new(rx.as_mut().unwrap()).poll_next(cx) {
Poll::Ready(Some(FramedMessage::Message(msg))) => { Poll::Ready(Some(FramedMessage::Message(msg))) => {
if let Err(err) = framed.force_send(msg) { if let Err(err) = framed.write(msg) {
*dispatch_state = *dispatch_state =
FramedState::FramedError(ServiceError::Encoder(err)); FramedState::FramedError(ServiceError::Encoder(err));
return true; return true;

View File

@ -24,7 +24,6 @@ path = "src/lib.rs"
[dependencies] [dependencies]
futures = "0.3.1" futures = "0.3.1"
pin-project = "0.4.5"
[dev-dependencies] [dev-dependencies]
tokio = "0.2.0-alpha.5" tokio = "0.2.0-alpha.5"

View File

@ -2,8 +2,6 @@ use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use pin_project::pin_project;
use super::{Service, ServiceFactory}; use super::{Service, ServiceFactory};
use crate::cell::Cell; use crate::cell::Cell;
@ -11,14 +9,14 @@ use crate::cell::Cell;
/// of another service which completes successfully. /// of another service which completes successfully.
/// ///
/// This is created by the `ServiceExt::and_then` method. /// This is created by the `ServiceExt::and_then` method.
pub struct AndThen<A, B> { pub struct AndThenService<A, B> {
a: A, a: A,
b: Cell<B>, b: Cell<B>,
} }
impl<A, B> AndThen<A, B> { impl<A, B> AndThenService<A, B> {
/// Create new `AndThen` combinator /// Create new `AndThen` combinator
pub fn new(a: A, b: B) -> Self pub(crate) fn new(a: A, b: B) -> Self
where where
A: Service, A: Service,
B: Service<Request = A::Response, Error = A::Error>, B: Service<Request = A::Response, Error = A::Error>,
@ -27,27 +25,29 @@ impl<A, B> AndThen<A, B> {
} }
} }
impl<A, B> Clone for AndThen<A, B> impl<A, B> Clone for AndThenService<A, B>
where where
A: Clone, A: Clone,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
AndThen { AndThenService {
a: self.a.clone(), a: self.a.clone(),
b: self.b.clone(), b: self.b.clone(),
} }
} }
} }
impl<A, B> Service for AndThen<A, B> impl<A, B> Service for AndThenService<A, B>
where where
A: Service, A: Service,
B: Service<Request = A::Response, Error = A::Error>, B: Service<Request = A::Response, Error = A::Error>,
A::Future: Unpin,
B::Future: Unpin,
{ {
type Request = A::Request; type Request = A::Request;
type Response = B::Response; type Response = B::Response;
type Error = A::Error; type Error = A::Error;
type Future = AndThenFuture<A, B>; type Future = AndThenServiceResponse<A, B>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
let not_ready = !self.a.poll_ready(cx)?.is_ready(); let not_ready = !self.a.poll_ready(cx)?.is_ready();
@ -59,30 +59,29 @@ where
} }
fn call(&mut self, req: A::Request) -> Self::Future { fn call(&mut self, req: A::Request) -> Self::Future {
AndThenFuture::new(self.a.call(req), self.b.clone()) AndThenServiceResponse::new(self.a.call(req), self.b.clone())
} }
} }
#[pin_project] pub struct AndThenServiceResponse<A, B>
pub struct AndThenFuture<A, B>
where where
A: Service, A: Service,
B: Service<Request = A::Response, Error = A::Error>, B: Service<Request = A::Response, Error = A::Error>,
{ {
b: Cell<B>, b: Cell<B>,
#[pin]
fut_b: Option<B::Future>, fut_b: Option<B::Future>,
#[pin]
fut_a: Option<A::Future>, fut_a: Option<A::Future>,
} }
impl<A, B> AndThenFuture<A, B> impl<A, B> AndThenServiceResponse<A, B>
where where
A: Service, A: Service,
B: Service<Request = A::Response, Error = A::Error>, B: Service<Request = A::Response, Error = A::Error>,
A::Future: Unpin,
B::Future: Unpin,
{ {
fn new(a: A::Future, b: Cell<B>) -> Self { fn new(a: A::Future, b: Cell<B>) -> Self {
AndThenFuture { AndThenServiceResponse {
b, b,
fut_a: Some(a), fut_a: Some(a),
fut_b: None, fut_b: None,
@ -90,34 +89,27 @@ where
} }
} }
impl<A, B> Future for AndThenFuture<A, B> impl<A, B> Future for AndThenServiceResponse<A, B>
where where
A: Service, A: Service,
B: Service<Request = A::Response, Error = A::Error>, B: Service<Request = A::Response, Error = A::Error>,
A::Future: Unpin,
B::Future: Unpin,
{ {
type Output = Result<B::Response, A::Error>; type Output = Result<B::Response, A::Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut this = self.project(); let mut this = self.get_mut();
loop { loop {
let mut fut_a = this.fut_a.as_mut(); if let Some(ref mut fut) = this.fut_b {
let mut fut_b = this.fut_b.as_mut(); return Pin::new(fut).poll(cx);
if let Some(fut) = fut_b.as_mut().as_pin_mut() {
return fut.poll(cx);
} }
match fut_a match Pin::new(&mut this.fut_a.as_mut().expect("Bug in actix-service")).poll(cx) {
.as_mut()
.as_pin_mut()
.expect("Bug in actix-service")
.poll(cx)
{
Poll::Ready(Ok(resp)) => { Poll::Ready(Ok(resp)) => {
fut_a.set(None); let _ = this.fut_a.take();
let new_fut = this.b.get_mut().call(resp); this.fut_b = Some(this.b.get_mut().call(resp));
fut_b.set(Some(new_fut));
} }
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)), Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
Poll::Pending => return Poll::Pending, Poll::Pending => return Poll::Pending,
@ -126,8 +118,8 @@ where
} }
} }
/// `AndThenNewService` new service combinator /// `.and_then()` service factory combinator
pub struct AndThenNewService<A, B> pub struct AndThenServiceFactory<A, B>
where where
A: ServiceFactory, A: ServiceFactory,
B: ServiceFactory, B: ServiceFactory,
@ -136,7 +128,7 @@ where
b: B, b: B,
} }
impl<A, B> AndThenNewService<A, B> impl<A, B> AndThenServiceFactory<A, B>
where where
A: ServiceFactory, A: ServiceFactory,
B: ServiceFactory< B: ServiceFactory<
@ -146,13 +138,13 @@ where
InitError = A::InitError, InitError = A::InitError,
>, >,
{ {
/// Create new `AndThen` combinator /// Create new `AndThenFactory` combinator
pub fn new(a: A, b: B) -> Self { pub fn new(a: A, b: B) -> Self {
Self { a, b } Self { a, b }
} }
} }
impl<A, B> ServiceFactory for AndThenNewService<A, B> impl<A, B> ServiceFactory for AndThenServiceFactory<A, B>
where where
A: ServiceFactory, A: ServiceFactory,
B: ServiceFactory< B: ServiceFactory<
@ -161,22 +153,28 @@ where
Error = A::Error, Error = A::Error,
InitError = A::InitError, InitError = A::InitError,
>, >,
A::Future: Unpin,
A::Service: Unpin,
<A::Service as Service>::Future: Unpin,
B::Future: Unpin,
B::Service: Unpin,
<B::Service as Service>::Future: Unpin,
{ {
type Request = A::Request; type Request = A::Request;
type Response = B::Response; type Response = B::Response;
type Error = A::Error; type Error = A::Error;
type Config = A::Config; type Config = A::Config;
type Service = AndThen<A::Service, B::Service>; type Service = AndThenService<A::Service, B::Service>;
type InitError = A::InitError; type InitError = A::InitError;
type Future = AndThenNewServiceFuture<A, B>; type Future = AndThenServiceFactoryResponse<A, B>;
fn new_service(&self, cfg: &A::Config) -> Self::Future { fn new_service(&self, cfg: &A::Config) -> Self::Future {
AndThenNewServiceFuture::new(self.a.new_service(cfg), self.b.new_service(cfg)) AndThenServiceFactoryResponse::new(self.a.new_service(cfg), self.b.new_service(cfg))
} }
} }
impl<A, B> Clone for AndThenNewService<A, B> impl<A, B> Clone for AndThenServiceFactory<A, B>
where where
A: ServiceFactory + Clone, A: ServiceFactory + Clone,
B: ServiceFactory + Clone, B: ServiceFactory + Clone,
@ -189,28 +187,31 @@ where
} }
} }
#[pin_project] pub struct AndThenServiceFactoryResponse<A, B>
pub struct AndThenNewServiceFuture<A, B>
where where
A: ServiceFactory, A: ServiceFactory,
B: ServiceFactory<Request = A::Response>, B: ServiceFactory<Request = A::Response>,
{ {
#[pin]
fut_b: B::Future, fut_b: B::Future,
#[pin]
fut_a: A::Future, fut_a: A::Future,
a: Option<A::Service>, a: Option<A::Service>,
b: Option<B::Service>, b: Option<B::Service>,
} }
impl<A, B> AndThenNewServiceFuture<A, B> impl<A, B> AndThenServiceFactoryResponse<A, B>
where where
A: ServiceFactory, A: ServiceFactory,
B: ServiceFactory<Request = A::Response>, B: ServiceFactory<Request = A::Response>,
A::Future: Unpin,
A::Service: Unpin,
<A::Service as Service>::Future: Unpin,
B::Future: Unpin,
B::Service: Unpin,
<B::Service as Service>::Future: Unpin,
{ {
fn new(fut_a: A::Future, fut_b: B::Future) -> Self { fn new(fut_a: A::Future, fut_b: B::Future) -> Self {
AndThenNewServiceFuture { AndThenServiceFactoryResponse {
fut_a, fut_a,
fut_b, fut_b,
a: None, a: None,
@ -219,27 +220,34 @@ where
} }
} }
impl<A, B> Future for AndThenNewServiceFuture<A, B> impl<A, B> Future for AndThenServiceFactoryResponse<A, B>
where where
A: ServiceFactory, A: ServiceFactory,
B: ServiceFactory<Request = A::Response, Error = A::Error, InitError = A::InitError>, B: ServiceFactory<Request = A::Response, Error = A::Error, InitError = A::InitError>,
A::Future: Unpin,
A::Service: Unpin,
<A::Service as Service>::Future: Unpin,
B::Future: Unpin,
B::Service: Unpin,
<B::Service as Service>::Future: Unpin,
{ {
type Output = Result<AndThen<A::Service, B::Service>, A::InitError>; type Output = Result<AndThenService<A::Service, B::Service>, A::InitError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project(); let this = self.get_mut();
if this.a.is_none() { if this.a.is_none() {
if let Poll::Ready(service) = this.fut_a.poll(cx)? { if let Poll::Ready(service) = Pin::new(&mut this.fut_a).poll(cx)? {
*this.a = Some(service); this.a = Some(service);
} }
} }
if this.b.is_none() { if this.b.is_none() {
if let Poll::Ready(service) = this.fut_b.poll(cx)? { if let Poll::Ready(service) = Pin::new(&mut this.fut_b).poll(cx)? {
*this.b = Some(service); this.b = Some(service);
} }
} }
if this.a.is_some() && this.b.is_some() { if this.a.is_some() && this.b.is_some() {
Poll::Ready(Ok(AndThen::new( Poll::Ready(Ok(AndThenService::new(
this.a.take().unwrap(), this.a.take().unwrap(),
this.b.take().unwrap(), this.b.take().unwrap(),
))) )))

View File

@ -1,4 +1,3 @@
use pin_project::pin_project;
use std::future::Future; use std::future::Future;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::pin::Pin; use std::pin::Pin;
@ -7,10 +6,7 @@ use std::task::{Context, Poll};
use super::{IntoService, IntoServiceFactory, Service, ServiceFactory}; use super::{IntoService, IntoServiceFactory, Service, ServiceFactory};
/// Apply tranform function to a service /// Apply tranform function to a service
pub fn apply_fn<T, F, R, In, Out, Err, U>( pub fn apply_fn<T, F, R, In, Out, Err, U>(service: U, f: F) -> Apply<T, F, R, In, Out, Err>
service: U,
f: F,
) -> impl Service<Request = In, Response = Out, Error = Err>
where where
T: Service<Error = Err>, T: Service<Error = Err>,
F: FnMut(In, &mut T) -> R, F: FnMut(In, &mut T) -> R,
@ -24,30 +20,21 @@ where
pub fn apply_fn_factory<T, F, R, In, Out, Err, U>( pub fn apply_fn_factory<T, F, R, In, Out, Err, U>(
service: U, service: U,
f: F, f: F,
) -> impl ServiceFactory< ) -> ApplyServiceFactory<T, F, R, In, Out, Err>
Config = T::Config,
Request = In,
Response = Out,
Error = Err,
InitError = T::InitError,
>
where where
T: ServiceFactory<Error = Err>, T: ServiceFactory<Error = Err>,
F: FnMut(In, &mut T::Service) -> R + Clone, F: FnMut(In, &mut T::Service) -> R + Clone,
R: Future<Output = Result<Out, Err>>, R: Future<Output = Result<Out, Err>>,
U: IntoServiceFactory<T>, U: IntoServiceFactory<T>,
{ {
ApplyNewService::new(service.into_factory(), f) ApplyServiceFactory::new(service.into_factory(), f)
} }
#[doc(hidden)]
/// `Apply` service combinator /// `Apply` service combinator
#[pin_project] pub struct Apply<T, F, R, In, Out, Err>
struct Apply<T, F, R, In, Out, Err>
where where
T: Service<Error = Err>, T: Service<Error = Err>,
{ {
#[pin]
service: T, service: T,
f: F, f: F,
r: PhantomData<(In, Out, R)>, r: PhantomData<(In, Out, R)>,
@ -89,8 +76,8 @@ where
} }
} }
/// `ApplyNewService` new service combinator /// `apply()` service factory
struct ApplyNewService<T, F, R, In, Out, Err> pub struct ApplyServiceFactory<T, F, R, In, Out, Err>
where where
T: ServiceFactory<Error = Err>, T: ServiceFactory<Error = Err>,
{ {
@ -99,7 +86,7 @@ where
r: PhantomData<(R, In, Out)>, r: PhantomData<(R, In, Out)>,
} }
impl<T, F, R, In, Out, Err> ApplyNewService<T, F, R, In, Out, Err> impl<T, F, R, In, Out, Err> ApplyServiceFactory<T, F, R, In, Out, Err>
where where
T: ServiceFactory<Error = Err>, T: ServiceFactory<Error = Err>,
F: FnMut(In, &mut T::Service) -> R + Clone, F: FnMut(In, &mut T::Service) -> R + Clone,
@ -115,10 +102,11 @@ where
} }
} }
impl<T, F, R, In, Out, Err> ServiceFactory for ApplyNewService<T, F, R, In, Out, Err> impl<T, F, R, In, Out, Err> ServiceFactory for ApplyServiceFactory<T, F, R, In, Out, Err>
where where
T: ServiceFactory<Error = Err>, T: ServiceFactory<Error = Err>,
F: FnMut(In, &mut T::Service) -> R + Clone, T::Future: Unpin,
F: FnMut(In, &mut T::Service) -> R + Unpin + Clone,
R: Future<Output = Result<Out, Err>>, R: Future<Output = Result<Out, Err>>,
{ {
type Request = In; type Request = In;
@ -128,34 +116,32 @@ where
type Config = T::Config; type Config = T::Config;
type Service = Apply<T::Service, F, R, In, Out, Err>; type Service = Apply<T::Service, F, R, In, Out, Err>;
type InitError = T::InitError; type InitError = T::InitError;
type Future = ApplyNewServiceFuture<T, F, R, In, Out, Err>; type Future = ApplyServiceFactoryResponse<T, F, R, In, Out, Err>;
fn new_service(&self, cfg: &T::Config) -> Self::Future { fn new_service(&self, cfg: &T::Config) -> Self::Future {
ApplyNewServiceFuture::new(self.service.new_service(cfg), self.f.clone()) ApplyServiceFactoryResponse::new(self.service.new_service(cfg), self.f.clone())
} }
} }
#[pin_project] pub struct ApplyServiceFactoryResponse<T, F, R, In, Out, Err>
struct ApplyNewServiceFuture<T, F, R, In, Out, Err>
where where
T: ServiceFactory<Error = Err>, T: ServiceFactory<Error = Err>,
F: FnMut(In, &mut T::Service) -> R + Clone, F: FnMut(In, &mut T::Service) -> R + Clone,
R: Future<Output = Result<Out, Err>>, R: Future<Output = Result<Out, Err>>,
{ {
#[pin]
fut: T::Future, fut: T::Future,
f: Option<F>, f: Option<F>,
r: PhantomData<(In, Out)>, r: PhantomData<(In, Out)>,
} }
impl<T, F, R, In, Out, Err> ApplyNewServiceFuture<T, F, R, In, Out, Err> impl<T, F, R, In, Out, Err> ApplyServiceFactoryResponse<T, F, R, In, Out, Err>
where where
T: ServiceFactory<Error = Err>, T: ServiceFactory<Error = Err>,
F: FnMut(In, &mut T::Service) -> R + Clone, F: FnMut(In, &mut T::Service) -> R + Clone,
R: Future<Output = Result<Out, Err>>, R: Future<Output = Result<Out, Err>>,
{ {
fn new(fut: T::Future, f: F) -> Self { fn new(fut: T::Future, f: F) -> Self {
ApplyNewServiceFuture { Self {
f: Some(f), f: Some(f),
fut, fut,
r: PhantomData, r: PhantomData,
@ -163,17 +149,28 @@ where
} }
} }
impl<T, F, R, In, Out, Err> Future for ApplyNewServiceFuture<T, F, R, In, Out, Err> impl<T, F, R, In, Out, Err> Unpin for ApplyServiceFactoryResponse<T, F, R, In, Out, Err>
where where
T: ServiceFactory<Error = Err>, T: ServiceFactory<Error = Err>,
F: FnMut(In, &mut T::Service) -> R + Clone, T::Future: Unpin,
F: FnMut(In, &mut T::Service) -> R + Unpin + Clone,
R: Future<Output = Result<Out, Err>>,
{
}
impl<T, F, R, In, Out, Err> Future for ApplyServiceFactoryResponse<T, F, R, In, Out, Err>
where
T: ServiceFactory<Error = Err>,
T::Future: Unpin,
F: FnMut(In, &mut T::Service) -> R + Unpin + Clone,
R: Future<Output = Result<Out, Err>>, R: Future<Output = Result<Out, Err>>,
{ {
type Output = Result<Apply<T::Service, F, R, In, Out, Err>, T::InitError>; type Output = Result<Apply<T::Service, F, R, In, Out, Err>, T::InitError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project(); let this = self.get_mut();
if let Poll::Ready(svc) = this.fut.poll(cx)? {
if let Poll::Ready(svc) = Pin::new(&mut this.fut).poll(cx)? {
Poll::Ready(Ok(Apply::new(svc, this.f.take().unwrap()))) Poll::Ready(Ok(Apply::new(svc, this.f.take().unwrap())))
} else { } else {
Poll::Pending Poll::Pending

View File

@ -3,28 +3,15 @@ use std::marker::PhantomData;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use futures::ready;
use pin_project::pin_project;
use crate::cell::Cell; use crate::cell::Cell;
use crate::{IntoService, Service, ServiceFactory}; use crate::{Service, ServiceFactory};
/// Convert `Fn(&Config, &mut Service) -> Future<Service>` fn to a NewService /// Convert `Fn(&Config, &mut Service) -> Future<Service>` fn to a NewService
pub fn apply_cfg<F, C, T, R, S, E>( pub fn apply_cfg<F, C, T, R, S, E>(srv: T, f: F) -> ApplyConfigService<F, C, T, R, S, E>
srv: T,
f: F,
) -> impl ServiceFactory<
Config = C,
Request = S::Request,
Response = S::Response,
Error = S::Error,
Service = S,
InitError = E,
> + Clone
where where
F: FnMut(&C, &mut T) -> R, F: FnMut(&C, &mut T) -> R,
T: Service, T: Service,
R: Future<Output = Result<S, E>>, R: Future<Output = Result<S, E>> + Unpin,
S: Service, S: Service,
{ {
ApplyConfigService { ApplyConfigService {
@ -39,14 +26,7 @@ where
pub fn apply_cfg_factory<F, C, T, R, S>( pub fn apply_cfg_factory<F, C, T, R, S>(
srv: T, srv: T,
f: F, f: F,
) -> impl ServiceFactory< ) -> ApplyConfigServiceFactory<F, C, T, R, S>
Config = C,
Request = S::Request,
Response = S::Response,
Error = S::Error,
Service = S,
InitError = T::InitError,
> + Clone
where where
C: Clone, C: Clone,
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
@ -55,7 +35,7 @@ where
R: Future<Output = Result<S, T::InitError>>, R: Future<Output = Result<S, T::InitError>>,
S: Service, S: Service,
{ {
ApplyConfigNewService { ApplyConfigServiceFactory {
f: Cell::new(f), f: Cell::new(f),
srv: Cell::new(srv), srv: Cell::new(srv),
_t: PhantomData, _t: PhantomData,
@ -63,8 +43,7 @@ where
} }
/// Convert `Fn(&Config) -> Future<Service>` fn to NewService\ /// Convert `Fn(&Config) -> Future<Service>` fn to NewService\
#[pin_project] pub struct ApplyConfigService<F, C, T, R, S, E>
struct ApplyConfigService<F, C, T, R, S, E>
where where
F: FnMut(&C, &mut T) -> R, F: FnMut(&C, &mut T) -> R,
T: Service, T: Service,
@ -72,7 +51,6 @@ where
S: Service, S: Service,
{ {
f: Cell<F>, f: Cell<F>,
#[pin]
srv: Cell<T>, srv: Cell<T>,
_t: PhantomData<(C, R, S)>, _t: PhantomData<(C, R, S)>,
} }
@ -97,7 +75,8 @@ impl<F, C, T, R, S, E> ServiceFactory for ApplyConfigService<F, C, T, R, S, E>
where where
F: FnMut(&C, &mut T) -> R, F: FnMut(&C, &mut T) -> R,
T: Service, T: Service,
R: Future<Output = Result<S, E>>, T::Future: Unpin,
R: Future<Output = Result<S, E>> + Unpin,
S: Service, S: Service,
{ {
type Config = C; type Config = C;
@ -107,41 +86,46 @@ where
type Service = S; type Service = S;
type InitError = E; type InitError = E;
type Future = FnNewServiceConfigFut<R, S, E>; type Future = ApplyConfigServiceResponse<R, S, E>;
fn new_service(&self, cfg: &C) -> Self::Future { fn new_service(&self, cfg: &C) -> Self::Future {
FnNewServiceConfigFut { ApplyConfigServiceResponse {
fut: unsafe { (self.f.get_mut_unsafe())(cfg, self.srv.get_mut_unsafe()) }, fut: unsafe { (self.f.get_mut_unsafe())(cfg, self.srv.get_mut_unsafe()) },
_t: PhantomData, _t: PhantomData,
} }
} }
} }
#[pin_project] pub struct ApplyConfigServiceResponse<R, S, E>
struct FnNewServiceConfigFut<R, S, E>
where where
R: Future<Output = Result<S, E>>, R: Future<Output = Result<S, E>>,
S: Service, S: Service,
{ {
#[pin]
fut: R, fut: R,
_t: PhantomData<(S,)>, _t: PhantomData<(S,)>,
} }
impl<R, S, E> Future for FnNewServiceConfigFut<R, S, E> impl<R, S, E> Unpin for ApplyConfigServiceResponse<R, S, E>
where where
R: Future<Output = Result<S, E>>, R: Future<Output = Result<S, E>> + Unpin,
S: Service,
{
}
impl<R, S, E> Future for ApplyConfigServiceResponse<R, S, E>
where
R: Future<Output = Result<S, E>> + Unpin,
S: Service, S: Service,
{ {
type Output = Result<S, E>; type Output = Result<S, E>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(Ok(ready!(self.project().fut.poll(cx))?.into_service())) Pin::new(&mut self.get_mut().fut).poll(cx)
} }
} }
/// Convert `Fn(&Config) -> Future<Service>` fn to NewService /// Convert `Fn(&Config) -> Future<Service>` fn to NewService
struct ApplyConfigNewService<F, C, T, R, S> pub struct ApplyConfigServiceFactory<F, C, T, R, S>
where where
C: Clone, C: Clone,
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
@ -154,7 +138,7 @@ where
_t: PhantomData<(C, R, S)>, _t: PhantomData<(C, R, S)>,
} }
impl<F, C, T, R, S> Clone for ApplyConfigNewService<F, C, T, R, S> impl<F, C, T, R, S> Clone for ApplyConfigServiceFactory<F, C, T, R, S>
where where
C: Clone, C: Clone,
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
@ -163,7 +147,7 @@ where
S: Service, S: Service,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
ApplyConfigNewService { Self {
f: self.f.clone(), f: self.f.clone(),
srv: self.srv.clone(), srv: self.srv.clone(),
_t: PhantomData, _t: PhantomData,
@ -171,13 +155,14 @@ where
} }
} }
impl<F, C, T, R, S> ServiceFactory for ApplyConfigNewService<F, C, T, R, S> impl<F, C, T, R, S> ServiceFactory for ApplyConfigServiceFactory<F, C, T, R, S>
where where
C: Clone, C: Clone,
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
T: ServiceFactory<Config = ()>, T: ServiceFactory<Config = ()>,
T::Future: Unpin,
T::InitError: From<T::Error>, T::InitError: From<T::Error>,
R: Future<Output = Result<S, T::InitError>>, R: Future<Output = Result<S, T::InitError>> + Unpin,
S: Service, S: Service,
{ {
type Config = C; type Config = C;
@ -187,10 +172,10 @@ where
type Service = S; type Service = S;
type InitError = T::InitError; type InitError = T::InitError;
type Future = ApplyConfigNewServiceFut<F, C, T, R, S>; type Future = ApplyConfigServiceFactoryResponse<F, C, T, R, S>;
fn new_service(&self, cfg: &C) -> Self::Future { fn new_service(&self, cfg: &C) -> Self::Future {
ApplyConfigNewServiceFut { ApplyConfigServiceFactoryResponse {
f: self.f.clone(), f: self.f.clone(),
cfg: cfg.clone(), cfg: cfg.clone(),
fut: None, fut: None,
@ -201,8 +186,7 @@ where
} }
} }
#[pin_project] pub struct ApplyConfigServiceFactoryResponse<F, C, T, R, S>
struct ApplyConfigNewServiceFut<F, C, T, R, S>
where where
C: Clone, C: Clone,
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
@ -214,45 +198,57 @@ where
cfg: C, cfg: C,
f: Cell<F>, f: Cell<F>,
srv: Option<T::Service>, srv: Option<T::Service>,
#[pin]
srv_fut: Option<T::Future>, srv_fut: Option<T::Future>,
#[pin]
fut: Option<R>, fut: Option<R>,
_t: PhantomData<(S,)>, _t: PhantomData<(S,)>,
} }
impl<F, C, T, R, S> Future for ApplyConfigNewServiceFut<F, C, T, R, S> impl<F, C, T, R, S> Unpin for ApplyConfigServiceFactoryResponse<F, C, T, R, S>
where where
C: Clone, C: Clone,
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
T: ServiceFactory<Config = ()>, T: ServiceFactory<Config = ()>,
T::Future: Unpin,
T::InitError: From<T::Error>, T::InitError: From<T::Error>,
R: Future<Output = Result<S, T::InitError>>, R: Future<Output = Result<S, T::InitError>> + Unpin,
S: Service,
{
}
impl<F, C, T, R, S> Future for ApplyConfigServiceFactoryResponse<F, C, T, R, S>
where
C: Clone,
F: FnMut(&C, &mut T::Service) -> R,
T: ServiceFactory<Config = ()>,
T::Future: Unpin,
T::InitError: From<T::Error>,
R: Future<Output = Result<S, T::InitError>> + Unpin,
S: Service, S: Service,
{ {
type Output = Result<S, T::InitError>; type Output = Result<S, T::InitError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut this = self.project(); let this = self.get_mut();
'poll: loop {
if let Some(fut) = this.srv_fut.as_mut().as_pin_mut() { loop {
match fut.poll(cx)? { if let Some(ref mut fut) = this.srv_fut {
match Pin::new(fut).poll(cx)? {
Poll::Pending => return Poll::Pending, Poll::Pending => return Poll::Pending,
Poll::Ready(srv) => { Poll::Ready(srv) => {
this.srv_fut.set(None); let _ = this.srv_fut.take();
*this.srv = Some(srv); this.srv = Some(srv);
continue 'poll; continue;
} }
} }
} }
if let Some(fut) = this.fut.as_mut().as_pin_mut() { if let Some(ref mut fut) = this.fut {
return Poll::Ready(Ok(ready!(fut.poll(cx))?.into_service())); return Pin::new(fut).poll(cx);
} else if let Some(ref mut srv) = this.srv { } else if let Some(ref mut srv) = this.srv {
match srv.poll_ready(cx)? { match srv.poll_ready(cx)? {
Poll::Ready(_) => { Poll::Ready(_) => {
this.fut.set(Some(this.f.get_mut()(&this.cfg, srv))); this.fut = Some(this.f.get_mut()(&this.cfg, srv));
continue 'poll; continue;
} }
Poll::Pending => return Poll::Pending, Poll::Pending => return Poll::Pending,
} }

View File

@ -4,72 +4,49 @@ use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use futures::future::{ok, Ready}; use futures::future::{ok, Ready};
use pin_project::pin_project;
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory}; use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
/// Create `ServiceFactory` for function that can act as a `Service` /// Create `ServiceFactory` for function that can act as a `Service`
pub fn service_fn<F, Fut, Req, Res, Err, Cfg>( pub fn service_fn<F, Fut, Req, Res, Err, Cfg>(
f: F, f: F,
) -> impl ServiceFactory<Config = Cfg, Request = Req, Response = Res, Error = Err, InitError = ()> ) -> FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
+ Clone
where where
F: FnMut(Req) -> Fut + Clone, F: FnMut(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
NewServiceFn::new(f) FnServiceFactory::new(f)
} }
pub fn service_fn2<F, Fut, Req, Res, Err>( pub fn service_fn2<F, Fut, Req, Res, Err>(f: F) -> FnService<F, Fut, Req, Res, Err>
f: F,
) -> impl Service<Request = Req, Response = Res, Error = Err>
where where
F: FnMut(Req) -> Fut, F: FnMut(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
ServiceFn::new(f) FnService::new(f)
} }
/// Create `ServiceFactory` for function that can produce services /// Create `ServiceFactory` for function that can produce services
pub fn factory_fn<S, F, Cfg, Fut, Err>( pub fn factory_fn<F, Cfg, Srv, Fut, Err>(f: F) -> FnServiceNoConfig<F, Cfg, Srv, Fut, Err>
f: F,
) -> impl ServiceFactory<
Config = Cfg,
Service = S,
Request = S::Request,
Response = S::Response,
Error = S::Error,
InitError = Err,
Future = Fut,
>
where where
S: Service, Srv: Service,
F: Fn() -> Fut, F: Fn() -> Fut,
Fut: Future<Output = Result<S, Err>>, Fut: Future<Output = Result<Srv, Err>>,
{ {
FnNewServiceNoConfig::new(f) FnServiceNoConfig::new(f)
} }
/// Create `ServiceFactory` for function that can produce services with configuration /// Create `ServiceFactory` for function that can produce services with configuration
pub fn factory_fn_cfg<F, Fut, Cfg, Srv, Err>( pub fn factory_fn_cfg<F, Fut, Cfg, Srv, Err>(f: F) -> FnServiceConfig<F, Fut, Cfg, Srv, Err>
f: F,
) -> impl ServiceFactory<
Config = Cfg,
Service = Srv,
Request = Srv::Request,
Response = Srv::Response,
Error = Srv::Error,
InitError = Err,
>
where where
F: Fn(&Cfg) -> Fut, F: Fn(&Cfg) -> Fut,
Fut: Future<Output = Result<Srv, Err>>, Fut: Future<Output = Result<Srv, Err>>,
Srv: Service, Srv: Service,
{ {
FnNewServiceConfig::new(f) FnServiceConfig::new(f)
} }
pub struct ServiceFn<F, Fut, Req, Res, Err> pub struct FnService<F, Fut, Req, Res, Err>
where where
F: FnMut(Req) -> Fut, F: FnMut(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
@ -78,27 +55,27 @@ where
_t: PhantomData<Req>, _t: PhantomData<Req>,
} }
impl<F, Fut, Req, Res, Err> ServiceFn<F, Fut, Req, Res, Err> impl<F, Fut, Req, Res, Err> FnService<F, Fut, Req, Res, Err>
where where
F: FnMut(Req) -> Fut, F: FnMut(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
pub(crate) fn new(f: F) -> Self { pub(crate) fn new(f: F) -> Self {
ServiceFn { f, _t: PhantomData } Self { f, _t: PhantomData }
} }
} }
impl<F, Fut, Req, Res, Err> Clone for ServiceFn<F, Fut, Req, Res, Err> impl<F, Fut, Req, Res, Err> Clone for FnService<F, Fut, Req, Res, Err>
where where
F: FnMut(Req) -> Fut + Clone, F: FnMut(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
ServiceFn::new(self.f.clone()) Self::new(self.f.clone())
} }
} }
impl<F, Fut, Req, Res, Err> Service for ServiceFn<F, Fut, Req, Res, Err> impl<F, Fut, Req, Res, Err> Service for FnService<F, Fut, Req, Res, Err>
where where
F: FnMut(Req) -> Fut, F: FnMut(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
@ -117,17 +94,17 @@ where
} }
} }
impl<F, Fut, Req, Res, Err> IntoService<ServiceFn<F, Fut, Req, Res, Err>> for F impl<F, Fut, Req, Res, Err> IntoService<FnService<F, Fut, Req, Res, Err>> for F
where where
F: FnMut(Req) -> Fut, F: FnMut(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
fn into_service(self) -> ServiceFn<F, Fut, Req, Res, Err> { fn into_service(self) -> FnService<F, Fut, Req, Res, Err> {
ServiceFn::new(self) FnService::new(self)
} }
} }
struct NewServiceFn<F, Fut, Req, Res, Err, Cfg> pub struct FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Fut, F: FnMut(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
@ -136,27 +113,27 @@ where
_t: PhantomData<(Req, Cfg)>, _t: PhantomData<(Req, Cfg)>,
} }
impl<F, Fut, Req, Res, Err, Cfg> NewServiceFn<F, Fut, Req, Res, Err, Cfg> impl<F, Fut, Req, Res, Err, Cfg> FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Fut + Clone, F: FnMut(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
fn new(f: F) -> Self { fn new(f: F) -> Self {
NewServiceFn { f, _t: PhantomData } FnServiceFactory { f, _t: PhantomData }
} }
} }
impl<F, Fut, Req, Res, Err, Cfg> Clone for NewServiceFn<F, Fut, Req, Res, Err, Cfg> impl<F, Fut, Req, Res, Err, Cfg> Clone for FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Fut + Clone, F: FnMut(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
NewServiceFn::new(self.f.clone()) Self::new(self.f.clone())
} }
} }
impl<F, Fut, Req, Res, Err, Cfg> ServiceFactory for NewServiceFn<F, Fut, Req, Res, Err, Cfg> impl<F, Fut, Req, Res, Err, Cfg> ServiceFactory for FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Fut + Clone, F: FnMut(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
@ -166,17 +143,17 @@ where
type Error = Err; type Error = Err;
type Config = Cfg; type Config = Cfg;
type Service = ServiceFn<F, Fut, Req, Res, Err>; type Service = FnService<F, Fut, Req, Res, Err>;
type InitError = (); type InitError = ();
type Future = Ready<Result<Self::Service, Self::InitError>>; type Future = Ready<Result<Self::Service, Self::InitError>>;
fn new_service(&self, _: &Cfg) -> Self::Future { fn new_service(&self, _: &Cfg) -> Self::Future {
ok(ServiceFn::new(self.f.clone())) ok(FnService::new(self.f.clone()))
} }
} }
/// Convert `Fn(&Config) -> Future<Service>` fn to NewService /// Convert `Fn(&Config) -> Future<Service>` fn to NewService
struct FnNewServiceConfig<F, Fut, Cfg, Srv, Err> pub struct FnServiceConfig<F, Fut, Cfg, Srv, Err>
where where
F: Fn(&Cfg) -> Fut, F: Fn(&Cfg) -> Fut,
Fut: Future<Output = Result<Srv, Err>>, Fut: Future<Output = Result<Srv, Err>>,
@ -186,21 +163,21 @@ where
_t: PhantomData<(Fut, Cfg, Srv, Err)>, _t: PhantomData<(Fut, Cfg, Srv, Err)>,
} }
impl<F, Fut, Cfg, Srv, Err> FnNewServiceConfig<F, Fut, Cfg, Srv, Err> impl<F, Fut, Cfg, Srv, Err> FnServiceConfig<F, Fut, Cfg, Srv, Err>
where where
F: Fn(&Cfg) -> Fut, F: Fn(&Cfg) -> Fut,
Fut: Future<Output = Result<Srv, Err>>, Fut: Future<Output = Result<Srv, Err>>,
Srv: Service, Srv: Service,
{ {
pub fn new(f: F) -> Self { fn new(f: F) -> Self {
FnNewServiceConfig { f, _t: PhantomData } FnServiceConfig { f, _t: PhantomData }
} }
} }
impl<F, Fut, Cfg, Srv, Err> ServiceFactory for FnNewServiceConfig<F, Fut, Cfg, Srv, Err> impl<F, Fut, Cfg, Srv, Err> ServiceFactory for FnServiceConfig<F, Fut, Cfg, Srv, Err>
where where
F: Fn(&Cfg) -> Fut, F: Fn(&Cfg) -> Fut,
Fut: Future<Output = Result<Srv, Err>>, Fut: Future<Output = Result<Srv, Err>> + Unpin,
Srv: Service, Srv: Service,
{ {
type Request = Srv::Request; type Request = Srv::Request;
@ -210,62 +187,67 @@ where
type Config = Cfg; type Config = Cfg;
type Service = Srv; type Service = Srv;
type InitError = Err; type InitError = Err;
type Future = FnNewServiceConfigFut<Fut, Srv, Err>; type Future = NewServiceFnConfigFut<Fut, Srv, Err>;
fn new_service(&self, cfg: &Cfg) -> Self::Future { fn new_service(&self, cfg: &Cfg) -> Self::Future {
FnNewServiceConfigFut { NewServiceFnConfigFut {
fut: (self.f)(cfg), fut: (self.f)(cfg),
_t: PhantomData, _t: PhantomData,
} }
} }
} }
#[pin_project] pub struct NewServiceFnConfigFut<R, S, E>
struct FnNewServiceConfigFut<R, S, E>
where where
R: Future<Output = Result<S, E>>, R: Future<Output = Result<S, E>> + Unpin,
S: Service, S: Service,
{ {
#[pin]
fut: R, fut: R,
_t: PhantomData<(S,)>, _t: PhantomData<(S,)>,
} }
impl<R, S, E> Future for FnNewServiceConfigFut<R, S, E> impl<R, S, E> Unpin for NewServiceFnConfigFut<R, S, E>
where where
R: Future<Output = Result<S, E>>, R: Future<Output = Result<S, E>> + Unpin,
S: Service,
{
}
impl<R, S, E> Future for NewServiceFnConfigFut<R, S, E>
where
R: Future<Output = Result<S, E>> + Unpin,
S: Service, S: Service,
{ {
type Output = Result<S, E>; type Output = Result<S, E>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(Ok(futures::ready!(self.project().fut.poll(cx))?)) Pin::new(&mut self.get_mut().fut).poll(cx)
} }
} }
/// Converter for `Fn() -> Future<Service>` fn /// Converter for `Fn() -> Future<Service>` fn
pub struct FnNewServiceNoConfig<F, C, R, S, E> pub struct FnServiceNoConfig<F, C, S, R, E>
where where
F: Fn() -> R, F: Fn() -> R,
R: Future<Output = Result<S, E>>,
S: Service, S: Service,
R: Future<Output = Result<S, E>>,
{ {
f: F, f: F,
_t: PhantomData<C>, _t: PhantomData<C>,
} }
impl<F, C, R, S, E> FnNewServiceNoConfig<F, C, R, S, E> impl<F, C, S, R, E> FnServiceNoConfig<F, C, S, R, E>
where where
F: Fn() -> R, F: Fn() -> R,
R: Future<Output = Result<S, E>>, R: Future<Output = Result<S, E>>,
S: Service, S: Service,
{ {
fn new(f: F) -> Self { fn new(f: F) -> Self {
FnNewServiceNoConfig { f, _t: PhantomData } Self { f, _t: PhantomData }
} }
} }
impl<F, C, R, S, E> ServiceFactory for FnNewServiceNoConfig<F, C, R, S, E> impl<F, C, S, R, E> ServiceFactory for FnServiceNoConfig<F, C, S, R, E>
where where
F: Fn() -> R, F: Fn() -> R,
R: Future<Output = Result<S, E>>, R: Future<Output = Result<S, E>>,
@ -284,7 +266,7 @@ where
} }
} }
impl<F, C, R, S, E> Clone for FnNewServiceNoConfig<F, C, R, S, E> impl<F, C, S, R, E> Clone for FnServiceNoConfig<F, C, S, R, E>
where where
F: Fn() -> R + Clone, F: Fn() -> R + Clone,
R: Future<Output = Result<S, E>>, R: Future<Output = Result<S, E>>,
@ -295,13 +277,13 @@ where
} }
} }
impl<F, C, R, S, E> IntoServiceFactory<FnNewServiceNoConfig<F, C, R, S, E>> for F impl<F, C, S, R, E> IntoServiceFactory<FnServiceNoConfig<F, C, S, R, E>> for F
where where
F: Fn() -> R, F: Fn() -> R,
R: Future<Output = Result<S, E>>, R: Future<Output = Result<S, E>>,
S: Service, S: Service,
{ {
fn into_factory(self) -> FnNewServiceNoConfig<F, C, R, S, E> { fn into_factory(self) -> FnServiceNoConfig<F, C, S, R, E> {
FnNewServiceNoConfig::new(self) FnServiceNoConfig::new(self)
} }
} }

View File

@ -1,204 +0,0 @@
use std::task::{Context, Poll};
use crate::map::{Map, MapNewService};
use crate::map_err::{MapErr, MapErrNewService};
use crate::map_init_err::MapInitErr;
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
#[inline]
/// Convert object of type `U` to a service `T`
pub fn into_service<T, U>(service: U) -> ServiceMapper<T>
where
U: IntoService<T>,
T: Service,
{
ServiceMapper {
service: service.into_service(),
}
}
pub fn into_factory<T, F>(factory: F) -> ServiceFactoryMapper<T>
where
T: ServiceFactory,
F: IntoServiceFactory<T>,
{
ServiceFactoryMapper {
factory: factory.into_factory(),
}
}
pub struct ServiceMapper<T> {
service: T,
}
pub struct ServiceFactoryMapper<T> {
factory: T,
}
impl<T: Service> ServiceMapper<T> {
/// Map this service's output to a different type, returning a new service
/// of the resulting type.
///
/// This function is similar to the `Option::map` or `Iterator::map` where
/// it will change the type of the underlying service.
///
/// Note that this function consumes the receiving service and returns a
/// wrapped version of it, similar to the existing `map` methods in the
/// standard library.
pub fn map<F, R>(
self,
f: F,
) -> ServiceMapper<impl Service<Request = T::Request, Response = R, Error = T::Error>>
where
Self: Sized,
F: FnMut(T::Response) -> R + Clone,
{
ServiceMapper {
service: Map::new(self.service, f),
}
}
/// Map this service's error to a different error, returning a new service.
///
/// This function is similar to the `Result::map_err` where it will change
/// the error type of the underlying service. This is useful for example to
/// ensure that services have the same error type.
///
/// Note that this function consumes the receiving service and returns a
/// wrapped version of it.
pub fn map_err<F, E>(
self,
f: F,
) -> ServiceMapper<impl Service<Request = T::Request, Response = T::Response, Error = E>>
where
Self: Sized,
F: Fn(T::Error) -> E + Clone,
{
ServiceMapper {
service: MapErr::new(self, f),
}
}
}
impl<T> Clone for ServiceMapper<T>
where
T: Clone,
{
fn clone(&self) -> Self {
ServiceMapper {
service: self.service.clone(),
}
}
}
impl<T: Service> Service for ServiceMapper<T> {
type Request = T::Request;
type Response = T::Response;
type Error = T::Error;
type Future = T::Future;
#[inline]
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.service.poll_ready(ctx)
}
#[inline]
fn call(&mut self, req: T::Request) -> Self::Future {
self.service.call(req)
}
}
impl<T: ServiceFactory> ServiceFactoryMapper<T> {
/// Map this service's output to a different type, returning a new service
/// of the resulting type.
pub fn map<F, R>(
self,
f: F,
) -> ServiceFactoryMapper<
impl ServiceFactory<
Config = T::Config,
Request = T::Request,
Response = R,
Error = T::Error,
InitError = T::InitError,
>,
>
where
Self: Sized,
F: FnMut(T::Response) -> R + Clone,
{
ServiceFactoryMapper {
factory: MapNewService::new(self.factory, f),
}
}
/// Map this service's error to a different error, returning a new service.
pub fn map_err<F, E>(
self,
f: F,
) -> ServiceFactoryMapper<
impl ServiceFactory<
Config = T::Config,
Request = T::Request,
Response = T::Response,
Error = E,
InitError = T::InitError,
>,
>
where
Self: Sized,
F: Fn(T::Error) -> E + Clone,
{
ServiceFactoryMapper {
factory: MapErrNewService::new(self.factory, f),
}
}
/// Map this factory's init error to a different error, returning a new service.
pub fn map_init_err<F, E>(
self,
f: F,
) -> ServiceFactoryMapper<
impl ServiceFactory<
Config = T::Config,
Request = T::Request,
Response = T::Response,
Error = T::Error,
InitError = E,
>,
>
where
Self: Sized,
F: Fn(T::InitError) -> E + Clone,
{
ServiceFactoryMapper {
factory: MapInitErr::new(self.factory, f),
}
}
}
impl<T> Clone for ServiceFactoryMapper<T>
where
T: Clone,
{
fn clone(&self) -> Self {
ServiceFactoryMapper {
factory: self.factory.clone(),
}
}
}
impl<T: ServiceFactory> ServiceFactory for ServiceFactoryMapper<T> {
type Config = T::Config;
type Request = T::Request;
type Response = T::Response;
type Error = T::Error;
type Service = T::Service;
type InitError = T::InitError;
type Future = T::Future;
#[inline]
fn new_service(&self, cfg: &T::Config) -> Self::Future {
self.factory.new_service(cfg)
}
}

View File

@ -10,7 +10,6 @@ mod apply_cfg;
pub mod boxed; pub mod boxed;
mod cell; mod cell;
mod fn_service; mod fn_service;
mod into;
mod map; mod map;
mod map_config; mod map_config;
mod map_err; mod map_err;
@ -18,12 +17,10 @@ mod map_init_err;
mod pipeline; mod pipeline;
mod then; mod then;
mod transform; mod transform;
mod transform_err;
pub use self::apply::{apply_fn, apply_fn_factory}; pub use self::apply::{apply_fn, apply_fn_factory};
pub use self::apply_cfg::{apply_cfg, apply_cfg_factory}; pub use self::apply_cfg::{apply_cfg, apply_cfg_factory};
pub use self::fn_service::{factory_fn, factory_fn_cfg, service_fn, service_fn2}; pub use self::fn_service::{factory_fn, factory_fn_cfg, service_fn, service_fn2};
pub use self::into::{into_factory, into_service, ServiceFactoryMapper, ServiceMapper};
pub use self::map_config::{map_config, unit_config, MappedConfig}; pub use self::map_config::{map_config, unit_config, MappedConfig};
pub use self::pipeline::{pipeline, pipeline_factory, Pipeline, PipelineFactory}; pub use self::pipeline::{pipeline, pipeline_factory, Pipeline, PipelineFactory};
pub use self::transform::{apply, Transform}; pub use self::transform::{apply, Transform};
@ -63,6 +60,41 @@ pub trait Service {
/// Calling `call` without calling `poll_ready` is permitted. The /// Calling `call` without calling `poll_ready` is permitted. The
/// implementation must be resilient to this fact. /// implementation must be resilient to this fact.
fn call(&mut self, req: Self::Request) -> Self::Future; fn call(&mut self, req: Self::Request) -> Self::Future;
/// Map this service's output to a different type, returning a new service
/// of the resulting type.
///
/// This function is similar to the `Option::map` or `Iterator::map` where
/// it will change the type of the underlying service.
///
/// Note that this function consumes the receiving service and returns a
/// wrapped version of it, similar to the existing `map` methods in the
/// standard library.
fn map<F, R>(self, f: F) -> crate::dev::Map<Self, F, R>
where
Self: Sized,
Self::Future: Unpin,
F: FnMut(Self::Response) -> R + Unpin,
{
crate::dev::Map::new(self, f)
}
/// Map this service's error to a different error, returning a new service.
///
/// This function is similar to the `Result::map_err` where it will change
/// the error type of the underlying service. This is useful for example to
/// ensure that services have the same error type.
///
/// Note that this function consumes the receiving service and returns a
/// wrapped version of it.
fn map_err<F, E>(self, f: F) -> crate::dev::MapErr<Self, F, E>
where
Self: Sized,
Self::Future: Unpin,
F: Fn(Self::Error) -> E,
{
crate::dev::MapErr::new(self, f)
}
} }
/// Creates new `Service` values. /// Creates new `Service` values.
@ -102,6 +134,37 @@ pub trait ServiceFactory {
/// Create and return a new service value asynchronously. /// Create and return a new service value asynchronously.
fn new_service(&self, cfg: &Self::Config) -> Self::Future; fn new_service(&self, cfg: &Self::Config) -> Self::Future;
/// Map this service's output to a different type, returning a new service
/// of the resulting type.
fn map<F, R>(self, f: F) -> crate::map::MapServiceFactory<Self, F, R>
where
Self: Sized,
<Self::Service as Service>::Future: Unpin,
F: FnMut(Self::Response) -> R + Unpin + Clone,
{
crate::map::MapServiceFactory::new(self, f)
}
/// Map this service's error to a different error, returning a new service.
fn map_err<F, E>(self, f: F) -> crate::map_err::MapErrServiceFactory<Self, F, E>
where
Self: Sized,
<Self::Service as Service>::Future: Unpin,
F: Fn(Self::Error) -> E + Unpin + Clone,
{
crate::map_err::MapErrServiceFactory::new(self, f)
}
/// Map this factory's init error to a different error, returning a new service.
fn map_init_err<F, E>(self, f: F) -> crate::map_init_err::MapInitErr<Self, F, E>
where
Self: Sized,
<Self::Service as Service>::Future: Unpin,
F: Fn(Self::InitError) -> E + Unpin + Clone,
{
crate::map_init_err::MapInitErr::new(self, f)
}
} }
impl<'a, S> Service for &'a mut S impl<'a, S> Service for &'a mut S
@ -227,3 +290,17 @@ where
self self
} }
} }
pub mod dev {
pub use crate::and_then::{AndThenService, AndThenServiceFactory};
pub use crate::apply::{Apply, ApplyServiceFactory};
pub use crate::apply_cfg::{ApplyConfigService, ApplyConfigServiceFactory};
pub use crate::fn_service::{
FnService, FnServiceConfig, FnServiceFactory, FnServiceNoConfig,
};
pub use crate::map::{Map, MapServiceFactory};
pub use crate::map_err::{MapErr, MapErrServiceFactory};
pub use crate::map_init_err::MapInitErr;
pub use crate::then::{ThenService, ThenServiceFactory};
pub use crate::transform::{ApplyTransform, TransformMapInitErr};
}

View File

@ -3,14 +3,12 @@ use std::marker::PhantomData;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use pin_project::pin_project;
use super::{Service, ServiceFactory}; use super::{Service, ServiceFactory};
/// Service for the `map` combinator, changing the type of a service's response. /// Service for the `map` combinator, changing the type of a service's response.
/// ///
/// This is created by the `ServiceExt::map` method. /// This is created by the `ServiceExt::map` method.
pub(crate) struct Map<A, F, Response> { pub struct Map<A, F, Response> {
service: A, service: A,
f: F, f: F,
_t: PhantomData<Response>, _t: PhantomData<Response>,
@ -18,7 +16,7 @@ pub(crate) struct Map<A, F, Response> {
impl<A, F, Response> Map<A, F, Response> { impl<A, F, Response> Map<A, F, Response> {
/// Create new `Map` combinator /// Create new `Map` combinator
pub fn new(service: A, f: F) -> Self pub(crate) fn new(service: A, f: F) -> Self
where where
A: Service, A: Service,
F: FnMut(A::Response) -> Response, F: FnMut(A::Response) -> Response,
@ -48,7 +46,8 @@ where
impl<A, F, Response> Service for Map<A, F, Response> impl<A, F, Response> Service for Map<A, F, Response>
where where
A: Service, A: Service,
F: FnMut(A::Response) -> Response + Clone, A::Future: Unpin,
F: FnMut(A::Response) -> Response + Unpin + Clone,
{ {
type Request = A::Request; type Request = A::Request;
type Response = Response; type Response = Response;
@ -64,14 +63,12 @@ where
} }
} }
#[pin_project] pub struct MapFuture<A, F, Response>
pub(crate) struct MapFuture<A, F, Response>
where where
A: Service, A: Service,
F: FnMut(A::Response) -> Response, F: FnMut(A::Response) -> Response,
{ {
f: F, f: F,
#[pin]
fut: A::Future, fut: A::Future,
} }
@ -88,13 +85,15 @@ where
impl<A, F, Response> Future for MapFuture<A, F, Response> impl<A, F, Response> Future for MapFuture<A, F, Response>
where where
A: Service, A: Service,
F: FnMut(A::Response) -> Response, A::Future: Unpin,
F: FnMut(A::Response) -> Response + Unpin,
{ {
type Output = Result<Response, A::Error>; type Output = Result<Response, A::Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project(); let this = self.get_mut();
match this.fut.poll(cx) {
match Pin::new(&mut this.fut).poll(cx) {
Poll::Ready(Ok(resp)) => Poll::Ready(Ok((this.f)(resp))), Poll::Ready(Ok(resp)) => Poll::Ready(Ok((this.f)(resp))),
Poll::Ready(Err(e)) => Poll::Ready(Err(e)), Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
Poll::Pending => Poll::Pending, Poll::Pending => Poll::Pending,
@ -103,18 +102,18 @@ where
} }
/// `MapNewService` new service combinator /// `MapNewService` new service combinator
pub(crate) struct MapNewService<A, F, Res> { pub struct MapServiceFactory<A, F, Res> {
a: A, a: A,
f: F, f: F,
r: PhantomData<Res>, r: PhantomData<Res>,
} }
impl<A, F, Res> MapNewService<A, F, Res> { impl<A, F, Res> MapServiceFactory<A, F, Res> {
/// Create new `Map` new service instance /// Create new `Map` new service instance
pub fn new(a: A, f: F) -> Self pub(crate) fn new(a: A, f: F) -> Self
where where
A: ServiceFactory, A: ServiceFactory,
F: FnMut(A::Response) -> Res, F: FnMut(A::Response) -> Res + Unpin,
{ {
Self { Self {
a, a,
@ -124,7 +123,7 @@ impl<A, F, Res> MapNewService<A, F, Res> {
} }
} }
impl<A, F, Res> Clone for MapNewService<A, F, Res> impl<A, F, Res> Clone for MapServiceFactory<A, F, Res>
where where
A: Clone, A: Clone,
F: Clone, F: Clone,
@ -138,10 +137,12 @@ where
} }
} }
impl<A, F, Res> ServiceFactory for MapNewService<A, F, Res> impl<A, F, Res> ServiceFactory for MapServiceFactory<A, F, Res>
where where
A: ServiceFactory, A: ServiceFactory,
F: FnMut(A::Response) -> Res + Clone, A::Future: Unpin,
<A::Service as Service>::Future: Unpin,
F: FnMut(A::Response) -> Res + Unpin + Clone,
{ {
type Request = A::Request; type Request = A::Request;
type Response = Res; type Response = Res;
@ -150,44 +151,44 @@ where
type Config = A::Config; type Config = A::Config;
type Service = Map<A::Service, F, Res>; type Service = Map<A::Service, F, Res>;
type InitError = A::InitError; type InitError = A::InitError;
type Future = MapNewServiceFuture<A, F, Res>; type Future = MapServiceFuture<A, F, Res>;
fn new_service(&self, cfg: &A::Config) -> Self::Future { fn new_service(&self, cfg: &A::Config) -> Self::Future {
MapNewServiceFuture::new(self.a.new_service(cfg), self.f.clone()) MapServiceFuture::new(self.a.new_service(cfg), self.f.clone())
} }
} }
#[pin_project] pub struct MapServiceFuture<A, F, Res>
pub(crate) struct MapNewServiceFuture<A, F, Res>
where where
A: ServiceFactory, A: ServiceFactory,
F: FnMut(A::Response) -> Res, F: FnMut(A::Response) -> Res,
{ {
#[pin]
fut: A::Future, fut: A::Future,
f: Option<F>, f: Option<F>,
} }
impl<A, F, Res> MapNewServiceFuture<A, F, Res> impl<A, F, Res> MapServiceFuture<A, F, Res>
where where
A: ServiceFactory, A: ServiceFactory,
F: FnMut(A::Response) -> Res, F: FnMut(A::Response) -> Res + Unpin,
{ {
fn new(fut: A::Future, f: F) -> Self { fn new(fut: A::Future, f: F) -> Self {
MapNewServiceFuture { f: Some(f), fut } MapServiceFuture { f: Some(f), fut }
} }
} }
impl<A, F, Res> Future for MapNewServiceFuture<A, F, Res> impl<A, F, Res> Future for MapServiceFuture<A, F, Res>
where where
A: ServiceFactory, A: ServiceFactory,
F: FnMut(A::Response) -> Res, A::Future: Unpin,
F: FnMut(A::Response) -> Res + Unpin,
{ {
type Output = Result<Map<A::Service, F, Res>, A::InitError>; type Output = Result<Map<A::Service, F, Res>, A::InitError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project(); let this = self.get_mut();
if let Poll::Ready(svc) = this.fut.poll(cx)? {
if let Poll::Ready(svc) = Pin::new(&mut this.fut).poll(cx)? {
Poll::Ready(Ok(Map::new(svc, this.f.take().unwrap()))) Poll::Ready(Ok(Map::new(svc, this.f.take().unwrap())))
} else { } else {
Poll::Pending Poll::Pending
@ -200,7 +201,7 @@ mod tests {
use futures::future::{lazy, ok, Ready}; use futures::future::{lazy, ok, Ready};
use super::*; use super::*;
use crate::{into_factory, into_service, Service}; use crate::{IntoServiceFactory, Service, ServiceFactory};
struct Srv; struct Srv;
@ -221,14 +222,14 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_poll_ready() { async fn test_poll_ready() {
let mut srv = into_service(Srv).map(|_| "ok"); let mut srv = Srv.map(|_| "ok");
let res = lazy(|cx| srv.poll_ready(cx)).await; let res = lazy(|cx| srv.poll_ready(cx)).await;
assert_eq!(res, Poll::Ready(Ok(()))); assert_eq!(res, Poll::Ready(Ok(())));
} }
#[tokio::test] #[tokio::test]
async fn test_call() { async fn test_call() {
let mut srv = into_service(Srv).map(|_| "ok"); let mut srv = Srv.map(|_| "ok");
let res = srv.call(()).await; let res = srv.call(()).await;
assert!(res.is_ok()); assert!(res.is_ok());
assert_eq!(res.unwrap(), "ok"); assert_eq!(res.unwrap(), "ok");
@ -236,7 +237,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_new_service() { async fn test_new_service() {
let new_srv = into_factory(|| ok::<_, ()>(Srv)).map(|_| "ok"); let new_srv = (|| ok::<_, ()>(Srv)).into_factory().map(|_| "ok");
let mut srv = new_srv.new_service(&()).await.unwrap(); let mut srv = new_srv.new_service(&()).await.unwrap();
let res = srv.call(()).await; let res = srv.call(()).await;
assert!(res.is_ok()); assert!(res.is_ok());

View File

@ -3,15 +3,13 @@ use std::marker::PhantomData;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use pin_project::pin_project;
use super::{Service, ServiceFactory}; use super::{Service, ServiceFactory};
/// Service for the `map_err` combinator, changing the type of a service's /// Service for the `map_err` combinator, changing the type of a service's
/// error. /// error.
/// ///
/// This is created by the `ServiceExt::map_err` method. /// This is created by the `ServiceExt::map_err` method.
pub(crate) struct MapErr<A, F, E> { pub struct MapErr<A, F, E> {
service: A, service: A,
f: F, f: F,
_t: PhantomData<E>, _t: PhantomData<E>,
@ -19,7 +17,7 @@ pub(crate) struct MapErr<A, F, E> {
impl<A, F, E> MapErr<A, F, E> { impl<A, F, E> MapErr<A, F, E> {
/// Create new `MapErr` combinator /// Create new `MapErr` combinator
pub fn new(service: A, f: F) -> Self pub(crate) fn new(service: A, f: F) -> Self
where where
A: Service, A: Service,
F: Fn(A::Error) -> E, F: Fn(A::Error) -> E,
@ -49,7 +47,8 @@ where
impl<A, F, E> Service for MapErr<A, F, E> impl<A, F, E> Service for MapErr<A, F, E>
where where
A: Service, A: Service,
F: Fn(A::Error) -> E + Clone, A::Future: Unpin,
F: Fn(A::Error) -> E + Unpin + Clone,
{ {
type Request = A::Request; type Request = A::Request;
type Response = A::Response; type Response = A::Response;
@ -65,21 +64,21 @@ where
} }
} }
#[pin_project] pub struct MapErrFuture<A, F, E>
pub(crate) struct MapErrFuture<A, F, E>
where where
A: Service, A: Service,
F: Fn(A::Error) -> E, A::Future: Unpin,
F: Fn(A::Error) -> E + Unpin,
{ {
f: F, f: F,
#[pin]
fut: A::Future, fut: A::Future,
} }
impl<A, F, E> MapErrFuture<A, F, E> impl<A, F, E> MapErrFuture<A, F, E>
where where
A: Service, A: Service,
F: Fn(A::Error) -> E, A::Future: Unpin,
F: Fn(A::Error) -> E + Unpin,
{ {
fn new(fut: A::Future, f: F) -> Self { fn new(fut: A::Future, f: F) -> Self {
MapErrFuture { f, fut } MapErrFuture { f, fut }
@ -89,13 +88,14 @@ where
impl<A, F, E> Future for MapErrFuture<A, F, E> impl<A, F, E> Future for MapErrFuture<A, F, E>
where where
A: Service, A: Service,
F: Fn(A::Error) -> E, A::Future: Unpin,
F: Fn(A::Error) -> E + Unpin,
{ {
type Output = Result<A::Response, E>; type Output = Result<A::Response, E>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project(); let this = self.get_mut();
this.fut.poll(cx).map_err(this.f) Pin::new(&mut this.fut).poll(cx).map_err(&this.f)
} }
} }
@ -103,7 +103,7 @@ where
/// service's error. /// service's error.
/// ///
/// This is created by the `NewServiceExt::map_err` method. /// This is created by the `NewServiceExt::map_err` method.
pub(crate) struct MapErrNewService<A, F, E> pub struct MapErrServiceFactory<A, F, E>
where where
A: ServiceFactory, A: ServiceFactory,
F: Fn(A::Error) -> E + Clone, F: Fn(A::Error) -> E + Clone,
@ -113,7 +113,7 @@ where
e: PhantomData<E>, e: PhantomData<E>,
} }
impl<A, F, E> MapErrNewService<A, F, E> impl<A, F, E> MapErrServiceFactory<A, F, E>
where where
A: ServiceFactory, A: ServiceFactory,
F: Fn(A::Error) -> E + Clone, F: Fn(A::Error) -> E + Clone,
@ -128,7 +128,7 @@ where
} }
} }
impl<A, F, E> Clone for MapErrNewService<A, F, E> impl<A, F, E> Clone for MapErrServiceFactory<A, F, E>
where where
A: ServiceFactory + Clone, A: ServiceFactory + Clone,
F: Fn(A::Error) -> E + Clone, F: Fn(A::Error) -> E + Clone,
@ -142,10 +142,12 @@ where
} }
} }
impl<A, F, E> ServiceFactory for MapErrNewService<A, F, E> impl<A, F, E> ServiceFactory for MapErrServiceFactory<A, F, E>
where where
A: ServiceFactory, A: ServiceFactory,
F: Fn(A::Error) -> E + Clone, A::Future: Unpin,
<A::Service as Service>::Future: Unpin,
F: Fn(A::Error) -> E + Unpin + Clone,
{ {
type Request = A::Request; type Request = A::Request;
type Response = A::Response; type Response = A::Response;
@ -154,44 +156,43 @@ where
type Config = A::Config; type Config = A::Config;
type Service = MapErr<A::Service, F, E>; type Service = MapErr<A::Service, F, E>;
type InitError = A::InitError; type InitError = A::InitError;
type Future = MapErrNewServiceFuture<A, F, E>; type Future = MapErrServiceFuture<A, F, E>;
fn new_service(&self, cfg: &A::Config) -> Self::Future { fn new_service(&self, cfg: &A::Config) -> Self::Future {
MapErrNewServiceFuture::new(self.a.new_service(cfg), self.f.clone()) MapErrServiceFuture::new(self.a.new_service(cfg), self.f.clone())
} }
} }
#[pin_project] pub struct MapErrServiceFuture<A, F, E>
pub(crate) struct MapErrNewServiceFuture<A, F, E>
where where
A: ServiceFactory, A: ServiceFactory,
F: Fn(A::Error) -> E, F: Fn(A::Error) -> E,
{ {
#[pin]
fut: A::Future, fut: A::Future,
f: F, f: F,
} }
impl<A, F, E> MapErrNewServiceFuture<A, F, E> impl<A, F, E> MapErrServiceFuture<A, F, E>
where where
A: ServiceFactory, A: ServiceFactory,
F: Fn(A::Error) -> E, F: Fn(A::Error) -> E,
{ {
fn new(fut: A::Future, f: F) -> Self { fn new(fut: A::Future, f: F) -> Self {
MapErrNewServiceFuture { f, fut } MapErrServiceFuture { f, fut }
} }
} }
impl<A, F, E> Future for MapErrNewServiceFuture<A, F, E> impl<A, F, E> Future for MapErrServiceFuture<A, F, E>
where where
A: ServiceFactory, A: ServiceFactory,
F: Fn(A::Error) -> E + Clone, A::Future: Unpin,
F: Fn(A::Error) -> E + Unpin + Clone,
{ {
type Output = Result<MapErr<A::Service, F, E>, A::InitError>; type Output = Result<MapErr<A::Service, F, E>, A::InitError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project(); let this = self.get_mut();
if let Poll::Ready(svc) = this.fut.poll(cx)? { if let Poll::Ready(svc) = Pin::new(&mut this.fut).poll(cx)? {
Poll::Ready(Ok(MapErr::new(svc, this.f.clone()))) Poll::Ready(Ok(MapErr::new(svc, this.f.clone())))
} else { } else {
Poll::Pending Poll::Pending
@ -204,7 +205,7 @@ mod tests {
use futures::future::{err, lazy, ok, Ready}; use futures::future::{err, lazy, ok, Ready};
use super::*; use super::*;
use crate::{into_factory, into_service, Service}; use crate::{IntoServiceFactory, Service, ServiceFactory};
struct Srv; struct Srv;
@ -225,14 +226,14 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_poll_ready() { async fn test_poll_ready() {
let mut srv = into_service(Srv).map_err(|_| "error"); let mut srv = Srv.map_err(|_| "error");
let res = lazy(|cx| srv.poll_ready(cx)).await; let res = lazy(|cx| srv.poll_ready(cx)).await;
assert_eq!(res, Poll::Ready(Err("error"))); assert_eq!(res, Poll::Ready(Err("error")));
} }
#[tokio::test] #[tokio::test]
async fn test_call() { async fn test_call() {
let mut srv = into_service(Srv).map_err(|_| "error"); let mut srv = Srv.map_err(|_| "error");
let res = srv.call(()).await; let res = srv.call(()).await;
assert!(res.is_err()); assert!(res.is_err());
assert_eq!(res.err().unwrap(), "error"); assert_eq!(res.err().unwrap(), "error");
@ -240,7 +241,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_new_service() { async fn test_new_service() {
let new_srv = into_factory(|| ok::<_, ()>(Srv)).map_err(|_| "error"); let new_srv = (|| ok::<_, ()>(Srv)).into_factory().map_err(|_| "error");
let mut srv = new_srv.new_service(&()).await.unwrap(); let mut srv = new_srv.new_service(&()).await.unwrap();
let res = srv.call(()).await; let res = srv.call(()).await;
assert!(res.is_err()); assert!(res.is_err());

View File

@ -3,12 +3,10 @@ use std::marker::PhantomData;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use pin_project::pin_project;
use super::ServiceFactory; use super::ServiceFactory;
/// `MapInitErr` service combinator /// `MapInitErr` service combinator
pub(crate) struct MapInitErr<A, F, E> { pub struct MapInitErr<A, F, E> {
a: A, a: A,
f: F, f: F,
e: PhantomData<E>, e: PhantomData<E>,
@ -46,7 +44,8 @@ where
impl<A, F, E> ServiceFactory for MapInitErr<A, F, E> impl<A, F, E> ServiceFactory for MapInitErr<A, F, E>
where where
A: ServiceFactory, A: ServiceFactory,
F: Fn(A::InitError) -> E + Clone, A::Future: Unpin,
F: Fn(A::InitError) -> E + Unpin + Clone,
{ {
type Request = A::Request; type Request = A::Request;
type Response = A::Response; type Response = A::Response;
@ -61,14 +60,13 @@ where
MapInitErrFuture::new(self.a.new_service(cfg), self.f.clone()) MapInitErrFuture::new(self.a.new_service(cfg), self.f.clone())
} }
} }
#[pin_project]
pub(crate) struct MapInitErrFuture<A, F, E> pub struct MapInitErrFuture<A, F, E>
where where
A: ServiceFactory, A: ServiceFactory,
F: Fn(A::InitError) -> E, F: Fn(A::InitError) -> E,
{ {
f: F, f: F,
#[pin]
fut: A::Future, fut: A::Future,
} }
@ -85,12 +83,13 @@ where
impl<A, F, E> Future for MapInitErrFuture<A, F, E> impl<A, F, E> Future for MapInitErrFuture<A, F, E>
where where
A: ServiceFactory, A: ServiceFactory,
F: Fn(A::InitError) -> E, A::Future: Unpin,
F: Fn(A::InitError) -> E + Unpin,
{ {
type Output = Result<A::Service, E>; type Output = Result<A::Service, E>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project(); let this = self.get_mut();
this.fut.poll(cx).map_err(this.f) Pin::new(&mut this.fut).poll(cx).map_err(&this.f)
} }
} }

View File

@ -1,7 +1,7 @@
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use crate::and_then::{AndThen, AndThenNewService}; use crate::and_then::{AndThenService, AndThenServiceFactory};
use crate::then::{Then, ThenNewService}; use crate::then::{ThenService, ThenServiceFactory};
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory}; use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
pub fn pipeline<F, T>(service: F) -> Pipeline<T> pub fn pipeline<F, T>(service: F) -> Pipeline<T>
@ -39,17 +39,14 @@ impl<T: Service> Pipeline<T> {
/// ///
/// Note that this function consumes the receiving service and returns a /// Note that this function consumes the receiving service and returns a
/// wrapped version of it. /// wrapped version of it.
pub fn and_then<F, U>( pub fn and_then<F, U>(self, service: F) -> Pipeline<AndThenService<T, U>>
self,
service: F,
) -> Pipeline<impl Service<Request = T::Request, Response = U::Response, Error = T::Error>>
where where
Self: Sized, Self: Sized,
F: IntoService<U>, F: IntoService<U>,
U: Service<Request = T::Response, Error = T::Error>, U: Service<Request = T::Response, Error = T::Error> + Unpin,
{ {
Pipeline { Pipeline {
service: AndThen::new(self.service, service.into_service()), service: AndThenService::new(self.service, service.into_service()),
} }
} }
@ -58,17 +55,14 @@ impl<T: Service> Pipeline<T> {
/// ///
/// Note that this function consumes the receiving pipeline and returns a /// Note that this function consumes the receiving pipeline and returns a
/// wrapped version of it. /// wrapped version of it.
pub fn then<F, U>( pub fn then<F, U>(self, service: F) -> Pipeline<ThenService<T, U>>
self,
service: F,
) -> Pipeline<impl Service<Request = T::Request, Response = U::Response, Error = T::Error>>
where where
Self: Sized, Self: Sized,
F: IntoService<U>, F: IntoService<U>,
U: Service<Request = Result<T::Response, T::Error>, Error = T::Error>, U: Service<Request = Result<T::Response, T::Error>, Error = T::Error>,
{ {
Pipeline { Pipeline {
service: Then::new(self.service, service.into_service()), service: ThenService::new(self.service, service.into_service()),
} }
} }
} }
@ -108,18 +102,7 @@ pub struct PipelineFactory<T> {
impl<T: ServiceFactory> PipelineFactory<T> { impl<T: ServiceFactory> PipelineFactory<T> {
/// Call another service after call to this one has resolved successfully. /// Call another service after call to this one has resolved successfully.
pub fn and_then<F, U>( pub fn and_then<F, U>(self, factory: F) -> PipelineFactory<AndThenServiceFactory<T, U>>
self,
factory: F,
) -> PipelineFactory<
impl ServiceFactory<
Config = T::Config,
Request = T::Request,
Response = U::Response,
Error = T::Error,
InitError = T::InitError,
>,
>
where where
Self: Sized, Self: Sized,
F: IntoServiceFactory<U>, F: IntoServiceFactory<U>,
@ -131,7 +114,7 @@ impl<T: ServiceFactory> PipelineFactory<T> {
>, >,
{ {
PipelineFactory { PipelineFactory {
factory: AndThenNewService::new(self.factory, factory.into_factory()), factory: AndThenServiceFactory::new(self.factory, factory.into_factory()),
} }
} }
@ -141,18 +124,7 @@ impl<T: ServiceFactory> PipelineFactory<T> {
/// ///
/// Note that this function consumes the receiving pipeline and returns a /// Note that this function consumes the receiving pipeline and returns a
/// wrapped version of it. /// wrapped version of it.
pub fn then<F, U>( pub fn then<F, U>(self, factory: F) -> PipelineFactory<ThenServiceFactory<T, U>>
self,
factory: F,
) -> PipelineFactory<
impl ServiceFactory<
Config = T::Config,
Request = T::Request,
Response = U::Response,
Error = T::Error,
InitError = T::InitError,
>,
>
where where
Self: Sized, Self: Sized,
F: IntoServiceFactory<U>, F: IntoServiceFactory<U>,
@ -164,7 +136,7 @@ impl<T: ServiceFactory> PipelineFactory<T> {
>, >,
{ {
PipelineFactory { PipelineFactory {
factory: ThenNewService::new(self.factory, factory.into_factory()), factory: ThenServiceFactory::new(self.factory, factory.into_factory()),
} }
} }
} }

View File

@ -2,8 +2,6 @@ use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use pin_project::pin_project;
use super::{Service, ServiceFactory}; use super::{Service, ServiceFactory};
use crate::cell::Cell; use crate::cell::Cell;
@ -11,43 +9,45 @@ use crate::cell::Cell;
/// another service. /// another service.
/// ///
/// This is created by the `ServiceExt::then` method. /// This is created by the `ServiceExt::then` method.
pub(crate) struct Then<A, B> { pub struct ThenService<A, B> {
a: A, a: A,
b: Cell<B>, b: Cell<B>,
} }
impl<A, B> Then<A, B> { impl<A, B> ThenService<A, B> {
/// Create new `Then` combinator /// Create new `.then()` combinator
pub fn new(a: A, b: B) -> Then<A, B> pub(crate) fn new(a: A, b: B) -> ThenService<A, B>
where where
A: Service, A: Service,
B: Service<Request = Result<A::Response, A::Error>, Error = A::Error>, B: Service<Request = Result<A::Response, A::Error>, Error = A::Error>,
{ {
Then { a, b: Cell::new(b) } Self { a, b: Cell::new(b) }
} }
} }
impl<A, B> Clone for Then<A, B> impl<A, B> Clone for ThenService<A, B>
where where
A: Clone, A: Clone,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Then { ThenService {
a: self.a.clone(), a: self.a.clone(),
b: self.b.clone(), b: self.b.clone(),
} }
} }
} }
impl<A, B> Service for Then<A, B> impl<A, B> Service for ThenService<A, B>
where where
A: Service, A: Service,
B: Service<Request = Result<A::Response, A::Error>, Error = A::Error>, B: Service<Request = Result<A::Response, A::Error>, Error = A::Error>,
A::Future: Unpin,
B::Future: Unpin,
{ {
type Request = A::Request; type Request = A::Request;
type Response = B::Response; type Response = B::Response;
type Error = B::Error; type Error = B::Error;
type Future = ThenFuture<A, B>; type Future = ThenServiceResponse<A, B>;
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
let not_ready = !self.a.poll_ready(ctx)?.is_ready(); let not_ready = !self.a.poll_ready(ctx)?.is_ready();
@ -59,30 +59,29 @@ where
} }
fn call(&mut self, req: A::Request) -> Self::Future { fn call(&mut self, req: A::Request) -> Self::Future {
ThenFuture::new(self.a.call(req), self.b.clone()) ThenServiceResponse::new(self.a.call(req), self.b.clone())
} }
} }
#[pin_project] pub struct ThenServiceResponse<A, B>
pub(crate) struct ThenFuture<A, B>
where where
A: Service, A: Service,
B: Service<Request = Result<A::Response, A::Error>>, B: Service<Request = Result<A::Response, A::Error>>,
{ {
b: Cell<B>, b: Cell<B>,
#[pin]
fut_b: Option<B::Future>, fut_b: Option<B::Future>,
#[pin]
fut_a: Option<A::Future>, fut_a: Option<A::Future>,
} }
impl<A, B> ThenFuture<A, B> impl<A, B> ThenServiceResponse<A, B>
where where
A: Service, A: Service,
B: Service<Request = Result<A::Response, A::Error>>, B: Service<Request = Result<A::Response, A::Error>>,
A::Future: Unpin,
B::Future: Unpin,
{ {
fn new(a: A::Future, b: Cell<B>) -> Self { fn new(a: A::Future, b: Cell<B>) -> Self {
ThenFuture { ThenServiceResponse {
b, b,
fut_a: Some(a), fut_a: Some(a),
fut_b: None, fut_b: None,
@ -90,34 +89,26 @@ where
} }
} }
impl<A, B> Future for ThenFuture<A, B> impl<A, B> Future for ThenServiceResponse<A, B>
where where
A: Service, A: Service,
B: Service<Request = Result<A::Response, A::Error>>, B: Service<Request = Result<A::Response, A::Error>>,
A::Future: Unpin,
B::Future: Unpin,
{ {
type Output = Result<B::Response, B::Error>; type Output = Result<B::Response, B::Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut this = self.project(); let this = self.get_mut();
loop { loop {
let mut fut_a = this.fut_a.as_mut(); if let Some(ref mut fut) = this.fut_b {
let mut fut_b = this.fut_b.as_mut(); return Pin::new(fut).poll(cx);
if let Some(fut) = fut_b.as_mut().as_pin_mut() {
return fut.poll(cx);
} }
match fut_a match Pin::new(this.fut_a.as_mut().expect("Bug in actix-service")).poll(cx) {
.as_mut()
.as_pin_mut()
.expect("Bug in actix-service")
.poll(cx)
{
Poll::Ready(r) => { Poll::Ready(r) => {
fut_a.set(None); this.fut_b = Some(this.b.get_mut().call(r));
let new_fut = this.b.get_mut().call(r);
fut_b.set(Some(new_fut));
} }
Poll::Pending => return Poll::Pending, Poll::Pending => return Poll::Pending,
@ -127,12 +118,12 @@ where
} }
/// `.then()` service factory combinator /// `.then()` service factory combinator
pub(crate) struct ThenNewService<A, B> { pub struct ThenServiceFactory<A, B> {
a: A, a: A,
b: B, b: B,
} }
impl<A, B> ThenNewService<A, B> impl<A, B> ThenServiceFactory<A, B>
where where
A: ServiceFactory, A: ServiceFactory,
B: ServiceFactory< B: ServiceFactory<
@ -143,12 +134,12 @@ where
>, >,
{ {
/// Create new `AndThen` combinator /// Create new `AndThen` combinator
pub fn new(a: A, b: B) -> Self { pub(crate) fn new(a: A, b: B) -> Self {
Self { a, b } Self { a, b }
} }
} }
impl<A, B> ServiceFactory for ThenNewService<A, B> impl<A, B> ServiceFactory for ThenServiceFactory<A, B>
where where
A: ServiceFactory, A: ServiceFactory,
B: ServiceFactory< B: ServiceFactory<
@ -157,22 +148,28 @@ where
Error = A::Error, Error = A::Error,
InitError = A::InitError, InitError = A::InitError,
>, >,
A::Future: Unpin,
A::Service: Unpin,
<A::Service as Service>::Future: Unpin,
B::Future: Unpin,
B::Service: Unpin,
<B::Service as Service>::Future: Unpin,
{ {
type Request = A::Request; type Request = A::Request;
type Response = B::Response; type Response = B::Response;
type Error = A::Error; type Error = A::Error;
type Config = A::Config; type Config = A::Config;
type Service = Then<A::Service, B::Service>; type Service = ThenService<A::Service, B::Service>;
type InitError = A::InitError; type InitError = A::InitError;
type Future = ThenNewServiceFuture<A, B>; type Future = ThenServiceFactoryResponse<A, B>;
fn new_service(&self, cfg: &A::Config) -> Self::Future { fn new_service(&self, cfg: &A::Config) -> Self::Future {
ThenNewServiceFuture::new(self.a.new_service(cfg), self.b.new_service(cfg)) ThenServiceFactoryResponse::new(self.a.new_service(cfg), self.b.new_service(cfg))
} }
} }
impl<A, B> Clone for ThenNewService<A, B> impl<A, B> Clone for ThenServiceFactory<A, B>
where where
A: Clone, A: Clone,
B: Clone, B: Clone,
@ -185,8 +182,7 @@ where
} }
} }
#[pin_project] pub struct ThenServiceFactoryResponse<A, B>
pub(crate) struct ThenNewServiceFuture<A, B>
where where
A: ServiceFactory, A: ServiceFactory,
B: ServiceFactory< B: ServiceFactory<
@ -196,15 +192,13 @@ where
InitError = A::InitError, InitError = A::InitError,
>, >,
{ {
#[pin]
fut_b: B::Future, fut_b: B::Future,
#[pin]
fut_a: A::Future, fut_a: A::Future,
a: Option<A::Service>, a: Option<A::Service>,
b: Option<B::Service>, b: Option<B::Service>,
} }
impl<A, B> ThenNewServiceFuture<A, B> impl<A, B> ThenServiceFactoryResponse<A, B>
where where
A: ServiceFactory, A: ServiceFactory,
B: ServiceFactory< B: ServiceFactory<
@ -213,9 +207,15 @@ where
Error = A::Error, Error = A::Error,
InitError = A::InitError, InitError = A::InitError,
>, >,
A::Future: Unpin,
A::Service: Unpin,
<A::Service as Service>::Future: Unpin,
B::Future: Unpin,
B::Service: Unpin,
<B::Service as Service>::Future: Unpin,
{ {
fn new(fut_a: A::Future, fut_b: B::Future) -> Self { fn new(fut_a: A::Future, fut_b: B::Future) -> Self {
ThenNewServiceFuture { Self {
fut_a, fut_a,
fut_b, fut_b,
a: None, a: None,
@ -224,7 +224,7 @@ where
} }
} }
impl<A, B> Future for ThenNewServiceFuture<A, B> impl<A, B> Future for ThenServiceFactoryResponse<A, B>
where where
A: ServiceFactory, A: ServiceFactory,
B: ServiceFactory< B: ServiceFactory<
@ -233,23 +233,30 @@ where
Error = A::Error, Error = A::Error,
InitError = A::InitError, InitError = A::InitError,
>, >,
A::Future: Unpin,
A::Service: Unpin,
<A::Service as Service>::Future: Unpin,
B::Future: Unpin,
B::Service: Unpin,
<B::Service as Service>::Future: Unpin,
{ {
type Output = Result<Then<A::Service, B::Service>, A::InitError>; type Output = Result<ThenService<A::Service, B::Service>, A::InitError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project(); let this = self.get_mut();
if this.a.is_none() { if this.a.is_none() {
if let Poll::Ready(service) = this.fut_a.poll(cx)? { if let Poll::Ready(service) = Pin::new(&mut this.fut_a).poll(cx)? {
*this.a = Some(service); this.a = Some(service);
} }
} }
if this.b.is_none() { if this.b.is_none() {
if let Poll::Ready(service) = this.fut_b.poll(cx)? { if let Poll::Ready(service) = Pin::new(&mut this.fut_b).poll(cx)? {
*this.b = Some(service); this.b = Some(service);
} }
} }
if this.a.is_some() && this.b.is_some() { if this.a.is_some() && this.b.is_some() {
Poll::Ready(Ok(Then::new( Poll::Ready(Ok(ThenService::new(
this.a.take().unwrap(), this.a.take().unwrap(),
this.b.take().unwrap(), this.b.take().unwrap(),
))) )))

View File

@ -1,14 +1,12 @@
use std::future::Future; use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin; use std::pin::Pin;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use crate::transform_err::TransformMapInitErr;
use crate::{IntoServiceFactory, Service, ServiceFactory}; use crate::{IntoServiceFactory, Service, ServiceFactory};
use pin_project::pin_project;
/// The `Transform` trait defines the interface of a Service factory. `Transform` /// The `Transform` trait defines the interface of a Service factory. `Transform`
/// is often implemented for middleware, defining how to construct a /// is often implemented for middleware, defining how to construct a
/// middleware Service. A Service that is constructed by the factory takes /// middleware Service. A Service that is constructed by the factory takes
@ -45,7 +43,8 @@ pub trait Transform<S> {
fn map_init_err<F, E>(self, f: F) -> TransformMapInitErr<Self, S, F, E> fn map_init_err<F, E>(self, f: F) -> TransformMapInitErr<Self, S, F, E>
where where
Self: Sized, Self: Sized,
F: Fn(Self::InitError) -> E, Self::Future: Unpin,
F: Fn(Self::InitError) -> E + Unpin + Clone,
{ {
TransformMapInitErr::new(self, f) TransformMapInitErr::new(self, f)
} }
@ -86,27 +85,19 @@ where
/// Apply transform to a service. Function returns /// Apply transform to a service. Function returns
/// services factory that in initialization creates /// services factory that in initialization creates
/// service and applies transform to this service. /// service and applies transform to this service.
pub fn apply<T, S, U>( pub fn apply<T, S, U>(t: T, service: U) -> ApplyTransform<T, S>
t: T,
service: U,
) -> impl ServiceFactory<
Config = S::Config,
Request = T::Request,
Response = T::Response,
Error = T::Error,
Service = T::Transform,
InitError = S::InitError,
> + Clone
where where
S: ServiceFactory, S: ServiceFactory,
S::Future: Unpin,
T: Transform<S::Service, InitError = S::InitError>, T: Transform<S::Service, InitError = S::InitError>,
T::Future: Unpin,
U: IntoServiceFactory<S>, U: IntoServiceFactory<S>,
{ {
ApplyTransform::new(t, service.into_factory()) ApplyTransform::new(t, service.into_factory())
} }
/// `Apply` transform to new service /// `Apply` transform to new service
struct ApplyTransform<T, S> { pub struct ApplyTransform<T, S> {
s: Rc<S>, s: Rc<S>,
t: Rc<T>, t: Rc<T>,
} }
@ -137,7 +128,9 @@ impl<T, S> Clone for ApplyTransform<T, S> {
impl<T, S> ServiceFactory for ApplyTransform<T, S> impl<T, S> ServiceFactory for ApplyTransform<T, S>
where where
S: ServiceFactory, S: ServiceFactory,
S::Future: Unpin,
T: Transform<S::Service, InitError = S::InitError>, T: Transform<S::Service, InitError = S::InitError>,
T::Future: Unpin,
{ {
type Request = T::Request; type Request = T::Request;
type Response = T::Response; type Response = T::Response;
@ -157,15 +150,12 @@ where
} }
} }
#[pin_project] pub struct ApplyTransformFuture<T, S>
struct ApplyTransformFuture<T, S>
where where
S: ServiceFactory, S: ServiceFactory,
T: Transform<S::Service, InitError = S::InitError>, T: Transform<S::Service, InitError = S::InitError>,
{ {
#[pin]
fut_a: S::Future, fut_a: S::Future,
#[pin]
fut_t: Option<T::Future>, fut_t: Option<T::Future>,
t_cell: Rc<T>, t_cell: Rc<T>,
} }
@ -173,23 +163,114 @@ where
impl<T, S> Future for ApplyTransformFuture<T, S> impl<T, S> Future for ApplyTransformFuture<T, S>
where where
S: ServiceFactory, S: ServiceFactory,
S::Future: Unpin,
T: Transform<S::Service, InitError = S::InitError>, T: Transform<S::Service, InitError = S::InitError>,
T::Future: Unpin,
{ {
type Output = Result<T::Transform, T::InitError>; type Output = Result<T::Transform, T::InitError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut this = self.project(); let mut this = self.get_mut();
if this.fut_t.as_mut().as_pin_mut().is_none() { if this.fut_t.is_none() {
if let Poll::Ready(service) = this.fut_a.poll(cx)? { if let Poll::Ready(service) = Pin::new(&mut this.fut_a).poll(cx)? {
this.fut_t.set(Some(this.t_cell.new_transform(service))); this.fut_t = Some(this.t_cell.new_transform(service));
} else {
return Poll::Pending;
} }
} }
if let Some(fut) = this.fut_t.as_mut().as_pin_mut() { if let Some(ref mut fut) = this.fut_t {
fut.poll(cx) Pin::new(fut).poll(cx)
} else { } else {
Poll::Pending Poll::Pending
} }
} }
} }
/// Transform for the `map_err` combinator, changing the type of a new
/// transform's init error.
///
/// This is created by the `Transform::map_err` method.
pub struct TransformMapInitErr<T, S, F, E> {
t: T,
f: F,
e: PhantomData<(S, E)>,
}
impl<T, S, F, E> TransformMapInitErr<T, S, F, E> {
/// Create new `TransformMapErr` new transform instance
pub(crate) fn new(t: T, f: F) -> Self
where
T: Transform<S>,
T::Future: Unpin,
F: Fn(T::InitError) -> E + Unpin + Clone,
{
Self {
t,
f,
e: PhantomData,
}
}
}
impl<T, S, F, E> Clone for TransformMapInitErr<T, S, F, E>
where
T: Clone,
F: Clone,
{
fn clone(&self) -> Self {
Self {
t: self.t.clone(),
f: self.f.clone(),
e: PhantomData,
}
}
}
impl<T, S, F, E> Transform<S> for TransformMapInitErr<T, S, F, E>
where
T: Transform<S>,
T::Future: Unpin,
F: Fn(T::InitError) -> E + Unpin + Clone,
{
type Request = T::Request;
type Response = T::Response;
type Error = T::Error;
type Transform = T::Transform;
type InitError = E;
type Future = TransformMapInitErrFuture<T, S, F, E>;
fn new_transform(&self, service: S) -> Self::Future {
TransformMapInitErrFuture {
fut: self.t.new_transform(service),
f: self.f.clone(),
}
}
}
pub struct TransformMapInitErrFuture<T, S, F, E>
where
T: Transform<S>,
T::Future: Unpin,
F: Fn(T::InitError) -> E + Unpin,
{
fut: T::Future,
f: F,
}
impl<T, S, F, E> Future for TransformMapInitErrFuture<T, S, F, E>
where
T: Transform<S>,
T::Future: Unpin,
F: Fn(T::InitError) -> E + Unpin + Clone,
{
type Output = Result<T::Transform, E>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
Pin::new(&mut this.fut).poll(cx).map_err(&this.f)
}
}

View File

@ -1,91 +0,0 @@
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::task::{Context, Poll};
use pin_project::pin_project;
use super::Transform;
/// Transform for the `map_err` combinator, changing the type of a new
/// transform's init error.
///
/// This is created by the `Transform::map_err` method.
pub struct TransformMapInitErr<T, S, F, E> {
t: T,
f: F,
e: PhantomData<(S, E)>,
}
impl<T, S, F, E> TransformMapInitErr<T, S, F, E> {
/// Create new `TransformMapErr` new transform instance
pub fn new(t: T, f: F) -> Self
where
T: Transform<S>,
F: Fn(T::InitError) -> E,
{
Self {
t,
f,
e: PhantomData,
}
}
}
impl<T, S, F, E> Clone for TransformMapInitErr<T, S, F, E>
where
T: Clone,
F: Clone,
{
fn clone(&self) -> Self {
Self {
t: self.t.clone(),
f: self.f.clone(),
e: PhantomData,
}
}
}
impl<T, S, F, E> Transform<S> for TransformMapInitErr<T, S, F, E>
where
T: Transform<S>,
F: Fn(T::InitError) -> E + Clone,
{
type Request = T::Request;
type Response = T::Response;
type Error = T::Error;
type Transform = T::Transform;
type InitError = E;
type Future = TransformMapInitErrFuture<T, S, F, E>;
fn new_transform(&self, service: S) -> Self::Future {
TransformMapInitErrFuture {
fut: self.t.new_transform(service),
f: self.f.clone(),
}
}
}
#[pin_project]
pub struct TransformMapInitErrFuture<T, S, F, E>
where
T: Transform<S>,
F: Fn(T::InitError) -> E,
{
#[pin]
fut: T::Future,
f: F,
}
impl<T, S, F, E> Future for TransformMapInitErrFuture<T, S, F, E>
where
T: Transform<S>,
F: Fn(T::InitError) -> E + Clone,
{
type Output = Result<T::Transform, E>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
this.fut.poll(cx).map_err(this.f)
}
}

View File

@ -325,7 +325,7 @@ where
if !buf_empty { if !buf_empty {
match inner.buf.pop_front().unwrap() { match inner.buf.pop_front().unwrap() {
Ok(msg) => { Ok(msg) => {
if let Err(err) = framed.force_send(msg) { if let Err(err) = framed.write(msg) {
*state = *state =
TransportState::FramedError(FramedTransportError::Encoder(err)); TransportState::FramedError(FramedTransportError::Encoder(err));
return true; return true;
@ -342,7 +342,7 @@ where
if !rx_done && rx.is_some() { if !rx_done && rx.is_some() {
match Pin::new(rx.as_mut().unwrap()).poll_next(cx) { match Pin::new(rx.as_mut().unwrap()).poll_next(cx) {
Poll::Ready(Some(FramedMessage::Message(msg))) => { Poll::Ready(Some(FramedMessage::Message(msg))) => {
if let Err(err) = framed.force_send(msg) { if let Err(err) = framed.write(msg) {
*state = *state =
TransportState::FramedError(FramedTransportError::Encoder(err)); TransportState::FramedError(FramedTransportError::Encoder(err));
return true; return true;