1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-02-07 22:04:24 +01:00

160 lines
4.1 KiB
Rust
Raw Normal View History

2019-04-10 15:06:27 -07:00
use std::fmt;
2019-11-21 12:17:01 +06:00
use std::future::Future;
2019-04-10 15:06:27 -07:00
use std::marker::PhantomData;
2019-11-21 12:17:01 +06:00
use std::task::{Context, Poll};
2019-04-10 15:06:27 -07:00
use actix_codec::{AsyncRead, AsyncWrite};
use actix_http::{http::Method, Error};
2019-11-21 12:17:01 +06:00
use actix_service::{Service, ServiceFactory};
use futures::future::{ok, FutureExt, LocalBoxFuture, Ready};
2019-04-10 15:06:27 -07:00
use log::error;
use crate::app::HttpServiceFactory;
use crate::request::FramedRequest;
/// Resource route definition
///
/// Route uses builder-like pattern for configuration.
/// If handler is not explicitly set, default *404 Not Found* handler is used.
2019-11-21 12:17:01 +06:00
pub struct FramedRoute<Io, S, F = (), R = (), E = ()> {
2019-04-10 15:06:27 -07:00
handler: F,
pattern: String,
methods: Vec<Method>,
2019-11-21 12:17:01 +06:00
state: PhantomData<(Io, S, R, E)>,
2019-04-10 15:06:27 -07:00
}
2019-04-10 18:08:28 -07:00
impl<Io, S> FramedRoute<Io, S> {
pub fn new(pattern: &str) -> Self {
FramedRoute {
handler: (),
pattern: pattern.to_string(),
methods: Vec::new(),
state: PhantomData,
}
2019-04-10 15:06:27 -07:00
}
2019-04-10 18:08:28 -07:00
pub fn get(path: &str) -> FramedRoute<Io, S> {
FramedRoute::new(path).method(Method::GET)
2019-04-10 15:06:27 -07:00
}
2019-04-10 18:08:28 -07:00
pub fn post(path: &str) -> FramedRoute<Io, S> {
FramedRoute::new(path).method(Method::POST)
2019-04-10 15:06:27 -07:00
}
2019-04-10 18:08:28 -07:00
pub fn put(path: &str) -> FramedRoute<Io, S> {
FramedRoute::new(path).method(Method::PUT)
2019-04-10 15:06:27 -07:00
}
2019-04-10 18:08:28 -07:00
pub fn delete(path: &str) -> FramedRoute<Io, S> {
FramedRoute::new(path).method(Method::DELETE)
2019-04-10 15:06:27 -07:00
}
2019-04-10 18:08:28 -07:00
pub fn method(mut self, method: Method) -> Self {
self.methods.push(method);
self
}
2019-11-21 12:17:01 +06:00
pub fn to<F, R, E>(self, handler: F) -> FramedRoute<Io, S, F, R, E>
2019-04-10 18:08:28 -07:00
where
F: FnMut(FramedRequest<Io, S>) -> R,
2019-11-21 12:17:01 +06:00
R: Future<Output = Result<(), E>> + 'static,
E: fmt::Debug,
2019-04-10 18:08:28 -07:00
{
2019-04-10 15:06:27 -07:00
FramedRoute {
handler,
2019-04-10 18:08:28 -07:00
pattern: self.pattern,
methods: self.methods,
2019-04-10 15:06:27 -07:00
state: PhantomData,
}
}
}
2019-11-21 12:17:01 +06:00
impl<Io, S, F, R, E> HttpServiceFactory for FramedRoute<Io, S, F, R, E>
2019-04-10 15:06:27 -07:00
where
Io: AsyncRead + AsyncWrite + 'static,
F: FnMut(FramedRequest<Io, S>) -> R + Clone,
2019-11-21 12:17:01 +06:00
R: Future<Output = Result<(), E>> + 'static,
E: fmt::Display,
2019-04-10 15:06:27 -07:00
{
2019-11-21 12:17:01 +06:00
type Factory = FramedRouteFactory<Io, S, F, R, E>;
2019-04-10 15:06:27 -07:00
fn path(&self) -> &str {
&self.pattern
}
fn create(self) -> Self::Factory {
FramedRouteFactory {
handler: self.handler,
methods: self.methods,
_t: PhantomData,
}
}
}
2019-11-21 12:17:01 +06:00
pub struct FramedRouteFactory<Io, S, F, R, E> {
2019-04-10 15:06:27 -07:00
handler: F,
methods: Vec<Method>,
2019-11-21 12:17:01 +06:00
_t: PhantomData<(Io, S, R, E)>,
2019-04-10 15:06:27 -07:00
}
2019-11-21 12:17:01 +06:00
impl<Io, S, F, R, E> ServiceFactory for FramedRouteFactory<Io, S, F, R, E>
2019-04-10 15:06:27 -07:00
where
Io: AsyncRead + AsyncWrite + 'static,
F: FnMut(FramedRequest<Io, S>) -> R + Clone,
2019-11-21 12:17:01 +06:00
R: Future<Output = Result<(), E>> + 'static,
E: fmt::Display,
2019-04-10 15:06:27 -07:00
{
2019-05-12 08:34:51 -07:00
type Config = ();
2019-04-10 15:06:27 -07:00
type Request = FramedRequest<Io, S>;
type Response = ();
type Error = Error;
type InitError = ();
2019-11-21 12:17:01 +06:00
type Service = FramedRouteService<Io, S, F, R, E>;
type Future = Ready<Result<Self::Service, Self::InitError>>;
2019-04-10 15:06:27 -07:00
fn new_service(&self, _: &()) -> Self::Future {
ok(FramedRouteService {
handler: self.handler.clone(),
methods: self.methods.clone(),
_t: PhantomData,
})
}
}
2019-11-21 12:17:01 +06:00
pub struct FramedRouteService<Io, S, F, R, E> {
2019-04-10 15:06:27 -07:00
handler: F,
methods: Vec<Method>,
2019-11-21 12:17:01 +06:00
_t: PhantomData<(Io, S, R, E)>,
2019-04-10 15:06:27 -07:00
}
2019-11-21 12:17:01 +06:00
impl<Io, S, F, R, E> Service for FramedRouteService<Io, S, F, R, E>
2019-04-10 15:06:27 -07:00
where
Io: AsyncRead + AsyncWrite + 'static,
F: FnMut(FramedRequest<Io, S>) -> R + Clone,
2019-11-21 12:17:01 +06:00
R: Future<Output = Result<(), E>> + 'static,
E: fmt::Display,
2019-04-10 15:06:27 -07:00
{
type Request = FramedRequest<Io, S>;
type Response = ();
type Error = Error;
2019-11-21 12:17:01 +06:00
type Future = LocalBoxFuture<'static, Result<(), Error>>;
2019-04-10 15:06:27 -07:00
2019-11-21 12:17:01 +06:00
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
2019-04-10 15:06:27 -07:00
}
fn call(&mut self, req: FramedRequest<Io, S>) -> Self::Future {
2019-11-21 12:17:01 +06:00
let fut = (self.handler)(req);
async move {
let res = fut.await;
2019-04-10 15:06:27 -07:00
if let Err(e) = res {
error!("Error in request handler: {}", e);
}
Ok(())
2019-11-21 12:17:01 +06:00
}
.boxed_local()
2019-04-10 15:06:27 -07:00
}
}