async-graphql-test 1.0.0

A test framework for Rust GraphQL servers.
Documentation
use async_graphql::async_trait::async_trait;
use async_graphql::{Context, CustomDirective, Directive, ResolveFut, ServerResult, Value};
use serde_json::Number;

use super::MatcherError;

struct ShouldBeTruthy;

/// Use `@shouldBeTruthy` when you don't care what a value is,
/// and you want to ensure a value is true in a boolean context.
/// There are four falsy values: `false`, `0`, `''`, `null`. Everything else is truthy.
#[Directive(location = "Field", name = "shouldBeTruthy")]
pub fn should_be_truthy() -> impl CustomDirective {
    ShouldBeTruthy
}

#[async_trait]
impl CustomDirective for ShouldBeTruthy {
    async fn resolve_field(
        &self,
        ctx: &Context<'_>,
        resolve: ResolveFut<'_>,
    ) -> ServerResult<Option<Value>> {
        match resolve.await {
            Ok(None) => Ok(None), // todo: think about this case
            Ok(Some(Value::Boolean(true))) => Ok(Some(Value::Boolean(true))),
            Ok(Some(Value::Number(num))) if num != Number::from(0) => Ok(Some(Value::Number(num))),
            Ok(Some(Value::Number(num))) if num != Number::from_f64(0.).unwrap() => {
                Ok(Some(Value::Number(num)))
            }
            Ok(Some(Value::String(str))) if !str.is_empty() => Ok(Some(Value::String(str))),
            Ok(Some(other)) => Err(MatcherError::new(
                ctx.item.pos,
                format!("Expected: truthy (not any of 0, null, false, \"\")\nReceived: {other}"),
            )),
            Err(err) => Err(MatcherError::unexpected_error(err)),
        }
    }
}