mirror of
https://github.com/actix/actix-extras.git
synced 2025-06-25 01:51:23 +02:00
move fs to separate crate
This commit is contained in:
118
src/app.rs
118
src/app.rs
@ -5,6 +5,7 @@ use std::rc::Rc;
|
||||
use actix_http::body::{Body, MessageBody};
|
||||
use actix_http::{Extensions, PayloadStream, Request, Response};
|
||||
use actix_router::{Path, ResourceDef, ResourceInfo, Router, Url};
|
||||
use actix_service::boxed::{self, BoxedNewService, BoxedService};
|
||||
use actix_service::{
|
||||
AndThenNewService, ApplyNewService, IntoNewService, IntoNewTransform, NewService,
|
||||
NewTransform, Service,
|
||||
@ -12,13 +13,12 @@ use actix_service::{
|
||||
use futures::future::{ok, Either, FutureResult};
|
||||
use futures::{Async, Future, IntoFuture, Poll};
|
||||
|
||||
use crate::helpers::{
|
||||
BoxedHttpNewService, BoxedHttpService, DefaultNewService, HttpDefaultNewService,
|
||||
};
|
||||
use crate::resource::Resource;
|
||||
use crate::service::{ServiceRequest, ServiceResponse};
|
||||
use crate::state::{State, StateFactory, StateFactoryResult};
|
||||
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
||||
type HttpNewService<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
||||
type BoxedResponse = Box<Future<Item = ServiceResponse, Error = ()>>;
|
||||
|
||||
pub trait HttpServiceFactory<Request> {
|
||||
@ -31,18 +31,9 @@ pub trait HttpServiceFactory<Request> {
|
||||
|
||||
/// Application builder
|
||||
pub struct App<P, B, T> {
|
||||
services: Vec<(
|
||||
ResourceDef,
|
||||
BoxedHttpNewService<ServiceRequest<P>, ServiceResponse>,
|
||||
)>,
|
||||
default: Option<Rc<HttpDefaultNewService<ServiceRequest<P>, ServiceResponse>>>,
|
||||
defaults: Vec<
|
||||
Rc<
|
||||
RefCell<
|
||||
Option<Rc<HttpDefaultNewService<ServiceRequest<P>, ServiceResponse>>>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
services: Vec<(ResourceDef, HttpNewService<P>)>,
|
||||
default: Option<Rc<HttpNewService<P>>>,
|
||||
defaults: Vec<Rc<RefCell<Option<Rc<HttpNewService<P>>>>>>,
|
||||
endpoint: T,
|
||||
factory_ref: Rc<RefCell<Option<AppFactory<P>>>>,
|
||||
extensions: Extensions,
|
||||
@ -181,10 +172,8 @@ where
|
||||
let rdef = ResourceDef::new(path);
|
||||
let resource = f(Resource::new());
|
||||
self.defaults.push(resource.get_default());
|
||||
self.services.push((
|
||||
rdef,
|
||||
Box::new(HttpNewService::new(resource.into_new_service())),
|
||||
));
|
||||
self.services
|
||||
.push((rdef, boxed::new_service(resource.into_new_service())));
|
||||
self
|
||||
}
|
||||
|
||||
@ -203,9 +192,9 @@ where
|
||||
> + 'static,
|
||||
{
|
||||
// create and configure default resource
|
||||
self.default = Some(Rc::new(Box::new(DefaultNewService::new(
|
||||
f(Resource::new()).into_new_service(),
|
||||
))));
|
||||
self.default = Some(Rc::new(boxed::new_service(
|
||||
f(Resource::new()).into_new_service().map_init_err(|_| ()),
|
||||
)));
|
||||
|
||||
self
|
||||
}
|
||||
@ -223,7 +212,7 @@ where
|
||||
{
|
||||
self.services.push((
|
||||
rdef.into(),
|
||||
Box::new(HttpNewService::new(factory.into_new_service())),
|
||||
boxed::new_service(factory.into_new_service().map_init_err(|_| ())),
|
||||
));
|
||||
self
|
||||
}
|
||||
@ -422,15 +411,10 @@ impl<P> Service for AppStateService<P> {
|
||||
}
|
||||
|
||||
pub struct AppFactory<P> {
|
||||
services: Rc<
|
||||
Vec<(
|
||||
ResourceDef,
|
||||
BoxedHttpNewService<ServiceRequest<P>, ServiceResponse>,
|
||||
)>,
|
||||
>,
|
||||
services: Rc<Vec<(ResourceDef, HttpNewService<P>)>>,
|
||||
}
|
||||
|
||||
impl<P> NewService for AppFactory<P> {
|
||||
impl<P: 'static> NewService for AppFactory<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
@ -454,8 +438,7 @@ impl<P> NewService for AppFactory<P> {
|
||||
}
|
||||
}
|
||||
|
||||
type HttpServiceFut<P> =
|
||||
Box<Future<Item = BoxedHttpService<ServiceRequest<P>, ServiceResponse>, Error = ()>>;
|
||||
type HttpServiceFut<P> = Box<Future<Item = HttpService<P>, Error = ()>>;
|
||||
|
||||
/// Create app service
|
||||
#[doc(hidden)]
|
||||
@ -465,10 +448,7 @@ pub struct CreateAppService<P> {
|
||||
|
||||
enum CreateAppServiceItem<P> {
|
||||
Future(Option<ResourceDef>, HttpServiceFut<P>),
|
||||
Service(
|
||||
ResourceDef,
|
||||
BoxedHttpService<ServiceRequest<P>, ServiceResponse>,
|
||||
),
|
||||
Service(ResourceDef, HttpService<P>),
|
||||
}
|
||||
|
||||
impl<P> Future for CreateAppService<P> {
|
||||
@ -522,7 +502,7 @@ impl<P> Future for CreateAppService<P> {
|
||||
}
|
||||
|
||||
pub struct AppService<P> {
|
||||
router: Router<BoxedHttpService<ServiceRequest<P>, ServiceResponse>>,
|
||||
router: Router<HttpService<P>>,
|
||||
ready: Option<(ServiceRequest<P>, ResourceInfo)>,
|
||||
}
|
||||
|
||||
@ -561,68 +541,6 @@ impl Future for AppServiceResponse {
|
||||
}
|
||||
}
|
||||
|
||||
struct HttpNewService<P: 'static, T: NewService<Request = ServiceRequest<P>>>(T);
|
||||
|
||||
impl<P, T> HttpNewService<P, T>
|
||||
where
|
||||
T: NewService<Request = ServiceRequest<P>, Response = ServiceResponse, Error = ()>,
|
||||
T::Future: 'static,
|
||||
<T::Service as Service>::Future: 'static,
|
||||
{
|
||||
pub fn new(service: T) -> Self {
|
||||
HttpNewService(service)
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: 'static, T> NewService for HttpNewService<P, T>
|
||||
where
|
||||
T: NewService<Request = ServiceRequest<P>, Response = ServiceResponse, Error = ()>,
|
||||
T::Future: 'static,
|
||||
T::Service: 'static,
|
||||
<T::Service as Service>::Future: 'static,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type InitError = ();
|
||||
type Service = BoxedHttpService<ServiceRequest<P>, Self::Response>;
|
||||
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
Box::new(self.0.new_service(&()).map_err(|_| ()).and_then(|service| {
|
||||
let service: BoxedHttpService<_, _> = Box::new(HttpServiceWrapper {
|
||||
service,
|
||||
_t: PhantomData,
|
||||
});
|
||||
Ok(service)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
struct HttpServiceWrapper<T: Service, P> {
|
||||
service: T,
|
||||
_t: PhantomData<(P,)>,
|
||||
}
|
||||
|
||||
impl<T, P> Service for HttpServiceWrapper<T, P>
|
||||
where
|
||||
T::Future: 'static,
|
||||
T: Service<Request = ServiceRequest<P>, Response = ServiceResponse, Error = ()>,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Future = BoxedResponse;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.service.poll_ready().map_err(|_| ())
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||
Box::new(self.service.call(req))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct AppEntry<P> {
|
||||
factory: Rc<RefCell<Option<AppFactory<P>>>>,
|
||||
@ -634,7 +552,7 @@ impl<P> AppEntry<P> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> NewService for AppEntry<P> {
|
||||
impl<P: 'static> NewService for AppEntry<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
|
@ -1,240 +0,0 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
|
||||
use actix_codec::Framed;
|
||||
use actix_http::h1::Codec;
|
||||
use actix_http::{Request, Response, SendResponse};
|
||||
use actix_router::{Path, Router, Url};
|
||||
use actix_service::{IntoNewService, NewService, Service};
|
||||
use actix_utils::cloneable::CloneableService;
|
||||
use futures::{Async, Future, Poll};
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
|
||||
use crate::app::{HttpServiceFactory, State};
|
||||
use crate::framed_handler::FramedRequest;
|
||||
use crate::helpers::{BoxedHttpNewService, BoxedHttpService, HttpNewService};
|
||||
use crate::request::Request as WebRequest;
|
||||
|
||||
pub type FRequest<T> = (Request, Framed<T, Codec>);
|
||||
type BoxedResponse = Box<Future<Item = (), Error = ()>>;
|
||||
|
||||
/// Application builder
|
||||
pub struct FramedApp<T, S = ()> {
|
||||
services: Vec<(String, BoxedHttpNewService<FramedRequest<S, T>, ()>)>,
|
||||
state: State<S>,
|
||||
}
|
||||
|
||||
impl<T: 'static> FramedApp<T, ()> {
|
||||
pub fn new() -> Self {
|
||||
FramedApp {
|
||||
services: Vec::new(),
|
||||
state: State::new(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static, S: 'static> FramedApp<T, S> {
|
||||
pub fn with(state: S) -> FramedApp<T, S> {
|
||||
FramedApp {
|
||||
services: Vec::new(),
|
||||
state: State::new(state),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn service<U>(mut self, factory: U) -> Self
|
||||
where
|
||||
U: HttpServiceFactory<S>,
|
||||
U::Factory: NewService<Request = FramedRequest<S, T>, Response = ()> + 'static,
|
||||
<U::Factory as NewService>::Future: 'static,
|
||||
<U::Factory as NewService>::Service: Service<Request = FramedRequest<S, T>>,
|
||||
<<U::Factory as NewService>::Service as Service>::Future: 'static,
|
||||
{
|
||||
let path = factory.path().to_string();
|
||||
self.services.push((
|
||||
path,
|
||||
Box::new(HttpNewService::new(factory.create(self.state.clone()))),
|
||||
));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn register_service<U>(&mut self, factory: U)
|
||||
where
|
||||
U: HttpServiceFactory<S>,
|
||||
U::Factory: NewService<Request = FramedRequest<S, T>, Response = ()> + 'static,
|
||||
<U::Factory as NewService>::Future: 'static,
|
||||
<U::Factory as NewService>::Service: Service<Request = FramedRequest<S, T>>,
|
||||
<<U::Factory as NewService>::Service as Service>::Future: 'static,
|
||||
{
|
||||
let path = factory.path().to_string();
|
||||
self.services.push((
|
||||
path,
|
||||
Box::new(HttpNewService::new(factory.create(self.state.clone()))),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static, S: 'static> IntoNewService<FramedAppFactory<S, T>> for FramedApp<T, S>
|
||||
where
|
||||
T: AsyncRead + AsyncWrite,
|
||||
{
|
||||
fn into_new_service(self) -> FramedAppFactory<S, T> {
|
||||
FramedAppFactory {
|
||||
state: self.state,
|
||||
services: Rc::new(self.services),
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FramedAppFactory<S, T> {
|
||||
state: State<S>,
|
||||
services: Rc<Vec<(String, BoxedHttpNewService<FramedRequest<S, T>, ()>)>>,
|
||||
_t: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<S: 'static, T: 'static> NewService for FramedAppFactory<S, T>
|
||||
where
|
||||
T: AsyncRead + AsyncWrite,
|
||||
{
|
||||
type Request = FRequest<T>;
|
||||
type Response = ();
|
||||
type Error = ();
|
||||
type InitError = ();
|
||||
type Service = CloneableService<FramedAppService<S, T>>;
|
||||
type Future = CreateService<S, T>;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
CreateService {
|
||||
fut: self
|
||||
.services
|
||||
.iter()
|
||||
.map(|(path, service)| {
|
||||
CreateServiceItem::Future(Some(path.clone()), service.new_service())
|
||||
})
|
||||
.collect(),
|
||||
state: self.state.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct CreateService<S, T> {
|
||||
fut: Vec<CreateServiceItem<S, T>>,
|
||||
state: State<S>,
|
||||
}
|
||||
|
||||
enum CreateServiceItem<S, T> {
|
||||
Future(
|
||||
Option<String>,
|
||||
Box<Future<Item = BoxedHttpService<FramedRequest<S, T>, ()>, Error = ()>>,
|
||||
),
|
||||
Service(String, BoxedHttpService<FramedRequest<S, T>, ()>),
|
||||
}
|
||||
|
||||
impl<S: 'static, T: 'static> Future for CreateService<S, T>
|
||||
where
|
||||
T: AsyncRead + AsyncWrite,
|
||||
{
|
||||
type Item = CloneableService<FramedAppService<S, T>>;
|
||||
type Error = ();
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
let mut done = true;
|
||||
|
||||
// poll http services
|
||||
for item in &mut self.fut {
|
||||
let res = match item {
|
||||
CreateServiceItem::Future(ref mut path, ref mut fut) => {
|
||||
match fut.poll()? {
|
||||
Async::Ready(service) => Some((path.take().unwrap(), service)),
|
||||
Async::NotReady => {
|
||||
done = false;
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
CreateServiceItem::Service(_, _) => continue,
|
||||
};
|
||||
|
||||
if let Some((path, service)) = res {
|
||||
*item = CreateServiceItem::Service(path, service);
|
||||
}
|
||||
}
|
||||
|
||||
if done {
|
||||
let router = self
|
||||
.fut
|
||||
.drain(..)
|
||||
.fold(Router::build(), |mut router, item| {
|
||||
match item {
|
||||
CreateServiceItem::Service(path, service) => {
|
||||
router.path(&path, service)
|
||||
}
|
||||
CreateServiceItem::Future(_, _) => unreachable!(),
|
||||
}
|
||||
router
|
||||
});
|
||||
Ok(Async::Ready(CloneableService::new(FramedAppService {
|
||||
router: router.finish(),
|
||||
state: self.state.clone(),
|
||||
// default: self.default.take().expect("something is wrong"),
|
||||
})))
|
||||
} else {
|
||||
Ok(Async::NotReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FramedAppService<S, T> {
|
||||
state: State<S>,
|
||||
router: Router<BoxedHttpService<FramedRequest<S, T>, ()>>,
|
||||
}
|
||||
|
||||
impl<S: 'static, T: 'static> Service for FramedAppService<S, T>
|
||||
where
|
||||
T: AsyncRead + AsyncWrite,
|
||||
{
|
||||
type Request = FRequest<T>;
|
||||
type Response = ();
|
||||
type Error = ();
|
||||
type Future = BoxedResponse;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
// let mut ready = true;
|
||||
// for service in &mut self.services {
|
||||
// if let Async::NotReady = service.poll_ready()? {
|
||||
// ready = false;
|
||||
// }
|
||||
// }
|
||||
// if ready {
|
||||
// Ok(Async::Ready(()))
|
||||
// } else {
|
||||
// Ok(Async::NotReady)
|
||||
// }
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, (req, framed): (Request, Framed<T, Codec>)) -> Self::Future {
|
||||
let mut path = Path::new(Url::new(req.uri().clone()));
|
||||
|
||||
if let Some((srv, _info)) = self.router.recognize_mut(&mut path) {
|
||||
return srv.call(FramedRequest::new(
|
||||
WebRequest::new(self.state.clone(), req, path),
|
||||
framed,
|
||||
));
|
||||
}
|
||||
// for item in &mut self.services {
|
||||
// req = match item.handle(req) {
|
||||
// Ok(fut) => return fut,
|
||||
// Err(req) => req,
|
||||
// };
|
||||
// }
|
||||
// self.default.call(req)
|
||||
Box::new(
|
||||
SendResponse::send(framed, Response::NotFound().finish().into())
|
||||
.map(|_| ())
|
||||
.map_err(|_| ()),
|
||||
)
|
||||
}
|
||||
}
|
@ -1,379 +0,0 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
|
||||
use actix_codec::Framed;
|
||||
use actix_http::{h1::Codec, Error};
|
||||
use actix_service::{NewService, Service};
|
||||
use futures::future::{ok, FutureResult};
|
||||
use futures::{Async, Future, IntoFuture, Poll};
|
||||
use log::error;
|
||||
|
||||
use crate::handler::FromRequest;
|
||||
use crate::request::Request;
|
||||
|
||||
pub struct FramedError<Io> {
|
||||
pub err: Error,
|
||||
pub framed: Framed<Io, Codec>,
|
||||
}
|
||||
|
||||
pub struct FramedRequest<S, Io, Ex = ()> {
|
||||
req: Request<S>,
|
||||
framed: Framed<Io, Codec>,
|
||||
param: Ex,
|
||||
}
|
||||
|
||||
impl<S, Io> FramedRequest<S, Io, ()> {
|
||||
pub fn new(req: Request<S>, framed: Framed<Io, Codec>) -> Self {
|
||||
Self {
|
||||
req,
|
||||
framed,
|
||||
param: (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, Io, Ex> FramedRequest<S, Io, Ex> {
|
||||
pub fn request(&self) -> &Request<S> {
|
||||
&self.req
|
||||
}
|
||||
|
||||
pub fn request_mut(&mut self) -> &mut Request<S> {
|
||||
&mut self.req
|
||||
}
|
||||
|
||||
pub fn into_parts(self) -> (Request<S>, Framed<Io, Codec>, Ex) {
|
||||
(self.req, self.framed, self.param)
|
||||
}
|
||||
|
||||
pub fn map<Ex2, F>(self, op: F) -> FramedRequest<S, Io, Ex2>
|
||||
where
|
||||
F: FnOnce(Ex) -> Ex2,
|
||||
{
|
||||
FramedRequest {
|
||||
req: self.req,
|
||||
framed: self.framed,
|
||||
param: op(self.param),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// T handler converter factory
|
||||
pub trait FramedFactory<S, Io, Ex, T, R, E>: Clone + 'static
|
||||
where
|
||||
R: IntoFuture<Item = (), Error = E>,
|
||||
E: Into<Error>,
|
||||
{
|
||||
fn call(&self, framed: Framed<Io, Codec>, param: T, extra: Ex) -> R;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct FramedHandle<F, S, Io, Ex, T, R, E>
|
||||
where
|
||||
F: FramedFactory<S, Io, Ex, T, R, E>,
|
||||
R: IntoFuture<Item = (), Error = E>,
|
||||
E: Into<Error>,
|
||||
{
|
||||
hnd: F,
|
||||
_t: PhantomData<(S, Io, Ex, T, R, E)>,
|
||||
}
|
||||
|
||||
impl<F, S, Io, Ex, T, R, E> FramedHandle<F, S, Io, Ex, T, R, E>
|
||||
where
|
||||
F: FramedFactory<S, Io, Ex, T, R, E>,
|
||||
R: IntoFuture<Item = (), Error = E>,
|
||||
E: Into<Error>,
|
||||
{
|
||||
pub fn new(hnd: F) -> Self {
|
||||
FramedHandle {
|
||||
hnd,
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<F, S, Io, Ex, T, R, E> NewService for FramedHandle<F, S, Io, Ex, T, R, E>
|
||||
where
|
||||
F: FramedFactory<S, Io, Ex, T, R, E>,
|
||||
R: IntoFuture<Item = (), Error = E>,
|
||||
E: Into<Error>,
|
||||
{
|
||||
type Request = (T, FramedRequest<S, Io, Ex>);
|
||||
type Response = ();
|
||||
type Error = FramedError<Io>;
|
||||
type InitError = ();
|
||||
type Service = FramedHandleService<F, S, Io, Ex, T, R, E>;
|
||||
type Future = FutureResult<Self::Service, ()>;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
ok(FramedHandleService {
|
||||
hnd: self.hnd.clone(),
|
||||
_t: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct FramedHandleService<F, S, Io, Ex, T, R, E>
|
||||
where
|
||||
F: FramedFactory<S, Io, Ex, T, R, E>,
|
||||
R: IntoFuture<Item = (), Error = E>,
|
||||
E: Into<Error>,
|
||||
{
|
||||
hnd: F,
|
||||
_t: PhantomData<(S, Io, Ex, T, R, E)>,
|
||||
}
|
||||
|
||||
impl<F, S, Io, Ex, T, R, E> Service for FramedHandleService<F, S, Io, Ex, T, R, E>
|
||||
where
|
||||
F: FramedFactory<S, Io, Ex, T, R, E>,
|
||||
R: IntoFuture<Item = (), Error = E>,
|
||||
E: Into<Error>,
|
||||
{
|
||||
type Request = (T, FramedRequest<S, Io, Ex>);
|
||||
type Response = ();
|
||||
type Error = FramedError<Io>;
|
||||
type Future = FramedHandleServiceResponse<Io, R::Future>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, (param, framed): (T, FramedRequest<S, Io, Ex>)) -> Self::Future {
|
||||
let (_, framed, ex) = framed.into_parts();
|
||||
FramedHandleServiceResponse {
|
||||
fut: self.hnd.call(framed, param, ex).into_future(),
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct FramedHandleServiceResponse<Io, F> {
|
||||
fut: F,
|
||||
_t: PhantomData<Io>,
|
||||
}
|
||||
|
||||
impl<Io, F> Future for FramedHandleServiceResponse<Io, F>
|
||||
where
|
||||
F: Future<Item = ()>,
|
||||
F::Error: Into<Error>,
|
||||
{
|
||||
type Item = ();
|
||||
type Error = FramedError<Io>;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
match self.fut.poll() {
|
||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||
Ok(Async::Ready(res)) => Ok(Async::Ready(res.into())),
|
||||
Err(e) => {
|
||||
let e: Error = e.into();
|
||||
error!("Error in handler: {:?}", e);
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FramedExtract<S, Io, Ex, T>
|
||||
where
|
||||
T: FromRequest<S>,
|
||||
{
|
||||
cfg: Rc<T::Config>,
|
||||
_t: PhantomData<(Io, Ex)>,
|
||||
}
|
||||
|
||||
impl<S, Io, Ex, T> FramedExtract<S, Io, Ex, T>
|
||||
where
|
||||
T: FromRequest<S> + 'static,
|
||||
{
|
||||
pub fn new(cfg: T::Config) -> FramedExtract<S, Io, Ex, T> {
|
||||
FramedExtract {
|
||||
cfg: Rc::new(cfg),
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<S, Io, Ex, T> NewService for FramedExtract<S, Io, Ex, T>
|
||||
where
|
||||
T: FromRequest<S> + 'static,
|
||||
{
|
||||
type Request = FramedRequest<S, Io, Ex>;
|
||||
type Response = (T, FramedRequest<S, Io, Ex>);
|
||||
type Error = FramedError<Io>;
|
||||
type InitError = ();
|
||||
type Service = FramedExtractService<S, Io, Ex, T>;
|
||||
type Future = FutureResult<Self::Service, ()>;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
ok(FramedExtractService {
|
||||
cfg: self.cfg.clone(),
|
||||
_t: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FramedExtractService<S, Io, Ex, T>
|
||||
where
|
||||
T: FromRequest<S>,
|
||||
{
|
||||
cfg: Rc<T::Config>,
|
||||
_t: PhantomData<(Io, Ex)>,
|
||||
}
|
||||
|
||||
impl<S, Io, Ex, T> Service for FramedExtractService<S, Io, Ex, T>
|
||||
where
|
||||
T: FromRequest<S> + 'static,
|
||||
{
|
||||
type Request = FramedRequest<S, Io, Ex>;
|
||||
type Response = (T, FramedRequest<S, Io, Ex>);
|
||||
type Error = FramedError<Io>;
|
||||
type Future = FramedExtractResponse<S, Io, Ex, T>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, req: FramedRequest<S, Io, Ex>) -> Self::Future {
|
||||
FramedExtractResponse {
|
||||
fut: T::from_request(&req.request(), self.cfg.as_ref()),
|
||||
req: Some(req),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FramedExtractResponse<S, Io, Ex, T>
|
||||
where
|
||||
T: FromRequest<S> + 'static,
|
||||
{
|
||||
req: Option<FramedRequest<S, Io, Ex>>,
|
||||
fut: T::Future,
|
||||
}
|
||||
|
||||
impl<S, Io, Ex, T> Future for FramedExtractResponse<S, Io, Ex, T>
|
||||
where
|
||||
T: FromRequest<S> + 'static,
|
||||
{
|
||||
type Item = (T, FramedRequest<S, Io, Ex>);
|
||||
type Error = FramedError<Io>;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
match self.fut.poll() {
|
||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||
Ok(Async::Ready(item)) => Ok(Async::Ready((item, self.req.take().unwrap()))),
|
||||
Err(err) => Err(FramedError {
|
||||
err: err.into(),
|
||||
framed: self.req.take().unwrap().into_parts().1,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! factory_tuple ({ ($(($nex:tt, $Ex:ident)),+), $(($n:tt, $T:ident)),+} => {
|
||||
impl<Func, S, Io, $($Ex,)+ $($T,)+ Res, Err> FramedFactory<S, Io, ($($Ex,)+), ($($T,)+), Res, Err> for Func
|
||||
where Func: Fn(Framed<Io, Codec>, $($Ex,)+ $($T,)+) -> Res + Clone + 'static,
|
||||
$($T: FromRequest<S> + 'static,)+
|
||||
Res: IntoFuture<Item=(), Error=Err> + 'static,
|
||||
Err: Into<Error>,
|
||||
{
|
||||
fn call(&self, framed: Framed<Io, Codec>, param: ($($T,)+), extra: ($($Ex,)+)) -> Res {
|
||||
(self)(framed, $(extra.$nex,)+ $(param.$n,)+)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
macro_rules! factory_tuple_unit ({$(($n:tt, $T:ident)),+} => {
|
||||
impl<Func, S, Io, $($T,)+ Res, Err> FramedFactory<S, Io, (), ($($T,)+), Res, Err> for Func
|
||||
where Func: Fn(Framed<Io, Codec>, $($T,)+) -> Res + Clone + 'static,
|
||||
$($T: FromRequest<S> + 'static,)+
|
||||
Res: IntoFuture<Item=(), Error=Err> + 'static,
|
||||
Err: Into<Error>,
|
||||
{
|
||||
fn call(&self, framed: Framed<Io, Codec>, param: ($($T,)+), _extra: () ) -> Res {
|
||||
(self)(framed, $(param.$n,)+)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
mod m {
|
||||
use super::*;
|
||||
|
||||
factory_tuple_unit!((0, A));
|
||||
factory_tuple!(((0, Aex)), (0, A));
|
||||
factory_tuple!(((0, Aex), (1, Bex)), (0, A));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A));
|
||||
|
||||
factory_tuple_unit!((0, A), (1, B));
|
||||
factory_tuple!(((0, Aex)), (0, A), (1, B));
|
||||
factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B));
|
||||
|
||||
factory_tuple_unit!((0, A), (1, B), (2, C));
|
||||
factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C));
|
||||
factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C));
|
||||
|
||||
factory_tuple_unit!((0, A), (1, B), (2, C), (3, D));
|
||||
factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D));
|
||||
factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D));
|
||||
|
||||
factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E));
|
||||
factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E));
|
||||
factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E));
|
||||
|
||||
factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
|
||||
factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
|
||||
factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
|
||||
|
||||
factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
|
||||
factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
|
||||
factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
|
||||
|
||||
factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
|
||||
factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
|
||||
factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
|
||||
|
||||
factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
|
||||
factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
|
||||
factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
|
||||
|
||||
factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
|
||||
factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
|
||||
factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
|
||||
factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
|
||||
}
|
@ -1,448 +0,0 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use actix_http::http::{HeaderName, HeaderValue, Method};
|
||||
use actix_http::Error;
|
||||
use actix_service::{IntoNewService, NewService, NewServiceExt, Service};
|
||||
use futures::{try_ready, Async, Future, IntoFuture, Poll};
|
||||
use log::{debug, error};
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
|
||||
use crate::app::{HttpServiceFactory, State};
|
||||
use crate::framed_handler::{
|
||||
FramedError, FramedExtract, FramedFactory, FramedHandle, FramedRequest,
|
||||
};
|
||||
use crate::handler::FromRequest;
|
||||
|
||||
/// Resource route definition
|
||||
///
|
||||
/// Route uses builder-like pattern for configuration.
|
||||
/// If handler is not explicitly set, default *404 Not Found* handler is used.
|
||||
pub struct FramedRoute<Io, T, S = ()> {
|
||||
service: T,
|
||||
pattern: String,
|
||||
methods: Vec<Method>,
|
||||
headers: Vec<(HeaderName, HeaderValue)>,
|
||||
state: PhantomData<(S, Io)>,
|
||||
}
|
||||
|
||||
impl<Io, S> FramedRoute<Io, (), S> {
|
||||
pub fn build(path: &str) -> FramedRoutePatternBuilder<Io, S> {
|
||||
FramedRoutePatternBuilder::new(path)
|
||||
}
|
||||
|
||||
pub fn get(path: &str) -> FramedRoutePatternBuilder<Io, S> {
|
||||
FramedRoutePatternBuilder::new(path).method(Method::GET)
|
||||
}
|
||||
|
||||
pub fn post(path: &str) -> FramedRoutePatternBuilder<Io, S> {
|
||||
FramedRoutePatternBuilder::new(path).method(Method::POST)
|
||||
}
|
||||
|
||||
pub fn put(path: &str) -> FramedRoutePatternBuilder<Io, S> {
|
||||
FramedRoutePatternBuilder::new(path).method(Method::PUT)
|
||||
}
|
||||
|
||||
pub fn delete(path: &str) -> FramedRoutePatternBuilder<Io, S> {
|
||||
FramedRoutePatternBuilder::new(path).method(Method::DELETE)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Io, T, S> FramedRoute<Io, T, S>
|
||||
where
|
||||
T: NewService<
|
||||
Request = FramedRequest<S, Io>,
|
||||
Response = (),
|
||||
Error = FramedError<Io>,
|
||||
> + 'static,
|
||||
{
|
||||
pub fn new<F: IntoNewService<T>>(pattern: &str, factory: F) -> Self {
|
||||
FramedRoute {
|
||||
pattern: pattern.to_string(),
|
||||
service: factory.into_new_service(),
|
||||
headers: Vec::new(),
|
||||
methods: Vec::new(),
|
||||
state: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn method(mut self, method: Method) -> Self {
|
||||
self.methods.push(method);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn header(mut self, name: HeaderName, value: HeaderValue) -> Self {
|
||||
self.headers.push((name, value));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<Io, T, S> HttpServiceFactory<S> for FramedRoute<Io, T, S>
|
||||
where
|
||||
Io: AsyncRead + AsyncWrite + 'static,
|
||||
T: NewService<
|
||||
Request = FramedRequest<S, Io>,
|
||||
Response = (),
|
||||
Error = FramedError<Io>,
|
||||
> + 'static,
|
||||
T::Service: 'static,
|
||||
{
|
||||
type Factory = FramedRouteFactory<Io, T, S>;
|
||||
|
||||
fn path(&self) -> &str {
|
||||
&self.pattern
|
||||
}
|
||||
|
||||
fn create(self, state: State<S>) -> Self::Factory {
|
||||
FramedRouteFactory {
|
||||
state,
|
||||
service: self.service,
|
||||
pattern: self.pattern,
|
||||
methods: self.methods,
|
||||
headers: self.headers,
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FramedRouteFactory<Io, T, S> {
|
||||
service: T,
|
||||
pattern: String,
|
||||
methods: Vec<Method>,
|
||||
headers: Vec<(HeaderName, HeaderValue)>,
|
||||
state: State<S>,
|
||||
_t: PhantomData<Io>,
|
||||
}
|
||||
|
||||
impl<Io, T, S> NewService for FramedRouteFactory<Io, T, S>
|
||||
where
|
||||
Io: AsyncRead + AsyncWrite + 'static,
|
||||
T: NewService<
|
||||
Request = FramedRequest<S, Io>,
|
||||
Response = (),
|
||||
Error = FramedError<Io>,
|
||||
> + 'static,
|
||||
T::Service: 'static,
|
||||
{
|
||||
type Request = FramedRequest<S, Io>;
|
||||
type Response = T::Response;
|
||||
type Error = ();
|
||||
type InitError = T::InitError;
|
||||
type Service = FramedRouteService<Io, T::Service, S>;
|
||||
type Future = CreateRouteService<Io, T, S>;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
CreateRouteService {
|
||||
fut: self.service.new_service(),
|
||||
pattern: self.pattern.clone(),
|
||||
methods: self.methods.clone(),
|
||||
headers: self.headers.clone(),
|
||||
state: self.state.clone(),
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CreateRouteService<Io, T: NewService, S> {
|
||||
fut: T::Future,
|
||||
pattern: String,
|
||||
methods: Vec<Method>,
|
||||
headers: Vec<(HeaderName, HeaderValue)>,
|
||||
state: State<S>,
|
||||
_t: PhantomData<Io>,
|
||||
}
|
||||
|
||||
impl<Io, T, S> Future for CreateRouteService<Io, T, S>
|
||||
where
|
||||
T: NewService<
|
||||
Request = FramedRequest<S, Io>,
|
||||
Response = (),
|
||||
Error = FramedError<Io>,
|
||||
>,
|
||||
{
|
||||
type Item = FramedRouteService<Io, T::Service, S>;
|
||||
type Error = T::InitError;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
let service = try_ready!(self.fut.poll());
|
||||
|
||||
Ok(Async::Ready(FramedRouteService {
|
||||
service,
|
||||
state: self.state.clone(),
|
||||
pattern: self.pattern.clone(),
|
||||
methods: self.methods.clone(),
|
||||
headers: self.headers.clone(),
|
||||
_t: PhantomData,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FramedRouteService<Io, T, S> {
|
||||
service: T,
|
||||
pattern: String,
|
||||
methods: Vec<Method>,
|
||||
headers: Vec<(HeaderName, HeaderValue)>,
|
||||
state: State<S>,
|
||||
_t: PhantomData<Io>,
|
||||
}
|
||||
|
||||
impl<Io, T, S> Service for FramedRouteService<Io, T, S>
|
||||
where
|
||||
Io: AsyncRead + AsyncWrite + 'static,
|
||||
T: Service<Request = FramedRequest<S, Io>, Response = (), Error = FramedError<Io>>
|
||||
+ 'static,
|
||||
{
|
||||
type Request = FramedRequest<S, Io>;
|
||||
type Response = ();
|
||||
type Error = ();
|
||||
type Future = FramedRouteServiceResponse<Io, T::Future>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.service.poll_ready().map_err(|e| {
|
||||
debug!("Service not available: {}", e.err);
|
||||
()
|
||||
})
|
||||
}
|
||||
|
||||
fn call(&mut self, req: FramedRequest<S, Io>) -> Self::Future {
|
||||
FramedRouteServiceResponse {
|
||||
fut: self.service.call(req),
|
||||
send: None,
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// impl<Io, T, S> HttpService<(Request, Framed<Io, Codec>)> for FramedRouteService<Io, T, S>
|
||||
// where
|
||||
// Io: AsyncRead + AsyncWrite + 'static,
|
||||
// S: 'static,
|
||||
// T: Service<FramedRequest<S, Io>, Response = (), Error = FramedError<Io>> + 'static,
|
||||
// {
|
||||
// fn handle(
|
||||
// &mut self,
|
||||
// (req, framed): (Request, Framed<Io, Codec>),
|
||||
// ) -> Result<Self::Future, (Request, Framed<Io, Codec>)> {
|
||||
// if self.methods.is_empty()
|
||||
// || !self.methods.is_empty() && self.methods.contains(req.method())
|
||||
// {
|
||||
// if let Some(params) = self.pattern.match_with_params(&req, 0) {
|
||||
// return Ok(FramedRouteServiceResponse {
|
||||
// fut: self.service.call(FramedRequest::new(
|
||||
// WebRequest::new(self.state.clone(), req, params),
|
||||
// framed,
|
||||
// )),
|
||||
// send: None,
|
||||
// _t: PhantomData,
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// Err((req, framed))
|
||||
// }
|
||||
// }
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct FramedRouteServiceResponse<Io, F> {
|
||||
fut: F,
|
||||
send: Option<Box<Future<Item = (), Error = Error>>>,
|
||||
_t: PhantomData<Io>,
|
||||
}
|
||||
|
||||
impl<Io, F> Future for FramedRouteServiceResponse<Io, F>
|
||||
where
|
||||
F: Future<Error = FramedError<Io>>,
|
||||
Io: AsyncRead + AsyncWrite + 'static,
|
||||
{
|
||||
type Item = ();
|
||||
type Error = ();
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
if let Some(ref mut fut) = self.send {
|
||||
return match fut.poll() {
|
||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||
Ok(Async::Ready(_)) => Ok(Async::Ready(())),
|
||||
Err(e) => {
|
||||
debug!("Error during error response send: {}", e);
|
||||
Err(())
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
match self.fut.poll() {
|
||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||
Ok(Async::Ready(_)) => Ok(Async::Ready(())),
|
||||
Err(e) => {
|
||||
error!("Error occurred during request handling: {}", e.err);
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FramedRoutePatternBuilder<Io, S> {
|
||||
pattern: String,
|
||||
methods: Vec<Method>,
|
||||
headers: Vec<(HeaderName, HeaderValue)>,
|
||||
state: PhantomData<(Io, S)>,
|
||||
}
|
||||
|
||||
impl<Io, S> FramedRoutePatternBuilder<Io, S> {
|
||||
fn new(path: &str) -> FramedRoutePatternBuilder<Io, S> {
|
||||
FramedRoutePatternBuilder {
|
||||
pattern: path.to_string(),
|
||||
methods: Vec::new(),
|
||||
headers: Vec::new(),
|
||||
state: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn method(mut self, method: Method) -> Self {
|
||||
self.methods.push(method);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn map<T, U, F: IntoNewService<T>>(
|
||||
self,
|
||||
md: F,
|
||||
) -> FramedRouteBuilder<Io, S, T, (), U>
|
||||
where
|
||||
T: NewService<
|
||||
Request = FramedRequest<S, Io>,
|
||||
Response = FramedRequest<S, Io, U>,
|
||||
Error = FramedError<Io>,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
FramedRouteBuilder {
|
||||
service: md.into_new_service(),
|
||||
pattern: self.pattern,
|
||||
methods: self.methods,
|
||||
headers: self.headers,
|
||||
state: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with<F, P, R, E>(
|
||||
self,
|
||||
handler: F,
|
||||
) -> FramedRoute<
|
||||
Io,
|
||||
impl NewService<
|
||||
Request = FramedRequest<S, Io>,
|
||||
Response = (),
|
||||
Error = FramedError<Io>,
|
||||
InitError = (),
|
||||
>,
|
||||
S,
|
||||
>
|
||||
where
|
||||
F: FramedFactory<S, Io, (), P, R, E>,
|
||||
P: FromRequest<S> + 'static,
|
||||
R: IntoFuture<Item = (), Error = E>,
|
||||
E: Into<Error>,
|
||||
{
|
||||
FramedRoute {
|
||||
service: FramedExtract::new(P::Config::default())
|
||||
.and_then(FramedHandle::new(handler)),
|
||||
pattern: self.pattern,
|
||||
methods: self.methods,
|
||||
headers: self.headers,
|
||||
state: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FramedRouteBuilder<Io, S, T, U1, U2> {
|
||||
service: T,
|
||||
pattern: String,
|
||||
methods: Vec<Method>,
|
||||
headers: Vec<(HeaderName, HeaderValue)>,
|
||||
state: PhantomData<(Io, S, U1, U2)>,
|
||||
}
|
||||
|
||||
impl<Io, S, T, U1, U2> FramedRouteBuilder<Io, S, T, U1, U2>
|
||||
where
|
||||
T: NewService<
|
||||
Request = FramedRequest<S, Io, U1>,
|
||||
Response = FramedRequest<S, Io, U2>,
|
||||
Error = FramedError<Io>,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
pub fn new<F: IntoNewService<T>>(path: &str, factory: F) -> Self {
|
||||
FramedRouteBuilder {
|
||||
service: factory.into_new_service(),
|
||||
pattern: path.to_string(),
|
||||
methods: Vec::new(),
|
||||
headers: Vec::new(),
|
||||
state: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn method(mut self, method: Method) -> Self {
|
||||
self.methods.push(method);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn map<K, U3, F: IntoNewService<K>>(
|
||||
self,
|
||||
md: F,
|
||||
) -> FramedRouteBuilder<
|
||||
Io,
|
||||
S,
|
||||
impl NewService<
|
||||
Request = FramedRequest<S, Io, U1>,
|
||||
Response = FramedRequest<S, Io, U3>,
|
||||
Error = FramedError<Io>,
|
||||
InitError = (),
|
||||
>,
|
||||
U1,
|
||||
U3,
|
||||
>
|
||||
where
|
||||
K: NewService<
|
||||
Request = FramedRequest<S, Io, U2>,
|
||||
Response = FramedRequest<S, Io, U3>,
|
||||
Error = FramedError<Io>,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
FramedRouteBuilder {
|
||||
service: self.service.from_err().and_then(md.into_new_service()),
|
||||
pattern: self.pattern,
|
||||
methods: self.methods,
|
||||
headers: self.headers,
|
||||
state: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with<F, P, R, E>(
|
||||
self,
|
||||
handler: F,
|
||||
) -> FramedRoute<
|
||||
Io,
|
||||
impl NewService<
|
||||
Request = FramedRequest<S, Io, U1>,
|
||||
Response = (),
|
||||
Error = FramedError<Io>,
|
||||
InitError = (),
|
||||
>,
|
||||
S,
|
||||
>
|
||||
where
|
||||
F: FramedFactory<S, Io, U2, P, R, E>,
|
||||
P: FromRequest<S> + 'static,
|
||||
R: IntoFuture<Item = (), Error = E>,
|
||||
E: Into<Error>,
|
||||
{
|
||||
FramedRoute {
|
||||
service: self
|
||||
.service
|
||||
.and_then(FramedExtract::new(P::Config::default()))
|
||||
.and_then(FramedHandle::new(handler)),
|
||||
pattern: self.pattern,
|
||||
methods: self.methods,
|
||||
headers: self.headers,
|
||||
state: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
180
src/helpers.rs
180
src/helpers.rs
@ -1,180 +0,0 @@
|
||||
use actix_http::Response;
|
||||
use actix_service::{NewService, Service};
|
||||
use futures::future::{ok, FutureResult};
|
||||
use futures::{Future, Poll};
|
||||
|
||||
pub(crate) type BoxedHttpService<Req, Res> = Box<
|
||||
Service<
|
||||
Request = Req,
|
||||
Response = Res,
|
||||
Error = (),
|
||||
Future = Box<Future<Item = Res, Error = ()>>,
|
||||
>,
|
||||
>;
|
||||
|
||||
pub(crate) type BoxedHttpNewService<Req, Res> = Box<
|
||||
NewService<
|
||||
Request = Req,
|
||||
Response = Res,
|
||||
Error = (),
|
||||
InitError = (),
|
||||
Service = BoxedHttpService<Req, Res>,
|
||||
Future = Box<Future<Item = BoxedHttpService<Req, Res>, Error = ()>>,
|
||||
>,
|
||||
>;
|
||||
|
||||
pub(crate) struct HttpNewService<T: NewService>(T);
|
||||
|
||||
impl<T> HttpNewService<T>
|
||||
where
|
||||
T: NewService,
|
||||
T::Response: 'static,
|
||||
T::Future: 'static,
|
||||
T::Service: Service,
|
||||
<T::Service as Service>::Future: 'static,
|
||||
{
|
||||
pub fn new(service: T) -> Self {
|
||||
HttpNewService(service)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> NewService for HttpNewService<T>
|
||||
where
|
||||
T: NewService,
|
||||
T::Request: 'static,
|
||||
T::Response: 'static,
|
||||
T::Future: 'static,
|
||||
T::Service: Service + 'static,
|
||||
<T::Service as Service>::Future: 'static,
|
||||
{
|
||||
type Request = T::Request;
|
||||
type Response = T::Response;
|
||||
type Error = ();
|
||||
type InitError = ();
|
||||
type Service = BoxedHttpService<T::Request, T::Response>;
|
||||
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
Box::new(self.0.new_service(&()).map_err(|_| ()).and_then(|service| {
|
||||
let service: BoxedHttpService<_, _> =
|
||||
Box::new(HttpServiceWrapper { service });
|
||||
Ok(service)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
struct HttpServiceWrapper<T: Service> {
|
||||
service: T,
|
||||
}
|
||||
|
||||
impl<T> Service for HttpServiceWrapper<T>
|
||||
where
|
||||
T: Service,
|
||||
T::Request: 'static,
|
||||
T::Response: 'static,
|
||||
T::Future: 'static,
|
||||
{
|
||||
type Request = T::Request;
|
||||
type Response = T::Response;
|
||||
type Error = ();
|
||||
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.service.poll_ready().map_err(|_| ())
|
||||
}
|
||||
|
||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||
Box::new(self.service.call(req).map_err(|_| ()))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn not_found<Req>(_: Req) -> FutureResult<Response, ()> {
|
||||
ok(Response::NotFound().finish())
|
||||
}
|
||||
|
||||
pub(crate) type HttpDefaultService<Req, Res> = Box<
|
||||
Service<
|
||||
Request = Req,
|
||||
Response = Res,
|
||||
Error = (),
|
||||
Future = Box<Future<Item = Res, Error = ()>>,
|
||||
>,
|
||||
>;
|
||||
|
||||
pub(crate) type HttpDefaultNewService<Req, Res> = Box<
|
||||
NewService<
|
||||
Request = Req,
|
||||
Response = Res,
|
||||
Error = (),
|
||||
InitError = (),
|
||||
Service = HttpDefaultService<Req, Res>,
|
||||
Future = Box<Future<Item = HttpDefaultService<Req, Res>, Error = ()>>,
|
||||
>,
|
||||
>;
|
||||
|
||||
pub(crate) struct DefaultNewService<T: NewService> {
|
||||
service: T,
|
||||
}
|
||||
|
||||
impl<T> DefaultNewService<T>
|
||||
where
|
||||
T: NewService + 'static,
|
||||
T::Future: 'static,
|
||||
<T::Service as Service>::Future: 'static,
|
||||
{
|
||||
pub fn new(service: T) -> Self {
|
||||
DefaultNewService { service }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> NewService for DefaultNewService<T>
|
||||
where
|
||||
T: NewService + 'static,
|
||||
T::Request: 'static,
|
||||
T::Future: 'static,
|
||||
T::Service: 'static,
|
||||
<T::Service as Service>::Future: 'static,
|
||||
{
|
||||
type Request = T::Request;
|
||||
type Response = T::Response;
|
||||
type Error = ();
|
||||
type InitError = ();
|
||||
type Service = HttpDefaultService<T::Request, T::Response>;
|
||||
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
Box::new(
|
||||
self.service
|
||||
.new_service(&())
|
||||
.map_err(|_| ())
|
||||
.and_then(|service| {
|
||||
let service: HttpDefaultService<_, _> =
|
||||
Box::new(DefaultServiceWrapper { service });
|
||||
Ok(service)
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct DefaultServiceWrapper<T: Service> {
|
||||
service: T,
|
||||
}
|
||||
|
||||
impl<T> Service for DefaultServiceWrapper<T>
|
||||
where
|
||||
T: Service + 'static,
|
||||
T::Future: 'static,
|
||||
{
|
||||
type Request = T::Request;
|
||||
type Response = T::Response;
|
||||
type Error = ();
|
||||
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.service.poll_ready().map_err(|_| ())
|
||||
}
|
||||
|
||||
fn call(&mut self, req: T::Request) -> Self::Future {
|
||||
Box::new(self.service.call(req).map_err(|_| ()))
|
||||
}
|
||||
}
|
@ -3,11 +3,10 @@
|
||||
mod app;
|
||||
mod extractor;
|
||||
pub mod handler;
|
||||
mod helpers;
|
||||
// mod helpers;
|
||||
// mod info;
|
||||
pub mod blocking;
|
||||
pub mod filter;
|
||||
pub mod fs;
|
||||
pub mod middleware;
|
||||
mod request;
|
||||
mod resource;
|
||||
|
@ -2,6 +2,7 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use actix_http::{http::Method, Error, Response};
|
||||
use actix_service::boxed::{self, BoxedNewService, BoxedService};
|
||||
use actix_service::{
|
||||
ApplyNewService, IntoNewService, IntoNewTransform, NewService, NewTransform, Service,
|
||||
};
|
||||
@ -9,11 +10,13 @@ use futures::future::{ok, Either, FutureResult};
|
||||
use futures::{Async, Future, IntoFuture, Poll};
|
||||
|
||||
use crate::handler::{AsyncFactory, Factory, FromRequest};
|
||||
use crate::helpers::{DefaultNewService, HttpDefaultNewService, HttpDefaultService};
|
||||
use crate::responder::Responder;
|
||||
use crate::route::{CreateRouteService, Route, RouteBuilder, RouteService};
|
||||
use crate::service::{ServiceRequest, ServiceResponse};
|
||||
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
||||
type HttpNewService<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
||||
|
||||
/// Resource route definition
|
||||
///
|
||||
/// Route uses builder-like pattern for configuration.
|
||||
@ -21,9 +24,7 @@ use crate::service::{ServiceRequest, ServiceResponse};
|
||||
pub struct Resource<P, T = ResourceEndpoint<P>> {
|
||||
routes: Vec<Route<P>>,
|
||||
endpoint: T,
|
||||
default: Rc<
|
||||
RefCell<Option<Rc<HttpDefaultNewService<ServiceRequest<P>, ServiceResponse>>>>,
|
||||
>,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService<P>>>>>,
|
||||
factory_ref: Rc<RefCell<Option<ResourceFactory<P>>>>,
|
||||
}
|
||||
|
||||
@ -277,17 +278,14 @@ where
|
||||
> + 'static,
|
||||
{
|
||||
// create and configure default resource
|
||||
self.default = Rc::new(RefCell::new(Some(Rc::new(Box::new(
|
||||
DefaultNewService::new(f(Resource::new()).into_new_service()),
|
||||
self.default = Rc::new(RefCell::new(Some(Rc::new(boxed::new_service(
|
||||
f(Resource::new()).into_new_service().map_init_err(|_| ()),
|
||||
)))));
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn get_default(
|
||||
&self,
|
||||
) -> Rc<RefCell<Option<Rc<HttpDefaultNewService<ServiceRequest<P>, ServiceResponse>>>>>
|
||||
{
|
||||
pub(crate) fn get_default(&self) -> Rc<RefCell<Option<Rc<HttpNewService<P>>>>> {
|
||||
self.default.clone()
|
||||
}
|
||||
}
|
||||
@ -313,12 +311,10 @@ where
|
||||
|
||||
pub struct ResourceFactory<P> {
|
||||
routes: Vec<Route<P>>,
|
||||
default: Rc<
|
||||
RefCell<Option<Rc<HttpDefaultNewService<ServiceRequest<P>, ServiceResponse>>>>,
|
||||
>,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService<P>>>>>,
|
||||
}
|
||||
|
||||
impl<P> NewService for ResourceFactory<P> {
|
||||
impl<P: 'static> NewService for ResourceFactory<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
@ -352,15 +348,8 @@ enum CreateRouteServiceItem<P> {
|
||||
|
||||
pub struct CreateResourceService<P> {
|
||||
fut: Vec<CreateRouteServiceItem<P>>,
|
||||
default: Option<HttpDefaultService<ServiceRequest<P>, ServiceResponse>>,
|
||||
default_fut: Option<
|
||||
Box<
|
||||
Future<
|
||||
Item = HttpDefaultService<ServiceRequest<P>, ServiceResponse>,
|
||||
Error = (),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
default: Option<HttpService<P>>,
|
||||
default_fut: Option<Box<Future<Item = HttpService<P>, Error = ()>>>,
|
||||
}
|
||||
|
||||
impl<P> Future for CreateResourceService<P> {
|
||||
@ -413,7 +402,7 @@ impl<P> Future for CreateResourceService<P> {
|
||||
|
||||
pub struct ResourceService<P> {
|
||||
routes: Vec<RouteService<P>>,
|
||||
default: Option<HttpDefaultService<ServiceRequest<P>, ServiceResponse>>,
|
||||
default: Option<HttpService<P>>,
|
||||
}
|
||||
|
||||
impl<P> Service for ResourceService<P> {
|
||||
@ -461,7 +450,7 @@ impl<P> ResourceEndpoint<P> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> NewService for ResourceEndpoint<P> {
|
||||
impl<P: 'static> NewService for ResourceEndpoint<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
|
Reference in New Issue
Block a user