use serde_json::Value;
use vantage_expressions::Expressive;
use crate::graphql::condition::{FieldCondition, GraphqlCondition, GraphqlOp};
use crate::graphql::types::{AnyGraphqlType, GraphqlType};
fn field_name<T>(expr: &(impl Expressive<T> + ?Sized)) -> String {
expr.expr().template.clone()
}
fn to_json(value: impl Into<AnyGraphqlType>) -> Value {
value.into().to_json()
}
fn to_json_array<I, V>(values: I) -> Value
where
I: IntoIterator<Item = V>,
V: Into<AnyGraphqlType>,
{
Value::Array(values.into_iter().map(to_json).collect())
}
pub trait GraphqlOperation<T>: Expressive<T> {
fn eq(&self, value: impl Into<AnyGraphqlType>) -> GraphqlCondition
where
Self: Sized,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::Eq,
to_json(value),
))
}
fn ne(&self, value: impl Into<AnyGraphqlType>) -> GraphqlCondition
where
Self: Sized,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::Ne,
to_json(value),
))
}
fn gt(&self, value: impl Into<AnyGraphqlType>) -> GraphqlCondition
where
Self: Sized,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::Gt,
to_json(value),
))
}
fn gte(&self, value: impl Into<AnyGraphqlType>) -> GraphqlCondition
where
Self: Sized,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::Gte,
to_json(value),
))
}
fn lt(&self, value: impl Into<AnyGraphqlType>) -> GraphqlCondition
where
Self: Sized,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::Lt,
to_json(value),
))
}
fn lte(&self, value: impl Into<AnyGraphqlType>) -> GraphqlCondition
where
Self: Sized,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::Lte,
to_json(value),
))
}
fn in_<I, V>(&self, values: I) -> GraphqlCondition
where
Self: Sized,
I: IntoIterator<Item = V>,
V: Into<AnyGraphqlType>,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::In,
to_json_array(values),
))
}
fn not_in<I, V>(&self, values: I) -> GraphqlCondition
where
Self: Sized,
I: IntoIterator<Item = V>,
V: Into<AnyGraphqlType>,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::NotIn,
to_json_array(values),
))
}
fn like(&self, pattern: impl Into<String>) -> GraphqlCondition
where
Self: Sized,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::Like,
Value::String(pattern.into()),
))
}
fn ilike(&self, pattern: impl Into<String>) -> GraphqlCondition
where
Self: Sized,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::ILike,
Value::String(pattern.into()),
))
}
fn is_null(&self) -> GraphqlCondition
where
Self: Sized,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::IsNull,
Value::Null,
))
}
fn is_not_null(&self) -> GraphqlCondition
where
Self: Sized,
{
GraphqlCondition::Field(FieldCondition::new(
field_name(self),
GraphqlOp::IsNotNull,
Value::Null,
))
}
}
impl<T, S: Expressive<T>> GraphqlOperation<T> for S {}
#[allow(dead_code)]
fn _assert_graphql_type_in_scope<T: GraphqlType>(_: &T) {}