/rust/registry/src/index.crates.io-1949cf8c6b5b557f/async-graphql-7.0.17/src/guard.rs
Line | Count | Source |
1 | | //! Field guards |
2 | | #[cfg(not(feature = "boxed-trait"))] |
3 | | use std::future::Future; |
4 | | |
5 | | use crate::{Context, Result}; |
6 | | |
7 | | /// Field guard |
8 | | /// |
9 | | /// Guard is a pre-condition for a field that is resolved if `Ok(())` is |
10 | | /// returned, otherwise an error is returned. |
11 | | #[cfg_attr(feature = "boxed-trait", async_trait::async_trait)] |
12 | | pub trait Guard { |
13 | | /// Check whether the guard will allow access to the field. |
14 | | #[cfg(feature = "boxed-trait")] |
15 | | async fn check(&self, ctx: &Context<'_>) -> Result<()>; |
16 | | |
17 | | /// Check whether the guard will allow access to the field. |
18 | | #[cfg(not(feature = "boxed-trait"))] |
19 | | fn check(&self, ctx: &Context<'_>) -> impl Future<Output = Result<()>> + Send; |
20 | | } |
21 | | |
22 | | #[cfg_attr(feature = "boxed-trait", async_trait::async_trait)] |
23 | | impl<T> Guard for T |
24 | | where |
25 | | T: Fn(&Context<'_>) -> Result<()> + Send + Sync + 'static, |
26 | | { |
27 | 0 | async fn check(&self, ctx: &Context<'_>) -> Result<()> { |
28 | 0 | self(ctx) |
29 | 0 | } |
30 | | } |
31 | | |
32 | | /// An extension trait for `Guard`. |
33 | | pub trait GuardExt: Guard + Sized { |
34 | | /// Perform `and` operator on two rules |
35 | 0 | fn and<R: Guard>(self, other: R) -> And<Self, R> { |
36 | 0 | And(self, other) |
37 | 0 | } |
38 | | |
39 | | /// Perform `or` operator on two rules |
40 | 0 | fn or<R: Guard>(self, other: R) -> Or<Self, R> { |
41 | 0 | Or(self, other) |
42 | 0 | } |
43 | | } |
44 | | |
45 | | impl<T: Guard> GuardExt for T {} |
46 | | |
47 | | /// Guard for [`GuardExt::and`](trait.GuardExt.html#method.and). |
48 | | pub struct And<A: Guard, B: Guard>(A, B); |
49 | | |
50 | | #[cfg_attr(feature = "boxed-trait", async_trait::async_trait)] |
51 | | impl<A: Guard + Send + Sync, B: Guard + Send + Sync> Guard for And<A, B> { |
52 | 0 | async fn check(&self, ctx: &Context<'_>) -> Result<()> { |
53 | 0 | self.0.check(ctx).await?; |
54 | 0 | self.1.check(ctx).await |
55 | 0 | } |
56 | | } |
57 | | |
58 | | /// Guard for [`GuardExt::or`](trait.GuardExt.html#method.or). |
59 | | pub struct Or<A: Guard, B: Guard>(A, B); |
60 | | |
61 | | #[cfg_attr(feature = "boxed-trait", async_trait::async_trait)] |
62 | | impl<A: Guard + Send + Sync, B: Guard + Send + Sync> Guard for Or<A, B> { |
63 | 0 | async fn check(&self, ctx: &Context<'_>) -> Result<()> { |
64 | 0 | if self.0.check(ctx).await.is_ok() { |
65 | 0 | return Ok(()); |
66 | 0 | } |
67 | 0 | self.1.check(ctx).await |
68 | 0 | } |
69 | | } |