Coverage Report

Created: 2025-11-28 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}