1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-27 19:12:56 +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> {
/// Force send item
pub fn force_send(
&mut self,
item: <U as Encoder>::Item,
) -> Result<(), <U as Encoder>::Error>
/// Serialize item and Write to the inner buffer
pub fn write(&mut self, item: <U as Encoder>::Item) -> Result<(), <U as Encoder>::Error>
where
T: AsyncWrite + Unpin,
U: Encoder + Unpin,

View File

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

View File

@ -20,6 +20,10 @@ pub mod ssl;
#[cfg(feature = "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::system_conf::read_system_conf;
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::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 {
let (resolver, bg) = AsyncResolver::new(cfg, opts);
tokio_executor::current_thread::spawn(bg);
@ -70,7 +70,7 @@ pub fn start_default_resolver() -> AsyncResolver {
pub fn new_connector<T: Address>(
resolver: AsyncResolver,
) -> impl Service<Request = Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError>
{
+ Clone {
pipeline(Resolver::new(resolver)).and_then(TcpConnector::new())
}
@ -83,14 +83,14 @@ pub fn new_connector_factory<T: Address>(
Response = Connection<T, TcpStream>,
Error = ConnectError,
InitError = (),
> {
> + Clone {
pipeline_factory(ResolverFactory::new(resolver)).and_then(TcpConnectorFactory::new())
}
/// Create connector service with default parameters
pub fn default_connector<T: Address>(
) -> impl Service<Request = Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError>
{
+ Clone {
pipeline(Resolver::default()).and_then(TcpConnector::new())
}
@ -101,6 +101,6 @@ pub fn default_connector_factory<T: Address>() -> impl ServiceFactory<
Response = Connection<T, TcpStream>,
Error = ConnectError,
InitError = (),
> {
> + Clone {
pipeline_factory(ResolverFactory::default()).and_then(TcpConnectorFactory::new())
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,72 +4,49 @@ use std::pin::Pin;
use std::task::{Context, Poll};
use futures::future::{ok, Ready};
use pin_project::pin_project;
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
/// Create `ServiceFactory` for function that can act as a `Service`
pub fn service_fn<F, Fut, Req, Res, Err, Cfg>(
f: F,
) -> impl ServiceFactory<Config = Cfg, Request = Req, Response = Res, Error = Err, InitError = ()>
+ Clone
) -> FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where
F: FnMut(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>,
{
NewServiceFn::new(f)
FnServiceFactory::new(f)
}
pub fn service_fn2<F, Fut, Req, Res, Err>(
f: F,
) -> impl Service<Request = Req, Response = Res, Error = Err>
pub fn service_fn2<F, Fut, Req, Res, Err>(f: F) -> FnService<F, Fut, Req, Res, Err>
where
F: FnMut(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>,
{
ServiceFn::new(f)
FnService::new(f)
}
/// Create `ServiceFactory` for function that can produce services
pub fn factory_fn<S, F, Cfg, Fut, Err>(
f: F,
) -> impl ServiceFactory<
Config = Cfg,
Service = S,
Request = S::Request,
Response = S::Response,
Error = S::Error,
InitError = Err,
Future = Fut,
>
pub fn factory_fn<F, Cfg, Srv, Fut, Err>(f: F) -> FnServiceNoConfig<F, Cfg, Srv, Fut, Err>
where
S: Service,
Srv: Service,
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
pub fn factory_fn_cfg<F, Fut, Cfg, Srv, Err>(
f: F,
) -> impl ServiceFactory<
Config = Cfg,
Service = Srv,
Request = Srv::Request,
Response = Srv::Response,
Error = Srv::Error,
InitError = Err,
>
pub fn factory_fn_cfg<F, Fut, Cfg, Srv, Err>(f: F) -> FnServiceConfig<F, Fut, Cfg, Srv, Err>
where
F: Fn(&Cfg) -> Fut,
Fut: Future<Output = Result<Srv, Err>>,
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
F: FnMut(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>,
@ -78,27 +55,27 @@ where
_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
F: FnMut(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>,
{
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
F: FnMut(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>,
{
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
F: FnMut(Req) -> Fut,
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
F: FnMut(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>,
{
fn into_service(self) -> ServiceFn<F, Fut, Req, Res, Err> {
ServiceFn::new(self)
fn into_service(self) -> FnService<F, Fut, Req, Res, Err> {
FnService::new(self)
}
}
struct NewServiceFn<F, Fut, Req, Res, Err, Cfg>
pub struct FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where
F: FnMut(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>,
@ -136,27 +113,27 @@ where
_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
F: FnMut(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>,
{
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
F: FnMut(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>,
{
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
F: FnMut(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>,
@ -166,17 +143,17 @@ where
type Error = Err;
type Config = Cfg;
type Service = ServiceFn<F, Fut, Req, Res, Err>;
type Service = FnService<F, Fut, Req, Res, Err>;
type InitError = ();
type Future = Ready<Result<Self::Service, Self::InitError>>;
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
struct FnNewServiceConfig<F, Fut, Cfg, Srv, Err>
pub struct FnServiceConfig<F, Fut, Cfg, Srv, Err>
where
F: Fn(&Cfg) -> Fut,
Fut: Future<Output = Result<Srv, Err>>,
@ -186,21 +163,21 @@ where
_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
F: Fn(&Cfg) -> Fut,
Fut: Future<Output = Result<Srv, Err>>,
Srv: Service,
{
pub fn new(f: F) -> Self {
FnNewServiceConfig { f, _t: PhantomData }
fn new(f: F) -> Self {
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
F: Fn(&Cfg) -> Fut,
Fut: Future<Output = Result<Srv, Err>>,
Fut: Future<Output = Result<Srv, Err>> + Unpin,
Srv: Service,
{
type Request = Srv::Request;
@ -210,62 +187,67 @@ where
type Config = Cfg;
type Service = Srv;
type InitError = Err;
type Future = FnNewServiceConfigFut<Fut, Srv, Err>;
type Future = NewServiceFnConfigFut<Fut, Srv, Err>;
fn new_service(&self, cfg: &Cfg) -> Self::Future {
FnNewServiceConfigFut {
NewServiceFnConfigFut {
fut: (self.f)(cfg),
_t: PhantomData,
}
}
}
#[pin_project]
struct FnNewServiceConfigFut<R, S, E>
pub struct NewServiceFnConfigFut<R, S, E>
where
R: Future<Output = Result<S, E>>,
R: Future<Output = Result<S, E>> + Unpin,
S: Service,
{
#[pin]
fut: R,
_t: PhantomData<(S,)>,
}
impl<R, S, E> Future for FnNewServiceConfigFut<R, S, E>
impl<R, S, E> Unpin for NewServiceFnConfigFut<R, S, E>
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,
{
type Output = Result<S, E>;
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
pub struct FnNewServiceNoConfig<F, C, R, S, E>
pub struct FnServiceNoConfig<F, C, S, R, E>
where
F: Fn() -> R,
R: Future<Output = Result<S, E>>,
S: Service,
R: Future<Output = Result<S, E>>,
{
f: F,
_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
F: Fn() -> R,
R: Future<Output = Result<S, E>>,
S: Service,
{
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
F: Fn() -> R,
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
F: Fn() -> R + Clone,
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
F: Fn() -> R,
R: Future<Output = Result<S, E>>,
S: Service,
{
fn into_factory(self) -> FnNewServiceNoConfig<F, C, R, S, E> {
FnNewServiceNoConfig::new(self)
fn into_factory(self) -> FnServiceNoConfig<F, C, S, R, E> {
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;
mod cell;
mod fn_service;
mod into;
mod map;
mod map_config;
mod map_err;
@ -18,12 +17,10 @@ mod map_init_err;
mod pipeline;
mod then;
mod transform;
mod transform_err;
pub use self::apply::{apply_fn, apply_fn_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::into::{into_factory, into_service, ServiceFactoryMapper, ServiceMapper};
pub use self::map_config::{map_config, unit_config, MappedConfig};
pub use self::pipeline::{pipeline, pipeline_factory, Pipeline, PipelineFactory};
pub use self::transform::{apply, Transform};
@ -63,6 +60,41 @@ pub trait Service {
/// Calling `call` without calling `poll_ready` is permitted. The
/// implementation must be resilient to this fact.
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.
@ -102,6 +134,37 @@ pub trait ServiceFactory {
/// Create and return a new service value asynchronously.
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
@ -227,3 +290,17 @@ where
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::task::{Context, Poll};
use pin_project::pin_project;
use super::{Service, ServiceFactory};
/// Service for the `map` combinator, changing the type of a service's response.
///
/// This is created by the `ServiceExt::map` method.
pub(crate) struct Map<A, F, Response> {
pub struct Map<A, F, Response> {
service: A,
f: F,
_t: PhantomData<Response>,
@ -18,7 +16,7 @@ pub(crate) struct Map<A, F, Response> {
impl<A, F, Response> Map<A, F, Response> {
/// Create new `Map` combinator
pub fn new(service: A, f: F) -> Self
pub(crate) fn new(service: A, f: F) -> Self
where
A: Service,
F: FnMut(A::Response) -> Response,
@ -48,7 +46,8 @@ where
impl<A, F, Response> Service for Map<A, F, Response>
where
A: Service,
F: FnMut(A::Response) -> Response + Clone,
A::Future: Unpin,
F: FnMut(A::Response) -> Response + Unpin + Clone,
{
type Request = A::Request;
type Response = Response;
@ -64,14 +63,12 @@ where
}
}
#[pin_project]
pub(crate) struct MapFuture<A, F, Response>
pub struct MapFuture<A, F, Response>
where
A: Service,
F: FnMut(A::Response) -> Response,
{
f: F,
#[pin]
fut: A::Future,
}
@ -88,13 +85,15 @@ where
impl<A, F, Response> Future for MapFuture<A, F, Response>
where
A: Service,
F: FnMut(A::Response) -> Response,
A::Future: Unpin,
F: FnMut(A::Response) -> Response + Unpin,
{
type Output = Result<Response, A::Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
match this.fut.poll(cx) {
let this = self.get_mut();
match Pin::new(&mut this.fut).poll(cx) {
Poll::Ready(Ok(resp)) => Poll::Ready(Ok((this.f)(resp))),
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
Poll::Pending => Poll::Pending,
@ -103,18 +102,18 @@ where
}
/// `MapNewService` new service combinator
pub(crate) struct MapNewService<A, F, Res> {
pub struct MapServiceFactory<A, F, Res> {
a: A,
f: F,
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
pub fn new(a: A, f: F) -> Self
pub(crate) fn new(a: A, f: F) -> Self
where
A: ServiceFactory,
F: FnMut(A::Response) -> Res,
F: FnMut(A::Response) -> Res + Unpin,
{
Self {
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
A: 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
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 Response = Res;
@ -150,44 +151,44 @@ where
type Config = A::Config;
type Service = Map<A::Service, F, Res>;
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 {
MapNewServiceFuture::new(self.a.new_service(cfg), self.f.clone())
MapServiceFuture::new(self.a.new_service(cfg), self.f.clone())
}
}
#[pin_project]
pub(crate) struct MapNewServiceFuture<A, F, Res>
pub struct MapServiceFuture<A, F, Res>
where
A: ServiceFactory,
F: FnMut(A::Response) -> Res,
{
#[pin]
fut: A::Future,
f: Option<F>,
}
impl<A, F, Res> MapNewServiceFuture<A, F, Res>
impl<A, F, Res> MapServiceFuture<A, F, Res>
where
A: ServiceFactory,
F: FnMut(A::Response) -> Res,
F: FnMut(A::Response) -> Res + Unpin,
{
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
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>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
if let Poll::Ready(svc) = this.fut.poll(cx)? {
let this = self.get_mut();
if let Poll::Ready(svc) = Pin::new(&mut this.fut).poll(cx)? {
Poll::Ready(Ok(Map::new(svc, this.f.take().unwrap())))
} else {
Poll::Pending
@ -200,7 +201,7 @@ mod tests {
use futures::future::{lazy, ok, Ready};
use super::*;
use crate::{into_factory, into_service, Service};
use crate::{IntoServiceFactory, Service, ServiceFactory};
struct Srv;
@ -221,14 +222,14 @@ mod tests {
#[tokio::test]
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;
assert_eq!(res, Poll::Ready(Ok(())));
}
#[tokio::test]
async fn test_call() {
let mut srv = into_service(Srv).map(|_| "ok");
let mut srv = Srv.map(|_| "ok");
let res = srv.call(()).await;
assert!(res.is_ok());
assert_eq!(res.unwrap(), "ok");
@ -236,7 +237,7 @@ mod tests {
#[tokio::test]
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 res = srv.call(()).await;
assert!(res.is_ok());

View File

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

View File

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

View File

@ -1,7 +1,7 @@
use std::task::{Context, Poll};
use crate::and_then::{AndThen, AndThenNewService};
use crate::then::{Then, ThenNewService};
use crate::and_then::{AndThenService, AndThenServiceFactory};
use crate::then::{ThenService, ThenServiceFactory};
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
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
/// wrapped version of it.
pub fn and_then<F, U>(
self,
service: F,
) -> Pipeline<impl Service<Request = T::Request, Response = U::Response, Error = T::Error>>
pub fn and_then<F, U>(self, service: F) -> Pipeline<AndThenService<T, U>>
where
Self: Sized,
F: IntoService<U>,
U: Service<Request = T::Response, Error = T::Error>,
U: Service<Request = T::Response, Error = T::Error> + Unpin,
{
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
/// wrapped version of it.
pub fn then<F, U>(
self,
service: F,
) -> Pipeline<impl Service<Request = T::Request, Response = U::Response, Error = T::Error>>
pub fn then<F, U>(self, service: F) -> Pipeline<ThenService<T, U>>
where
Self: Sized,
F: IntoService<U>,
U: Service<Request = Result<T::Response, T::Error>, Error = T::Error>,
{
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> {
/// Call another service after call to this one has resolved successfully.
pub fn and_then<F, U>(
self,
factory: F,
) -> PipelineFactory<
impl ServiceFactory<
Config = T::Config,
Request = T::Request,
Response = U::Response,
Error = T::Error,
InitError = T::InitError,
>,
>
pub fn and_then<F, U>(self, factory: F) -> PipelineFactory<AndThenServiceFactory<T, U>>
where
Self: Sized,
F: IntoServiceFactory<U>,
@ -131,7 +114,7 @@ impl<T: ServiceFactory> PipelineFactory<T> {
>,
{
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
/// wrapped version of it.
pub fn then<F, U>(
self,
factory: F,
) -> PipelineFactory<
impl ServiceFactory<
Config = T::Config,
Request = T::Request,
Response = U::Response,
Error = T::Error,
InitError = T::InitError,
>,
>
pub fn then<F, U>(self, factory: F) -> PipelineFactory<ThenServiceFactory<T, U>>
where
Self: Sized,
F: IntoServiceFactory<U>,
@ -164,7 +136,7 @@ impl<T: ServiceFactory> PipelineFactory<T> {
>,
{
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::task::{Context, Poll};
use pin_project::pin_project;
use super::{Service, ServiceFactory};
use crate::cell::Cell;
@ -11,43 +9,45 @@ use crate::cell::Cell;
/// another service.
///
/// This is created by the `ServiceExt::then` method.
pub(crate) struct Then<A, B> {
pub struct ThenService<A, B> {
a: A,
b: Cell<B>,
}
impl<A, B> Then<A, B> {
/// Create new `Then` combinator
pub fn new(a: A, b: B) -> Then<A, B>
impl<A, B> ThenService<A, B> {
/// Create new `.then()` combinator
pub(crate) fn new(a: A, b: B) -> ThenService<A, B>
where
A: Service,
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
A: Clone,
{
fn clone(&self) -> Self {
Then {
ThenService {
a: self.a.clone(),
b: self.b.clone(),
}
}
}
impl<A, B> Service for Then<A, B>
impl<A, B> Service for ThenService<A, B>
where
A: Service,
B: Service<Request = Result<A::Response, A::Error>, Error = A::Error>,
A::Future: Unpin,
B::Future: Unpin,
{
type Request = A::Request;
type Response = B::Response;
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>> {
let not_ready = !self.a.poll_ready(ctx)?.is_ready();
@ -59,30 +59,29 @@ where
}
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(crate) struct ThenFuture<A, B>
pub struct ThenServiceResponse<A, B>
where
A: Service,
B: Service<Request = Result<A::Response, A::Error>>,
{
b: Cell<B>,
#[pin]
fut_b: Option<B::Future>,
#[pin]
fut_a: Option<A::Future>,
}
impl<A, B> ThenFuture<A, B>
impl<A, B> ThenServiceResponse<A, B>
where
A: Service,
B: Service<Request = Result<A::Response, A::Error>>,
A::Future: Unpin,
B::Future: Unpin,
{
fn new(a: A::Future, b: Cell<B>) -> Self {
ThenFuture {
ThenServiceResponse {
b,
fut_a: Some(a),
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
A: Service,
B: Service<Request = Result<A::Response, A::Error>>,
A::Future: Unpin,
B::Future: Unpin,
{
type Output = Result<B::Response, B::Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut this = self.project();
let this = self.get_mut();
loop {
let mut fut_a = this.fut_a.as_mut();
let mut fut_b = this.fut_b.as_mut();
if let Some(fut) = fut_b.as_mut().as_pin_mut() {
return fut.poll(cx);
if let Some(ref mut fut) = this.fut_b {
return Pin::new(fut).poll(cx);
}
match fut_a
.as_mut()
.as_pin_mut()
.expect("Bug in actix-service")
.poll(cx)
{
match Pin::new(this.fut_a.as_mut().expect("Bug in actix-service")).poll(cx) {
Poll::Ready(r) => {
fut_a.set(None);
let new_fut = this.b.get_mut().call(r);
fut_b.set(Some(new_fut));
this.fut_b = Some(this.b.get_mut().call(r));
}
Poll::Pending => return Poll::Pending,
@ -127,12 +118,12 @@ where
}
/// `.then()` service factory combinator
pub(crate) struct ThenNewService<A, B> {
pub struct ThenServiceFactory<A, B> {
a: A,
b: B,
}
impl<A, B> ThenNewService<A, B>
impl<A, B> ThenServiceFactory<A, B>
where
A: ServiceFactory,
B: ServiceFactory<
@ -143,12 +134,12 @@ where
>,
{
/// Create new `AndThen` combinator
pub fn new(a: A, b: B) -> Self {
pub(crate) fn new(a: A, b: B) -> Self {
Self { a, b }
}
}
impl<A, B> ServiceFactory for ThenNewService<A, B>
impl<A, B> ServiceFactory for ThenServiceFactory<A, B>
where
A: ServiceFactory,
B: ServiceFactory<
@ -157,22 +148,28 @@ where
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 Request = A::Request;
type Response = B::Response;
type Error = A::Error;
type Config = A::Config;
type Service = Then<A::Service, B::Service>;
type Service = ThenService<A::Service, B::Service>;
type InitError = A::InitError;
type Future = ThenNewServiceFuture<A, B>;
type Future = ThenServiceFactoryResponse<A, B>;
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
A: Clone,
B: Clone,
@ -185,8 +182,7 @@ where
}
}
#[pin_project]
pub(crate) struct ThenNewServiceFuture<A, B>
pub struct ThenServiceFactoryResponse<A, B>
where
A: ServiceFactory,
B: ServiceFactory<
@ -196,15 +192,13 @@ where
InitError = A::InitError,
>,
{
#[pin]
fut_b: B::Future,
#[pin]
fut_a: A::Future,
a: Option<A::Service>,
b: Option<B::Service>,
}
impl<A, B> ThenNewServiceFuture<A, B>
impl<A, B> ThenServiceFactoryResponse<A, B>
where
A: ServiceFactory,
B: ServiceFactory<
@ -213,9 +207,15 @@ where
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,
{
fn new(fut_a: A::Future, fut_b: B::Future) -> Self {
ThenNewServiceFuture {
Self {
fut_a,
fut_b,
a: None,
@ -224,7 +224,7 @@ where
}
}
impl<A, B> Future for ThenNewServiceFuture<A, B>
impl<A, B> Future for ThenServiceFactoryResponse<A, B>
where
A: ServiceFactory,
B: ServiceFactory<
@ -233,23 +233,30 @@ where
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<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> {
let this = self.project();
let this = self.get_mut();
if this.a.is_none() {
if let Poll::Ready(service) = this.fut_a.poll(cx)? {
*this.a = Some(service);
if let Poll::Ready(service) = Pin::new(&mut this.fut_a).poll(cx)? {
this.a = Some(service);
}
}
if this.b.is_none() {
if let Poll::Ready(service) = this.fut_b.poll(cx)? {
*this.b = Some(service);
if let Poll::Ready(service) = Pin::new(&mut this.fut_b).poll(cx)? {
this.b = Some(service);
}
}
if this.a.is_some() && this.b.is_some() {
Poll::Ready(Ok(Then::new(
Poll::Ready(Ok(ThenService::new(
this.a.take().unwrap(),
this.b.take().unwrap(),
)))

View File

@ -1,14 +1,12 @@
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::rc::Rc;
use std::sync::Arc;
use std::task::{Context, Poll};
use crate::transform_err::TransformMapInitErr;
use crate::{IntoServiceFactory, Service, ServiceFactory};
use pin_project::pin_project;
/// The `Transform` trait defines the interface of a Service factory. `Transform`
/// is often implemented for middleware, defining how to construct a
/// 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>
where
Self: Sized,
F: Fn(Self::InitError) -> E,
Self::Future: Unpin,
F: Fn(Self::InitError) -> E + Unpin + Clone,
{
TransformMapInitErr::new(self, f)
}
@ -86,27 +85,19 @@ where
/// Apply transform to a service. Function returns
/// services factory that in initialization creates
/// service and applies transform to this service.
pub fn apply<T, S, U>(
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
pub fn apply<T, S, U>(t: T, service: U) -> ApplyTransform<T, S>
where
S: ServiceFactory,
S::Future: Unpin,
T: Transform<S::Service, InitError = S::InitError>,
T::Future: Unpin,
U: IntoServiceFactory<S>,
{
ApplyTransform::new(t, service.into_factory())
}
/// `Apply` transform to new service
struct ApplyTransform<T, S> {
pub struct ApplyTransform<T, S> {
s: Rc<S>,
t: Rc<T>,
}
@ -137,7 +128,9 @@ impl<T, S> Clone for ApplyTransform<T, S> {
impl<T, S> ServiceFactory for ApplyTransform<T, S>
where
S: ServiceFactory,
S::Future: Unpin,
T: Transform<S::Service, InitError = S::InitError>,
T::Future: Unpin,
{
type Request = T::Request;
type Response = T::Response;
@ -157,15 +150,12 @@ where
}
}
#[pin_project]
struct ApplyTransformFuture<T, S>
pub struct ApplyTransformFuture<T, S>
where
S: ServiceFactory,
T: Transform<S::Service, InitError = S::InitError>,
{
#[pin]
fut_a: S::Future,
#[pin]
fut_t: Option<T::Future>,
t_cell: Rc<T>,
}
@ -173,23 +163,114 @@ where
impl<T, S> Future for ApplyTransformFuture<T, S>
where
S: ServiceFactory,
S::Future: Unpin,
T: Transform<S::Service, InitError = S::InitError>,
T::Future: Unpin,
{
type Output = Result<T::Transform, T::InitError>;
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 let Poll::Ready(service) = this.fut_a.poll(cx)? {
this.fut_t.set(Some(this.t_cell.new_transform(service)));
if this.fut_t.is_none() {
if let Poll::Ready(service) = Pin::new(&mut this.fut_a).poll(cx)? {
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() {
fut.poll(cx)
if let Some(ref mut fut) = this.fut_t {
Pin::new(fut).poll(cx)
} else {
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 {
match inner.buf.pop_front().unwrap() {
Ok(msg) => {
if let Err(err) = framed.force_send(msg) {
if let Err(err) = framed.write(msg) {
*state =
TransportState::FramedError(FramedTransportError::Encoder(err));
return true;
@ -342,7 +342,7 @@ where
if !rx_done && rx.is_some() {
match Pin::new(rx.as_mut().unwrap()).poll_next(cx) {
Poll::Ready(Some(FramedMessage::Message(msg))) => {
if let Err(err) = framed.force_send(msg) {
if let Err(err) = framed.write(msg) {
*state =
TransportState::FramedError(FramedTransportError::Encoder(err));
return true;