1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-01-18 05:41:50 +01:00

remove box from predicates

This commit is contained in:
Nikolay Kim 2017-12-20 13:23:50 -08:00
parent 813b56ebe5
commit 79f047f5be
5 changed files with 99 additions and 51 deletions

View File

@ -506,9 +506,8 @@ fn main() {
Application::new() Application::new()
.resource("/index.html", |r| .resource("/index.html", |r|
r.route() r.route()
.p(Box::new(ContentTypeHeader)) .p(ContentTypeHeader)
.f(|req| HTTPOk)) .h(HTTPOk));
.finish();
} }
``` ```
@ -545,14 +544,14 @@ fn main() {
predicates match. i.e: predicates match. i.e:
```rust,ignore ```rust,ignore
pred::Any(vec![pred::Get(), pred::Post()]) pred::Any(pred::Get()).or(pred::Post())
``` ```
`All` predicate accept list of predicates and matches if all of the supplied `All` predicate accept list of predicates and matches if all of the supplied
predicates match. i.e: predicates match. i.e:
```rust,ignore ```rust,ignore
pred::All(vec![pred::Get(), pred::Header("content-type", "plain/text")]) pred::All(pred::Get()).and(pred::Header("content-type", "plain/text"))
``` ```
## Changing the default Not Found response ## Changing the default Not Found response

View File

@ -260,7 +260,7 @@ impl<S, H, F, R, E> RouteHandler<S> for AsyncHandler<S, H, F, R, E>
Ok(reply) => match reply.into().0 { Ok(reply) => match reply.into().0 {
ReplyItem::Message(resp) => ok(resp), ReplyItem::Message(resp) => ok(resp),
_ => panic!("Nested async replies are not supported"), _ => panic!("Nested async replies are not supported"),
} },
Err(e) => err(e), Err(e) => err(e),
} }
}); });

View File

