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:
parent
c1cdc9908a
commit
7404d82a9b
@ -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,
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
|
@ -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(),
|
||||||
)))
|
)))
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -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};
|
||||||
|
}
|
||||||
|
@ -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());
|
||||||
|
@ -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());
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
||||||
)))
|
)))
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user