async_graphql_test/matchers/
should_match.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, ValueTypeName};
7
8#[Directive(location = "Field", name = "shouldMatch")]
9pub fn should_match(string: Option<String>, regex: Option<String>) -> impl CustomDirective {
10 if let Some(string) = string {
11 return ShouldMatch::String(string);
12 }
13
14 if let Some(regex) = regex {
15 return ShouldMatch::Regex(
16 regex::Regex::new(®ex)
17 .map_err(|err| format!("incorrect regular expression: {err}"))
18 .unwrap(),
19 );
20 }
21
22 panic!("at least one of the arguments must be present");
23}
24
25enum ShouldMatch {
26 Regex(regex::Regex),
27 String(String),
28}
29
30impl ShouldMatch {
31 pub fn matches(&self, text: &str) -> bool {
32 match self {
33 ShouldMatch::String(sub) => text.contains(sub),
34 ShouldMatch::Regex(regex) => regex.is_match(text),
35 }
36 }
37}
38
39impl Display for ShouldMatch {
40 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
41 match self {
42 ShouldMatch::Regex(regex) => write!(f, "/{regex}/"),
43 ShouldMatch::String(sub) => sub.fmt(f),
44 }
45 }
46}
47
48#[async_trait]
49impl CustomDirective for ShouldMatch {
50 async fn resolve_field(
51 &self,
52 ctx: &Context<'_>,
53 resolve: ResolveFut<'_>,
54 ) -> ServerResult<Option<Value>> {
55 match resolve.await {
56 Ok(None) => Ok(None),
57 Ok(Some(Value::String(received))) => {
58 if self.matches(&received) {
59 Ok(Some(Value::String(received)))
60 } else {
61 Err(MatcherError::new(
62 ctx.item.pos,
63 format!("Expected value to match:\n {self}\nReceived:\n \"{received}\""),
64 ))
65 }
66 }
67 Ok(Some(value)) => {
68 let type_name = ValueTypeName(&value);
69 Err(MatcherError::new(
70 ctx.item.pos,
71 format!(
72 "@shouldMatch error: received value must be a string.\nReceived has type: {type_name}\nReceived has value: {value}"
73 ),
74 ))
75 }
76 Err(err) => Err(MatcherError::unexpected_error(err)),
77 }
78 }
79}