use async_graphql::async_trait::async_trait;
use async_graphql::{Context, CustomDirective, Directive, ResolveFut, ServerResult, Value};
use serde_json::Number;
use super::MatcherError;
struct ShouldBeFalsy;
#[Directive(location = "Field", name = "shouldBeFalsy")]
pub fn should_be_falsy() -> impl CustomDirective {
ShouldBeFalsy
}
#[async_trait]
impl CustomDirective for ShouldBeFalsy {
async fn resolve_field(
&self,
ctx: &Context<'_>,
resolve: ResolveFut<'_>,
) -> ServerResult<Option<Value>> {
match resolve.await {
Ok(None) => Ok(None), Ok(Some(Value::Null)) => Ok(Some(Value::Null)),
Ok(Some(Value::Boolean(false))) => Ok(Some(Value::Boolean(false))),
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: falsy (0, null, false, \"\")\nReceived: {other}"),
)),
Err(err) => Err(MatcherError::unexpected_error(err)),
}
}
}