async-graphql-test 1.0.0

A test framework for Rust GraphQL servers.
Documentation
use std::fmt::{Debug, Display, Formatter};

use async_graphql::async_trait::async_trait;
use async_graphql::{Any, Context, CustomDirective, Directive, ResolveFut, ServerResult, Value};

use super::MatcherError;

#[Directive(location = "Field", name = "shouldBeOneOf")]
pub fn should_be_one_of(list: Vec<Option<Any>>) -> impl CustomDirective {
    ShouldBeOneOf {
        list: list
            .into_iter()
            .map(|any| any.map_or(Value::Null, |it| it.0))
            .collect(),
    }
}

struct ShouldBeOneOf {
    list: Vec<Value>,
}

impl Display for ShouldBeOneOf {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        self.list.fmt(f)
    }
}

#[async_trait]
impl CustomDirective for ShouldBeOneOf {
    async fn resolve_field(
        &self,
        ctx: &Context<'_>,
        resolve: ResolveFut<'_>,
    ) -> ServerResult<Option<Value>> {
        match resolve.await {
            Ok(None) => Ok(None),
            Ok(Some(value)) => {
                if self.list.contains(&value) {
                    Ok(Some(value))
                } else {
                    Err(MatcherError::new(
                        ctx.item.pos,
                        format!("Expected: one of {self}\nReceived: {value}"),
                    ))
                }
            }
            Err(err) => Err(MatcherError::unexpected_error(err)),
        }
    }
}