@ -16,13 +16,36 @@ pub trait Predicate<S> {
} }
/// Return predicate that matches if any of supplied predicate matches. /// Return predicate that matches if any of supplied predicate matches.
pub fn Any<T, S: 'static>(preds: T) -> Box<Predicate<S>> ///
where T: IntoIterator<Item=Box<Predicate<S>>> /// ```rust
/// # extern crate actix_web;
/// # extern crate http;
/// # use actix_web::*;
/// # use actix_web::httpcodes::*;
/// use actix_web::pred;
///
/// fn main() {
/// Application::new()
/// .resource("/index.html", |r| r.route()
/// .p(pred::Any(pred::Get()).or(pred::Post()))
/// .h(HTTPMethodNotAllowed));
/// }
/// ```
pub fn Any<S: 'static, P: Predicate<S> + 'static>(pred: P) -> AnyPredicate<S>
{ {
Box::new(AnyPredicate(preds.into_iter().collect())) AnyPredicate(vec![Box::new(pred)])
} }
struct AnyPredicate<S>(Vec<Box<Predicate<S>>>); /// Matches if any of supplied predicate matches.
pub struct AnyPredicate<S>(Vec<Box<Predicate<S>>>);
impl<S> AnyPredicate<S> {
/// Add new predicate to list of predicates to check
pub fn or<P: Predicate<S> + 'static>(mut self, pred: P) -> Self {
self.0.push(Box::new(pred));
self
}
}
impl<S: 'static> Predicate<S> for AnyPredicate<S> { impl<S: 'static> Predicate<S> for AnyPredicate<S> {
fn check(&self, req: &mut HttpRequest<S>) -> bool { fn check(&self, req: &mut HttpRequest<S>) -> bool {
@ -36,13 +59,36 @@ impl<S: 'static> Predicate<S> for AnyPredicate<S> {
} }
/// Return predicate that matches if all of supplied predicate matches. /// Return predicate that matches if all of supplied predicate matches.
pub fn All<T, S: 'static>(preds: T) -> Box<Predicate<S>> ///
where T: IntoIterator<Item=Box<Predicate<S>>> /// ```rust
{ /// # extern crate actix_web;
Box::new(AllPredicate(preds.into_iter().collect())) /// # extern crate http;
/// # use actix_web::*;
/// # use actix_web::httpcodes::*;
/// use actix_web::pred;
///
/// fn main() {
/// Application::new()
/// .resource("/index.html", |r| r.route()
/// .p(pred::All(pred::Get())
/// .and(pred::Header("content-type", "plain/text")))
/// .h(HTTPMethodNotAllowed));
/// }
/// ```
pub fn All<S: 'static, P: Predicate<S> + 'static>(pred: P) -> AllPredicate<S> {
AllPredicate(vec![Box::new(pred)])
} }
struct AllPredicate<S>(Vec<Box<Predicate<S>>>); /// Matches if all of supplied predicate matches.
pub struct AllPredicate<S>(Vec<Box<Predicate<S>>>);
impl<S> AllPredicate<S> {
/// Add new predicate to list of predicates to check
pub fn and<P: Predicate<S> + 'static>(mut self, pred: P) -> Self {
self.0.push(Box::new(pred));
self
}
}
impl<S: 'static> Predicate<S> for AllPredicate<S> { impl<S: 'static> Predicate<S> for AllPredicate<S> {
fn check(&self, req: &mut HttpRequest<S>) -> bool { fn check(&self, req: &mut HttpRequest<S>) -> bool {
@ -56,12 +102,13 @@ impl<S: 'static> Predicate<S> for AllPredicate<S> {
} }
/// Return predicate that matches if supplied predicate does not match. /// Return predicate that matches if supplied predicate does not match.
pub fn Not<S: 'static>(pred: Box<Predicate<S>>) -> Box<Predicate<S>> pub fn Not<S: 'static, P: Predicate<S> + 'static>(pred: P) -> NotPredicate<S>
{ {
Box::new(NotPredicate(pred)) NotPredicate(Box::new(pred))
} }
struct NotPredicate<S>(Box<Predicate<S>>); #[doc(hidden)]
pub struct NotPredicate<S>(Box<Predicate<S>>);
impl<S: 'static> Predicate<S> for NotPredicate<S> { impl<S: 'static> Predicate<S> for NotPredicate<S> {
fn check(&self, req: &mut HttpRequest<S>) -> bool { fn check(&self, req: &mut HttpRequest<S>) -> bool {
@ -70,7 +117,8 @@ impl<S: 'static> Predicate<S> for NotPredicate<S> {
} }
/// Http method predicate /// Http method predicate
struct MethodPredicate<S>(http::Method, PhantomData<S>); #[doc(hidden)]
pub struct MethodPredicate<S>(http::Method, PhantomData<S>);
impl<S: 'static> Predicate<S> for MethodPredicate<S> { impl<S: 'static> Predicate<S> for MethodPredicate<S> {
fn check(&self, req: &mut HttpRequest<S>) -> bool { fn check(&self, req: &mut HttpRequest<S>) -> bool {
@ -79,64 +127,65 @@ impl<S: 'static> Predicate<S> for MethodPredicate<S> {
} }
/// Predicate to match *GET* http method /// Predicate to match *GET* http method
pub fn Get<S: 'static>() -> Box<Predicate<S>> { pub fn Get<S: 'static>() -> MethodPredicate<S> {
Box::new(MethodPredicate(http::Method::GET, PhantomData)) MethodPredicate(http::Method::GET, PhantomData)
} }
/// Predicate to match *POST* http method /// Predicate to match *POST* http method
pub fn Post<S: 'static>() -> Box<Predicate<S>> { pub fn Post<S: 'static>() -> MethodPredicate<S> {
Box::new(MethodPredicate(http::Method::POST, PhantomData)) MethodPredicate(http::Method::POST, PhantomData)
} }
/// Predicate to match *PUT* http method /// Predicate to match *PUT* http method
pub fn Put<S: 'static>() -> Box<Predicate<S>> { pub fn Put<S: 'static>() -> MethodPredicate<S> {
Box::new(MethodPredicate(http::Method::PUT, PhantomData)) MethodPredicate(http::Method::PUT, PhantomData)
} }
/// Predicate to match *DELETE* http method /// Predicate to match *DELETE* http method
pub fn Delete<S: 'static>() -> Box<Predicate<S>> { pub fn Delete<S: 'static>() -> MethodPredicate<S> {
Box::new(MethodPredicate(http::Method::DELETE, PhantomData)) MethodPredicate(http::Method::DELETE, PhantomData)
} }
/// Predicate to match *HEAD* http method /// Predicate to match *HEAD* http method
pub fn Head<S: 'static>() -> Box<Predicate<S>> { pub fn Head<S: 'static>() -> MethodPredicate<S> {
Box::new(MethodPredicate(http::Method::HEAD, PhantomData)) MethodPredicate(http::Method::HEAD, PhantomData)
} }
/// Predicate to match *OPTIONS* http method /// Predicate to match *OPTIONS* http method
pub fn Options<S: 'static>() -> Box<Predicate<S>> { pub fn Options<S: 'static>() -> MethodPredicate<S> {
Box::new(MethodPredicate(http::Method::OPTIONS, PhantomData)) MethodPredicate(http::Method::OPTIONS, PhantomData)
} }
/// Predicate to match *CONNECT* http method /// Predicate to match *CONNECT* http method
pub fn Connect<S: 'static>() -> Box<Predicate<S>> { pub fn Connect<S: 'static>() -> MethodPredicate<S> {
Box::new(MethodPredicate(http::Method::CONNECT, PhantomData)) MethodPredicate(http::Method::CONNECT, PhantomData)
} }
/// Predicate to match *PATCH* http method /// Predicate to match *PATCH* http method
pub fn Patch<S: 'static>() -> Box<Predicate<S>> { pub fn Patch<S: 'static>() -> MethodPredicate<S> {
Box::new(MethodPredicate(http::Method::PATCH, PhantomData)) MethodPredicate(http::Method::PATCH, PhantomData)
} }
/// Predicate to match *TRACE* http method /// Predicate to match *TRACE* http method
pub fn Trace<S: 'static>() -> Box<Predicate<S>> { pub fn Trace<S: 'static>() -> MethodPredicate<S> {
Box::new(MethodPredicate(http::Method::TRACE, PhantomData)) MethodPredicate(http::Method::TRACE, PhantomData)
} }
/// Predicate to match specified http method /// Predicate to match specified http method
pub fn Method<S: 'static>(method: http::Method) -> Box<Predicate<S>> { pub fn Method<S: 'static>(method: http::Method) -> MethodPredicate<S> {
Box::new(MethodPredicate(method, PhantomData)) MethodPredicate(method, PhantomData)
} }
/// Return predicate that matches if request contains specified header and value. /// Return predicate that matches if request contains specified header and value.
pub fn Header<S: 'static>(name: &'static str, value: &'static str) -> Box<Predicate<S>> pub fn Header<S: 'static>(name: &'static str, value: &'static str) -> HeaderPredicate<S>
{ {
Box::new(HeaderPredicate(header::HeaderName::try_from(name).unwrap(), HeaderPredicate(header::HeaderName::try_from(name).unwrap(),
header::HeaderValue::from_static(value), header::HeaderValue::from_static(value),
PhantomData)) PhantomData)
} }
struct HeaderPredicate<S>(header::HeaderName, header::HeaderValue, PhantomData<S>); #[doc(hidden)]
pub struct HeaderPredicate<S>(header::HeaderName, header::HeaderValue, PhantomData<S>);
impl<S: 'static> Predicate<S> for HeaderPredicate<S> { impl<S: 'static> Predicate<S> for HeaderPredicate<S> {
fn check(&self, req: &mut HttpRequest<S>) -> bool { fn check(&self, req: &mut HttpRequest<S>) -> bool {
@ -238,10 +287,10 @@ mod tests {
assert!(Not(Get()).check(&mut r)); assert!(Not(Get()).check(&mut r));
assert!(!Not(Trace()).check(&mut r)); assert!(!Not(Trace()).check(&mut r));
assert!(All(vec![Trace(), Trace()]).check(&mut r)); assert!(All(Trace()).and(Trace()).check(&mut r));
assert!(!All(vec![Get(), Trace()]).check(&mut r)); assert!(!All(Get()).and(Trace()).check(&mut r));
assert!(Any(vec![Get(), Trace()]).check(&mut r)); assert!(Any(Get()).or(Trace()).check(&mut r));
assert!(!Any(vec![Get(), Get()]).check(&mut r)); assert!(!Any(Get()).or(Get()).check(&mut r));
} }
} }

View File

@ -76,7 +76,7 @@ impl<S: 'static> Resource<S> {
/// let app = Application::new() /// let app = Application::new()
/// .resource( /// .resource(
/// "/", |r| r.route() /// "/", |r| r.route()
/// .p(pred::Any(vec![pred::Get(), pred::Put()])) /// .p(pred::Any(pred::Get()).or(pred::Put()))
/// .p(pred::Header("Content-Type", "text/plain")) /// .p(pred::Header("Content-Type", "text/plain"))
/// .f(|r| HttpResponse::Ok())) /// .f(|r| HttpResponse::Ok()))
/// .finish(); /// .finish();

View File

@ -57,8 +57,8 @@ impl<S: 'static> Route<S> {
/// # .finish(); /// # .finish();
/// # } /// # }
/// ``` /// ```
pub fn p(&mut self, p: Box<Predicate<S>>) -> &mut Self { pub fn p<T: Predicate<S> + 'static>(&mut self, p: T) -> &mut Self {
self.preds.push(p); self.preds.push(Box::new(p));
self self
} }