mirror of
https://github.com/actix/actix-web.git
synced 2024-12-22 08:07:18 +00:00
better error conversion impl for and_then
This commit is contained in:
parent
41eddae266
commit
9456065d7b
5 changed files with 143 additions and 51 deletions
|
@ -259,14 +259,18 @@ where
|
|||
|
||||
impl<A, B, C> NewConfigurableService<C> for AndThenNewConfigurableService<A, B, C>
|
||||
where
|
||||
A: NewConfigurableService<C, Response = B::Request, InitError = B::InitError>,
|
||||
A::Error: Into<B::Error>,
|
||||
B: NewConfigurableService<C>,
|
||||
A: NewConfigurableService<C>,
|
||||
B: NewConfigurableService<
|
||||
C,
|
||||
Request = A::Response,
|
||||
Error = A::Error,
|
||||
InitError = A::InitError,
|
||||
>,
|
||||
C: Clone,
|
||||
{
|
||||
type Request = A::Request;
|
||||
type Response = B::Response;
|
||||
type Error = B::Error;
|
||||
type Error = A::Error;
|
||||
type Service = AndThen<A::Service, B::Service>;
|
||||
|
||||
type InitError = A::InitError;
|
||||
|
@ -282,9 +286,13 @@ where
|
|||
|
||||
impl<A, B, C> Clone for AndThenNewConfigurableService<A, B, C>
|
||||
where
|
||||
A: NewConfigurableService<C, Response = B::Request, InitError = B::InitError> + Clone,
|
||||
A::Error: Into<B::Error>,
|
||||
B: NewConfigurableService<C> + Clone,
|
||||
A: NewConfigurableService<C> + Clone,
|
||||
B: NewConfigurableService<
|
||||
C,
|
||||
Request = A::Response,
|
||||
Error = A::Error,
|
||||
InitError = A::InitError,
|
||||
> + Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
|
@ -326,18 +334,22 @@ where
|
|||
impl<A, B, C> Future for AndThenNewConfigurableServiceFuture<A, B, C>
|
||||
where
|
||||
A: NewConfigurableService<C>,
|
||||
A::Error: Into<B::Error>,
|
||||
B: NewConfigurableService<C, Request = A::Response, InitError = A::InitError>,
|
||||
B: NewConfigurableService<
|
||||
C,
|
||||
Request = A::Response,
|
||||
Error = A::Error,
|
||||
InitError = A::InitError,
|
||||
>,
|
||||
{
|
||||
type Item = AndThen<A::Service, B::Service>;
|
||||
type Error = B::InitError;
|
||||
type Error = A::InitError;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
if let Async::Ready(service) = self.fut_a.poll()? {
|
||||
self.a = Some(service);
|
||||
}
|
||||
|
||||
if let Async::Ready(service) = self.fut_b.poll()? {
|
||||
if let Async::Ready(service) = self.fut_b.poll().map_err(|e| e.into())? {
|
||||
self.b = Some(service);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@ pub struct AndThen<A, B> {
|
|||
impl<A, B> AndThen<A, B>
|
||||
where
|
||||
A: Service,
|
||||
A::Error: Into<B::Error>,
|
||||
B: Service<Request = A::Response>,
|
||||
B: Service<Request = A::Response, Error = A::Error>,
|
||||
{
|
||||
/// Create new `AndThen` combinator
|
||||
pub fn new(a: A, b: B) -> Self {
|
||||
|
@ -30,19 +29,18 @@ where
|
|||
impl<A, B> Service for AndThen<A, B>
|
||||
where
|
||||
A: Service,
|
||||
A::Error: Into<B::Error>,
|
||||
B: Service<Request = A::Response>,
|
||||
B: Service<Request = A::Response, Error = A::Error>,
|
||||
{
|
||||
type Request = A::Request;
|
||||
type Response = B::Response;
|
||||
type Error = B::Error;
|
||||
type Error = A::Error;
|
||||
type Future = AndThenFuture<A, B>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
match self.a.poll_ready() {
|
||||
Ok(Async::Ready(_)) => self.b.borrow_mut().poll_ready(),
|
||||
Ok(Async::Ready(_)) => self.b.borrow_mut().poll_ready().map_err(|e| e.into()),
|
||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||
Err(err) => Err(err.into()),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,8 +52,7 @@ where
|
|||
pub struct AndThenFuture<A, B>
|
||||
where
|
||||
A: Service,
|
||||
A::Error: Into<B::Error>,
|
||||
B: Service<Request = A::Response>,
|
||||
B: Service<Request = A::Response, Error = A::Error>,
|
||||
{
|
||||
b: Rc<RefCell<B>>,
|
||||
fut_b: Option<B::Future>,
|
||||
|
@ -65,8 +62,7 @@ where
|
|||
impl<A, B> AndThenFuture<A, B>
|
||||
where
|
||||
A: Service,
|
||||
A::Error: Into<B::Error>,
|
||||
B: Service<Request = A::Response>,
|
||||
B: Service<Request = A::Response, Error = A::Error>,
|
||||
{
|
||||
fn new(fut_a: A::Future, b: Rc<RefCell<B>>) -> Self {
|
||||
AndThenFuture {
|
||||
|
@ -80,15 +76,15 @@ where
|
|||
impl<A, B> Future for AndThenFuture<A, B>
|
||||
where
|
||||
A: Service,
|
||||
A::Error: Into<B::Error>,
|
||||
B: Service<Request = A::Response>,
|
||||
B: Service<Request = A::Response, Error = A::Error>,
|
||||
B::Error: Into<A::Error>,
|
||||
{
|
||||
type Item = B::Response;
|
||||
type Error = B::Error;
|
||||
type Error = A::Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
if let Some(ref mut fut) = self.fut_b {
|
||||
return fut.poll();
|
||||
return fut.poll().map_err(|e| e.into());
|
||||
}
|
||||
|
||||
match self.fut_a.poll() {
|
||||
|
@ -97,7 +93,7 @@ where
|
|||
self.poll()
|
||||
}
|
||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||
Err(err) => Err(err.into()),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,17 +120,15 @@ where
|
|||
|
||||
impl<A, B> NewService for AndThenNewService<A, B>
|
||||
where
|
||||
A: NewService<Response = B::Request, InitError = B::InitError>,
|
||||
A::Error: Into<B::Error>,
|
||||
A::InitError: Into<B::InitError>,
|
||||
B: NewService,
|
||||
A: NewService,
|
||||
B: NewService<Request = A::Response, Error = A::Error, InitError = A::InitError>,
|
||||
{
|
||||
type Request = A::Request;
|
||||
type Response = B::Response;
|
||||
type Error = B::Error;
|
||||
type Error = A::Error;
|
||||
type Service = AndThen<A::Service, B::Service>;
|
||||
|
||||
type InitError = B::InitError;
|
||||
type InitError = A::InitError;
|
||||
type Future = AndThenNewServiceFuture<A, B>;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
|
@ -144,10 +138,8 @@ where
|
|||
|
||||
impl<A, B> Clone for AndThenNewService<A, B>
|
||||
where
|
||||
A: NewService<Response = B::Request, InitError = B::InitError> + Clone,
|
||||
A::Error: Into<B::Error>,
|
||||
A::InitError: Into<B::InitError>,
|
||||
B: NewService + Clone,
|
||||
A: NewService + Clone,
|
||||
B: NewService<Request = A::Response, Error = A::Error, InitError = A::InitError> + Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
|
@ -186,22 +178,20 @@ where
|
|||
impl<A, B> Future for AndThenNewServiceFuture<A, B>
|
||||
where
|
||||
A: NewService,
|
||||
A::Error: Into<B::Error>,
|
||||
A::InitError: Into<B::InitError>,
|
||||
B: NewService<Request = A::Response>,
|
||||
B: NewService<Request = A::Response, Error = A::Error, InitError = A::InitError>,
|
||||
{
|
||||
type Item = AndThen<A::Service, B::Service>;
|
||||
type Error = B::InitError;
|
||||
type Error = A::InitError;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
if self.a.is_none() {
|
||||
if let Async::Ready(service) = self.fut_a.poll().map_err(|e| e.into())? {
|
||||
if let Async::Ready(service) = self.fut_a.poll()? {
|
||||
self.a = Some(service);
|
||||
}
|
||||
}
|
||||
|
||||
if self.b.is_none() {
|
||||
if let Async::Ready(service) = self.fut_b.poll()? {
|
||||
if let Async::Ready(service) = self.fut_b.poll().map_err(|e| e.into())? {
|
||||
self.b = Some(service);
|
||||
}
|
||||
}
|
||||
|
|
61
src/service/from_err.rs
Normal file
61
src/service/from_err.rs
Normal file
|
@ -0,0 +1,61 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use futures::{Future, Poll};
|
||||
use tower_service::Service;
|
||||
|
||||
pub struct FromErr<A, E>
|
||||
where
|
||||
A: Service,
|
||||
{
|
||||
service: A,
|
||||
f: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<A: Service, E: From<A::Error>> FromErr<A, E> {
|
||||
pub(crate) fn new(service: A) -> Self {
|
||||
FromErr {
|
||||
service,
|
||||
f: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, E> Service for FromErr<A, E>
|
||||
where
|
||||
A: Service,
|
||||
E: From<A::Error>,
|
||||
{
|
||||
type Request = A::Request;
|
||||
type Response = A::Response;
|
||||
type Error = E;
|
||||
type Future = FromErrFuture<A, E>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), E> {
|
||||
Ok(self.service.poll_ready().map_err(E::from)?)
|
||||
}
|
||||
|
||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||
FromErrFuture {
|
||||
fut: self.service.call(req),
|
||||
f: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FromErrFuture<A: Service, E> {
|
||||
fut: A::Future,
|
||||
f: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<A, E> Future for FromErrFuture<A, E>
|
||||
where
|
||||
A: Service,
|
||||
E: From<A::Error>,
|
||||
{
|
||||
type Item = A::Response;
|
||||
type Error = E;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
self.fut.poll().map_err(E::from)
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ mod and_then;
|
|||
mod apply;
|
||||
mod fn_service;
|
||||
mod fn_state_service;
|
||||
mod from_err;
|
||||
mod map;
|
||||
mod map_err;
|
||||
mod map_init_err;
|
||||
|
@ -12,6 +13,7 @@ pub use self::and_then::{AndThen, AndThenNewService};
|
|||
pub use self::apply::{Apply, ApplyNewService};
|
||||
pub use self::fn_service::{FnNewService, FnService};
|
||||
pub use self::fn_state_service::{FnStateNewService, FnStateService};
|
||||
pub use self::from_err::FromErr;
|
||||
pub use self::map::{Map, MapNewService};
|
||||
pub use self::map_err::{MapErr, MapErrNewService};
|
||||
pub use self::map_init_err::MapInitErr;
|
||||
|
@ -37,6 +39,14 @@ pub trait ServiceExt: Service {
|
|||
AndThen::new(self, service.into_service())
|
||||
}
|
||||
|
||||
fn from_err<E>(self) -> FromErr<Self, E>
|
||||
where
|
||||
Self: Sized,
|
||||
E: From<Self::Error>,
|
||||
{
|
||||
FromErr::new(self)
|
||||
}
|
||||
|
||||
fn map<F, R>(self, f: F) -> Map<Self, F, R>
|
||||
where
|
||||
Self: Sized,
|
||||
|
|
|
@ -92,38 +92,57 @@ impl<T: AsyncRead + AsyncWrite> Service for OpensslAcceptorService<T> {
|
|||
}
|
||||
|
||||
/// Openssl connector factory
|
||||
pub struct OpensslConnector<T, Io> {
|
||||
pub struct OpensslConnector<T, Io, E> {
|
||||
connector: SslConnector,
|
||||
t: PhantomData<T>,
|
||||
io: PhantomData<Io>,
|
||||
_e: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<T, Io> OpensslConnector<T, Io> {
|
||||
impl<T, Io, E> OpensslConnector<T, Io, E> {
|
||||
pub fn new(connector: SslConnector) -> Self {
|
||||
OpensslConnector {
|
||||
connector,
|
||||
t: PhantomData,
|
||||
io: PhantomData,
|
||||
_e: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Io> Clone for OpensslConnector<T, Io> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
connector: self.connector.clone(),
|
||||
impl<T, Io: AsyncRead + AsyncWrite> OpensslConnector<T, Io, ()> {
|
||||
pub fn service(
|
||||
connector: SslConnector,
|
||||
) -> impl Service<
|
||||
Request = (T, ConnectionInfo, Io),
|
||||
Response = (T, ConnectionInfo, SslStream<Io>),
|
||||
Error = Error,
|
||||
> {
|
||||
OpensslConnectorService {
|
||||
connector: connector,
|
||||
t: PhantomData,
|
||||
io: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Io: AsyncRead + AsyncWrite> NewService for OpensslConnector<T, Io> {
|
||||
impl<T, Io, E> Clone for OpensslConnector<T, Io, E> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
connector: self.connector.clone(),
|
||||
t: PhantomData,
|
||||
io: PhantomData,
|
||||
_e: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Io: AsyncRead + AsyncWrite, E> NewService for OpensslConnector<T, Io, E> {
|
||||
type Request = (T, ConnectionInfo, Io);
|
||||
type Response = (T, ConnectionInfo, SslStream<Io>);
|
||||
type Error = Error;
|
||||
type Service = OpensslConnectorService<T, Io>;
|
||||
type InitError = io::Error;
|
||||
type InitError = E;
|
||||
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
|
|
Loading…
Reference in a new issue