mirror of
https://github.com/actix/actix-web.git
synced 2024-12-22 16:16:40 +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>
|
impl<A, B, C> NewConfigurableService<C> for AndThenNewConfigurableService<A, B, C>
|
||||||
where
|
where
|
||||||
A: NewConfigurableService<C, Response = B::Request, InitError = B::InitError>,
|
A: NewConfigurableService<C>,
|
||||||
A::Error: Into<B::Error>,
|
B: NewConfigurableService<
|
||||||
B: NewConfigurableService<C>,
|
C,
|
||||||
|
Request = A::Response,
|
||||||
|
Error = A::Error,
|
||||||
|
InitError = A::InitError,
|
||||||
|
>,
|
||||||
C: Clone,
|
C: Clone,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
type Request = A::Request;
|
||||||
type Response = B::Response;
|
type Response = B::Response;
|
||||||
type Error = B::Error;
|
type Error = A::Error;
|
||||||
type Service = AndThen<A::Service, B::Service>;
|
type Service = AndThen<A::Service, B::Service>;
|
||||||
|
|
||||||
type InitError = A::InitError;
|
type InitError = A::InitError;
|
||||||
|
@ -282,9 +286,13 @@ where
|
||||||
|
|
||||||
impl<A, B, C> Clone for AndThenNewConfigurableService<A, B, C>
|
impl<A, B, C> Clone for AndThenNewConfigurableService<A, B, C>
|
||||||
where
|
where
|
||||||
A: NewConfigurableService<C, Response = B::Request, InitError = B::InitError> + Clone,
|
A: NewConfigurableService<C> + Clone,
|
||||||
A::Error: Into<B::Error>,
|
B: NewConfigurableService<
|
||||||
B: NewConfigurableService<C> + Clone,
|
C,
|
||||||
|
Request = A::Response,
|
||||||
|
Error = A::Error,
|
||||||
|
InitError = A::InitError,
|
||||||
|
> + Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -326,18 +334,22 @@ where
|
||||||
impl<A, B, C> Future for AndThenNewConfigurableServiceFuture<A, B, C>
|
impl<A, B, C> Future for AndThenNewConfigurableServiceFuture<A, B, C>
|
||||||
where
|
where
|
||||||
A: NewConfigurableService<C>,
|
A: NewConfigurableService<C>,
|
||||||
A::Error: Into<B::Error>,
|
B: NewConfigurableService<
|
||||||
B: NewConfigurableService<C, Request = A::Response, InitError = A::InitError>,
|
C,
|
||||||
|
Request = A::Response,
|
||||||
|
Error = A::Error,
|
||||||
|
InitError = A::InitError,
|
||||||
|
>,
|
||||||
{
|
{
|
||||||
type Item = AndThen<A::Service, B::Service>;
|
type Item = AndThen<A::Service, B::Service>;
|
||||||
type Error = B::InitError;
|
type Error = A::InitError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
if let Async::Ready(service) = self.fut_a.poll()? {
|
if let Async::Ready(service) = self.fut_a.poll()? {
|
||||||
self.a = Some(service);
|
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);
|
self.b = Some(service);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,7 @@ pub struct AndThen<A, B> {
|
||||||
impl<A, B> AndThen<A, B>
|
impl<A, B> AndThen<A, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service,
|
||||||
A::Error: Into<B::Error>,
|
B: Service<Request = A::Response, Error = A::Error>,
|
||||||
B: Service<Request = A::Response>,
|
|
||||||
{
|
{
|
||||||
/// Create new `AndThen` combinator
|
/// Create new `AndThen` combinator
|
||||||
pub fn new(a: A, b: B) -> Self {
|
pub fn new(a: A, b: B) -> Self {
|
||||||
|
@ -30,19 +29,18 @@ where
|
||||||
impl<A, B> Service for AndThen<A, B>
|
impl<A, B> Service for AndThen<A, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service,
|
||||||
A::Error: Into<B::Error>,
|
B: Service<Request = A::Response, Error = A::Error>,
|
||||||
B: Service<Request = A::Response>,
|
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
type Request = A::Request;
|
||||||
type Response = B::Response;
|
type Response = B::Response;
|
||||||
type Error = B::Error;
|
type Error = A::Error;
|
||||||
type Future = AndThenFuture<A, B>;
|
type Future = AndThenFuture<A, B>;
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
match self.a.poll_ready() {
|
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),
|
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>
|
pub struct AndThenFuture<A, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service,
|
||||||
A::Error: Into<B::Error>,
|
B: Service<Request = A::Response, Error = A::Error>,
|
||||||
B: Service<Request = A::Response>,
|
|
||||||
{
|
{
|
||||||
b: Rc<RefCell<B>>,
|
b: Rc<RefCell<B>>,
|
||||||
fut_b: Option<B::Future>,
|
fut_b: Option<B::Future>,
|
||||||
|
@ -65,8 +62,7 @@ where
|
||||||
impl<A, B> AndThenFuture<A, B>
|
impl<A, B> AndThenFuture<A, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service,
|
||||||
A::Error: Into<B::Error>,
|
B: Service<Request = A::Response, Error = A::Error>,
|
||||||
B: Service<Request = A::Response>,
|
|
||||||
{
|
{
|
||||||
fn new(fut_a: A::Future, b: Rc<RefCell<B>>) -> Self {
|
fn new(fut_a: A::Future, b: Rc<RefCell<B>>) -> Self {
|
||||||
AndThenFuture {
|
AndThenFuture {
|
||||||
|
@ -80,15 +76,15 @@ where
|
||||||
impl<A, B> Future for AndThenFuture<A, B>
|
impl<A, B> Future for AndThenFuture<A, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service,
|
||||||
A::Error: Into<B::Error>,
|
B: Service<Request = A::Response, Error = A::Error>,
|
||||||
B: Service<Request = A::Response>,
|
B::Error: Into<A::Error>,
|
||||||
{
|
{
|
||||||
type Item = B::Response;
|
type Item = B::Response;
|
||||||
type Error = B::Error;
|
type Error = A::Error;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
if let Some(ref mut fut) = self.fut_b {
|
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() {
|
match self.fut_a.poll() {
|
||||||
|
@ -97,7 +93,7 @@ where
|
||||||
self.poll()
|
self.poll()
|
||||||
}
|
}
|
||||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
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>
|
impl<A, B> NewService for AndThenNewService<A, B>
|
||||||
where
|
where
|
||||||
A: NewService<Response = B::Request, InitError = B::InitError>,
|
A: NewService,
|
||||||
A::Error: Into<B::Error>,
|
B: NewService<Request = A::Response, Error = A::Error, InitError = A::InitError>,
|
||||||
A::InitError: Into<B::InitError>,
|
|
||||||
B: NewService,
|
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
type Request = A::Request;
|
||||||
type Response = B::Response;
|
type Response = B::Response;
|
||||||
type Error = B::Error;
|
type Error = A::Error;
|
||||||
type Service = AndThen<A::Service, B::Service>;
|
type Service = AndThen<A::Service, B::Service>;
|
||||||
|
|
||||||
type InitError = B::InitError;
|
type InitError = A::InitError;
|
||||||
type Future = AndThenNewServiceFuture<A, B>;
|
type Future = AndThenNewServiceFuture<A, B>;
|
||||||
|
|
||||||
fn new_service(&self) -> Self::Future {
|
fn new_service(&self) -> Self::Future {
|
||||||
|
@ -144,10 +138,8 @@ where
|
||||||
|
|
||||||
impl<A, B> Clone for AndThenNewService<A, B>
|
impl<A, B> Clone for AndThenNewService<A, B>
|
||||||
where
|
where
|
||||||
A: NewService<Response = B::Request, InitError = B::InitError> + Clone,
|
A: NewService + Clone,
|
||||||
A::Error: Into<B::Error>,
|
B: NewService<Request = A::Response, Error = A::Error, InitError = A::InitError> + Clone,
|
||||||
A::InitError: Into<B::InitError>,
|
|
||||||
B: NewService + Clone,
|
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -186,22 +178,20 @@ where
|
||||||
impl<A, B> Future for AndThenNewServiceFuture<A, B>
|
impl<A, B> Future for AndThenNewServiceFuture<A, B>
|
||||||
where
|
where
|
||||||
A: NewService,
|
A: NewService,
|
||||||
A::Error: Into<B::Error>,
|
B: NewService<Request = A::Response, Error = A::Error, InitError = A::InitError>,
|
||||||
A::InitError: Into<B::InitError>,
|
|
||||||
B: NewService<Request = A::Response>,
|
|
||||||
{
|
{
|
||||||
type Item = AndThen<A::Service, B::Service>;
|
type Item = AndThen<A::Service, B::Service>;
|
||||||
type Error = B::InitError;
|
type Error = A::InitError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
if self.a.is_none() {
|
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);
|
self.a = Some(service);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.b.is_none() {
|
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);
|
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 apply;
|
||||||
mod fn_service;
|
mod fn_service;
|
||||||
mod fn_state_service;
|
mod fn_state_service;
|
||||||
|
mod from_err;
|
||||||
mod map;
|
mod map;
|
||||||
mod map_err;
|
mod map_err;
|
||||||
mod map_init_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::apply::{Apply, ApplyNewService};
|
||||||
pub use self::fn_service::{FnNewService, FnService};
|
pub use self::fn_service::{FnNewService, FnService};
|
||||||
pub use self::fn_state_service::{FnStateNewService, FnStateService};
|
pub use self::fn_state_service::{FnStateNewService, FnStateService};
|
||||||
|
pub use self::from_err::FromErr;
|
||||||
pub use self::map::{Map, MapNewService};
|
pub use self::map::{Map, MapNewService};
|
||||||
pub use self::map_err::{MapErr, MapErrNewService};
|
pub use self::map_err::{MapErr, MapErrNewService};
|
||||||
pub use self::map_init_err::MapInitErr;
|
pub use self::map_init_err::MapInitErr;
|
||||||
|
@ -37,6 +39,14 @@ pub trait ServiceExt: Service {
|
||||||
AndThen::new(self, service.into_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>
|
fn map<F, R>(self, f: F) -> Map<Self, F, R>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
|
|
|
@ -92,38 +92,57 @@ impl<T: AsyncRead + AsyncWrite> Service for OpensslAcceptorService<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Openssl connector factory
|
/// Openssl connector factory
|
||||||
pub struct OpensslConnector<T, Io> {
|
pub struct OpensslConnector<T, Io, E> {
|
||||||
connector: SslConnector,
|
connector: SslConnector,
|
||||||
t: PhantomData<T>,
|
t: PhantomData<T>,
|
||||||
io: PhantomData<Io>,
|
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 {
|
pub fn new(connector: SslConnector) -> Self {
|
||||||
OpensslConnector {
|
OpensslConnector {
|
||||||
connector,
|
connector,
|
||||||
t: PhantomData,
|
t: PhantomData,
|
||||||
io: PhantomData,
|
io: PhantomData,
|
||||||
|
_e: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Io> Clone for OpensslConnector<T, Io> {
|
impl<T, Io: AsyncRead + AsyncWrite> OpensslConnector<T, Io, ()> {
|
||||||
fn clone(&self) -> Self {
|
pub fn service(
|
||||||
Self {
|
connector: SslConnector,
|
||||||
connector: self.connector.clone(),
|
) -> impl Service<
|
||||||
|
Request = (T, ConnectionInfo, Io),
|
||||||
|
Response = (T, ConnectionInfo, SslStream<Io>),
|
||||||
|
Error = Error,
|
||||||
|
> {
|
||||||
|
OpensslConnectorService {
|
||||||
|
connector: connector,
|
||||||
t: PhantomData,
|
t: PhantomData,
|
||||||
io: 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 Request = (T, ConnectionInfo, Io);
|
||||||
type Response = (T, ConnectionInfo, SslStream<Io>);
|
type Response = (T, ConnectionInfo, SslStream<Io>);
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Service = OpensslConnectorService<T, Io>;
|
type Service = OpensslConnectorService<T, Io>;
|
||||||
type InitError = io::Error;
|
type InitError = E;
|
||||||
type Future = FutureResult<Self::Service, Self::InitError>;
|
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||||
|
|
||||||
fn new_service(&self) -> Self::Future {
|
fn new_service(&self) -> Self::Future {
|
||||||
|
|
Loading…
Reference in a new issue