diff --git a/CHANGES.md b/CHANGES.md index b1334fbc6..f925f3b94 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,8 @@ ### Changed - `Guard` trait now receives a `&GuardContext`. [#2552] - `guard::fn_guard` functions now receives a `&GuardContext`. [#2552] -- Some guards now return `impl Guard` and their concrete types are made private: `guard::{Not, Header}` and all the method guards. [#2552] +- Some guards now return `impl Guard` and their concrete types are made private: `guard::{Header}` and all the method guards. [#2552] +- The `Not` guard is now generic over the type of guard it wraps. [#2552] [#2552]: https://github.com/actix/actix-web/pull/2552 diff --git a/src/guard.rs b/src/guard.rs index 231d8c840..58a6108f7 100644 --- a/src/guard.rs +++ b/src/guard.rs @@ -253,15 +253,9 @@ impl Guard for AllGuard { /// .guard(guard::Not(guard::Get())) /// .to(|| HttpResponse::Ok()); /// ``` -#[allow(non_snake_case)] -pub fn Not(guard: G) -> NotGuard { - NotGuard(guard) -} +pub struct Not(pub G); -#[doc(hidden)] -pub struct NotGuard(G); - -impl Guard for NotGuard { +impl Guard for Not { fn check(&self, ctx: &GuardContext<'_>) -> bool { !self.0.check(ctx) } @@ -595,4 +589,18 @@ mod tests { assert!(Any(Get()).or(Trace()).check(&r.guard_ctx())); assert!(!Any(Get()).or(Get()).check(&r.guard_ctx())); } + + #[test] + fn not_guard_reflexive() { + let req = TestRequest::default().to_srv_request(); + + let get = Get(); + assert!(get.check(&req.guard_ctx())); + + let not_get = Not(get); + assert!(!not_get.check(&req.guard_ctx())); + + let not_not_get = Not(not_get); + assert!(not_not_get.check(&req.guard_ctx())); + } }