diff --git a/guide/src/qs_5.md b/guide/src/qs_5.md index 7eb1ac809..65ee24c3f 100644 --- a/guide/src/qs_5.md +++ b/guide/src/qs_5.md @@ -506,9 +506,8 @@ fn main() { Application::new() .resource("/index.html", |r| r.route() - .p(Box::new(ContentTypeHeader)) - .f(|req| HTTPOk)) - .finish(); + .p(ContentTypeHeader) + .h(HTTPOk)); } ``` @@ -545,14 +544,14 @@ fn main() { predicates match. i.e: ```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 predicates match. i.e: ```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 diff --git a/src/handler.rs b/src/handler.rs index 2293d9090..cbca0aed6 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -260,7 +260,7 @@ impl RouteHandler for AsyncHandler Ok(reply) => match reply.into().0 { ReplyItem::Message(resp) => ok(resp), _ => panic!("Nested async replies are not supported"), - } + }, Err(e) => err(e), } }); diff --git a/src/pred.rs b/src/pred.rs index 82283899f..47d906fb0 100644 --- a/src/pred.rs +++ b/src/pred.rs @@ -16,13 +16,36 @@ pub trait Predicate { } /// Return predicate that matches if any of supplied predicate matches. -pub fn Any(preds: T) -> Box> - where T: IntoIterator>> +/// +/// ```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 + 'static>(pred: P) -> AnyPredicate { - Box::new(AnyPredicate(preds.into_iter().collect())) + AnyPredicate(vec![Box::new(pred)]) } -struct AnyPredicate(Vec>>); +/// Matches if any of supplied predicate matches. +pub struct AnyPredicate(Vec>>); + +impl AnyPredicate { + /// Add new predicate to list of predicates to check + pub fn or + 'static>(mut self, pred: P) -> Self { + self.0.push(Box::new(pred)); + self + } +} impl Predicate for AnyPredicate { fn check(&self, req: &mut HttpRequest) -> bool { @@ -36,13 +59,36 @@ impl Predicate for AnyPredicate { } /// Return predicate that matches if all of supplied predicate matches. -pub fn All(preds: T) -> Box> - where T: IntoIterator>> -{ - Box::new(AllPredicate(preds.into_iter().collect())) +/// +/// ```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::All(pred::Get()) +/// .and(pred::Header("content-type", "plain/text"))) +/// .h(HTTPMethodNotAllowed)); +/// } +/// ``` +pub fn All + 'static>(pred: P) -> AllPredicate { + AllPredicate(vec![Box::new(pred)]) } -struct AllPredicate(Vec>>); +/// Matches if all of supplied predicate matches. +pub struct AllPredicate(Vec>>); + +impl AllPredicate { + /// Add new predicate to list of predicates to check + pub fn and + 'static>(mut self, pred: P) -> Self { + self.0.push(Box::new(pred)); + self + } +} impl Predicate for AllPredicate { fn check(&self, req: &mut HttpRequest) -> bool { @@ -56,12 +102,13 @@ impl Predicate for AllPredicate { } /// Return predicate that matches if supplied predicate does not match. -pub fn Not(pred: Box>) -> Box> +pub fn Not + 'static>(pred: P) -> NotPredicate { - Box::new(NotPredicate(pred)) + NotPredicate(Box::new(pred)) } -struct NotPredicate(Box>); +#[doc(hidden)] +pub struct NotPredicate(Box>); impl Predicate for NotPredicate { fn check(&self, req: &mut HttpRequest) -> bool { @@ -70,7 +117,8 @@ impl Predicate for NotPredicate { } /// Http method predicate -struct MethodPredicate(http::Method, PhantomData); +#[doc(hidden)] +pub struct MethodPredicate(http::Method, PhantomData); impl Predicate for MethodPredicate { fn check(&self, req: &mut HttpRequest) -> bool { @@ -79,64 +127,65 @@ impl Predicate for MethodPredicate { } /// Predicate to match *GET* http method -pub fn Get() -> Box> { - Box::new(MethodPredicate(http::Method::GET, PhantomData)) +pub fn Get() -> MethodPredicate { + MethodPredicate(http::Method::GET, PhantomData) } /// Predicate to match *POST* http method -pub fn Post() -> Box> { - Box::new(MethodPredicate(http::Method::POST, PhantomData)) +pub fn Post() -> MethodPredicate { + MethodPredicate(http::Method::POST, PhantomData) } /// Predicate to match *PUT* http method -pub fn Put() -> Box> { - Box::new(MethodPredicate(http::Method::PUT, PhantomData)) +pub fn Put() -> MethodPredicate { + MethodPredicate(http::Method::PUT, PhantomData) } /// Predicate to match *DELETE* http method -pub fn Delete() -> Box> { - Box::new(MethodPredicate(http::Method::DELETE, PhantomData)) +pub fn Delete() -> MethodPredicate { + MethodPredicate(http::Method::DELETE, PhantomData) } /// Predicate to match *HEAD* http method -pub fn Head() -> Box> { - Box::new(MethodPredicate(http::Method::HEAD, PhantomData)) +pub fn Head() -> MethodPredicate { + MethodPredicate(http::Method::HEAD, PhantomData) } /// Predicate to match *OPTIONS* http method -pub fn Options() -> Box> { - Box::new(MethodPredicate(http::Method::OPTIONS, PhantomData)) +pub fn Options() -> MethodPredicate { + MethodPredicate(http::Method::OPTIONS, PhantomData) } /// Predicate to match *CONNECT* http method -pub fn Connect() -> Box> { - Box::new(MethodPredicate(http::Method::CONNECT, PhantomData)) +pub fn Connect() -> MethodPredicate { + MethodPredicate(http::Method::CONNECT, PhantomData) } /// Predicate to match *PATCH* http method -pub fn Patch() -> Box> { - Box::new(MethodPredicate(http::Method::PATCH, PhantomData)) +pub fn Patch() -> MethodPredicate { + MethodPredicate(http::Method::PATCH, PhantomData) } /// Predicate to match *TRACE* http method -pub fn Trace() -> Box> { - Box::new(MethodPredicate(http::Method::TRACE, PhantomData)) +pub fn Trace() -> MethodPredicate { + MethodPredicate(http::Method::TRACE, PhantomData) } /// Predicate to match specified http method -pub fn Method(method: http::Method) -> Box> { - Box::new(MethodPredicate(method, PhantomData)) +pub fn Method(method: http::Method) -> MethodPredicate { + MethodPredicate(method, PhantomData) } /// Return predicate that matches if request contains specified header and value. -pub fn Header(name: &'static str, value: &'static str) -> Box> +pub fn Header(name: &'static str, value: &'static str) -> HeaderPredicate { - Box::new(HeaderPredicate(header::HeaderName::try_from(name).unwrap(), - header::HeaderValue::from_static(value), - PhantomData)) + HeaderPredicate(header::HeaderName::try_from(name).unwrap(), + header::HeaderValue::from_static(value), + PhantomData) } -struct HeaderPredicate(header::HeaderName, header::HeaderValue, PhantomData); +#[doc(hidden)] +pub struct HeaderPredicate(header::HeaderName, header::HeaderValue, PhantomData); impl Predicate for HeaderPredicate { fn check(&self, req: &mut HttpRequest) -> bool { @@ -238,10 +287,10 @@ mod tests { assert!(Not(Get()).check(&mut r)); assert!(!Not(Trace()).check(&mut r)); - assert!(All(vec![Trace(), Trace()]).check(&mut r)); - assert!(!All(vec![Get(), Trace()]).check(&mut r)); + assert!(All(Trace()).and(Trace()).check(&mut r)); + assert!(!All(Get()).and(Trace()).check(&mut r)); - assert!(Any(vec![Get(), Trace()]).check(&mut r)); - assert!(!Any(vec![Get(), Get()]).check(&mut r)); + assert!(Any(Get()).or(Trace()).check(&mut r)); + assert!(!Any(Get()).or(Get()).check(&mut r)); } } diff --git a/src/resource.rs b/src/resource.rs index b914cfa3b..937c28251 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -76,7 +76,7 @@ impl Resource { /// let app = Application::new() /// .resource( /// "/", |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")) /// .f(|r| HttpResponse::Ok())) /// .finish(); diff --git a/src/route.rs b/src/route.rs index 194a1c06c..404fa16d3 100644 --- a/src/route.rs +++ b/src/route.rs @@ -57,8 +57,8 @@ impl Route { /// # .finish(); /// # } /// ``` - pub fn p(&mut self, p: Box>) -> &mut Self { - self.preds.push(p); + pub fn p + 'static>(&mut self, p: T) -> &mut Self { + self.preds.push(Box::new(p)); self }