async_graphql_test/matchers/
should_be_less_than.rs1use std::fmt::{Display, Formatter};
2
3use async_graphql::async_trait::async_trait;
4use async_graphql::{Context, CustomDirective, Directive, ResolveFut, ServerResult, Value};
5
6use super::{MatcherError, Numeric, ValueTypeName};
7
8#[Directive(location = "Field", name = "shouldBeLessThan")]
9pub fn should_be_less_than(
10 i: Option<i64>,
11 f: Option<f64>,
12 bi: Option<String>,
13) -> impl CustomDirective {
14 let num = if let Some(i) = i {
15 Numeric::Int(i)
16 } else if let Some(f) = f {
17 Numeric::Float(f)
18 } else if let Some(s) = bi {
19 Numeric::String(s)
20 } else {
21 panic!("@shouldBeLess missing an argument")
22 };
23 ShouldBeLessThan { num }
24}
25
26struct ShouldBeLessThan {
27 num: Numeric,
28}
29
30impl Display for ShouldBeLessThan {
31 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
32 self.num.fmt(f)
33 }
34}
35
36#[async_trait]
37impl CustomDirective for ShouldBeLessThan {
38 async fn resolve_field(
39 &self,
40 ctx: &Context<'_>,
41 resolve: ResolveFut<'_>,
42 ) -> ServerResult<Option<Value>> {
43 match resolve.await {
44 Ok(None) => Ok(None),
45 Ok(Some(Value::Number(num))) => {
46 if self.num < num {
47 Ok(Some(Value::Number(num)))
48 } else {
49 Err(MatcherError::new(
50 ctx.item.pos,
51 format!("Expected: < {self}\nReceived: {num}"),
52 ))
53 }
54 }
55 Ok(Some(value)) => {
56 let type_name = ValueTypeName(&value);
57 Err(MatcherError::new(
58 ctx.item.pos,
59 format!(
60 "@shouldBeLess error: value must be numeric.\nReceived has type: {type_name}\nReceived has value: {value}"
61 ),
62 ))
63 }
64 Err(err) => Err(MatcherError::unexpected_error(err)),
65 }
66 }
67}