use std::borrow::Cow;
use crate::{queries::SelectionBuilder, QueryVariablesFields};
pub trait QueryFragment: Sized {
type SchemaType;
type VariablesFields: QueryVariablesFields;
const TYPE: Option<&'static str> = None;
fn query(builder: SelectionBuilder<'_, Self::SchemaType, Self::VariablesFields>);
fn name() -> Option<Cow<'static, str>> {
None
}
}
impl<T> QueryFragment for Option<T>
where
T: QueryFragment,
{
type SchemaType = Option<T::SchemaType>;
type VariablesFields = T::VariablesFields;
fn query(builder: SelectionBuilder<'_, Self::SchemaType, Self::VariablesFields>) {
T::query(builder.into_inner())
}
}
impl<T> QueryFragment for Vec<T>
where
T: QueryFragment,
{
type SchemaType = Vec<T::SchemaType>;
type VariablesFields = T::VariablesFields;
fn query(builder: SelectionBuilder<'_, Self::SchemaType, Self::VariablesFields>) {
T::query(builder.into_inner())
}
}
impl<T> QueryFragment for Box<T>
where
T: QueryFragment,
{
type SchemaType = T::SchemaType;
type VariablesFields = T::VariablesFields;
const TYPE: Option<&'static str> = T::TYPE;
fn query(builder: SelectionBuilder<'_, Self::SchemaType, Self::VariablesFields>) {
T::query(builder)
}
}
impl<T> QueryFragment for std::rc::Rc<T>
where
T: QueryFragment,
{
type SchemaType = T::SchemaType;
type VariablesFields = T::VariablesFields;
const TYPE: Option<&'static str> = T::TYPE;
fn query(builder: SelectionBuilder<'_, Self::SchemaType, Self::VariablesFields>) {
T::query(builder)
}
}
impl<T> QueryFragment for std::sync::Arc<T>
where
T: QueryFragment,
{
type SchemaType = T::SchemaType;
type VariablesFields = T::VariablesFields;
const TYPE: Option<&'static str> = T::TYPE;
fn query(builder: SelectionBuilder<'_, Self::SchemaType, Self::VariablesFields>) {
T::query(builder)
}
}
impl QueryFragment for bool {
type SchemaType = bool;
type VariablesFields = ();
fn query(_builder: SelectionBuilder<'_, Self::SchemaType, Self::VariablesFields>) {}
}
impl QueryFragment for String {
type SchemaType = String;
type VariablesFields = ();
fn query(_builder: SelectionBuilder<'_, Self::SchemaType, Self::VariablesFields>) {}
}
pub trait InlineFragments<'de>: QueryFragment + serde::de::Deserialize<'de> {
fn deserialize_variant<D>(typename: &str, deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>;
}
pub trait Enum: serde::de::DeserializeOwned + serde::Serialize {
type SchemaType;
}
impl<T> Enum for Option<T>
where
T: Enum,
{
type SchemaType = Option<T::SchemaType>;
}
impl<T> Enum for Vec<T>
where
T: Enum,
{
type SchemaType = Vec<T::SchemaType>;
}
impl<T> Enum for Box<T>
where
T: Enum,
{
type SchemaType = T::SchemaType;
}
pub trait InputObject: serde::Serialize {
type SchemaType;
}
impl<T> InputObject for Option<T>
where
T: InputObject,
{
type SchemaType = Option<T::SchemaType>;
}
impl<T> InputObject for Vec<T>
where
T: InputObject,
{
type SchemaType = Vec<T::SchemaType>;
}
impl<T> InputObject for [T]
where
T: InputObject,
{
type SchemaType = Vec<T::SchemaType>;
}
impl<T, const SIZE: usize> InputObject for [T; SIZE]
where
T: InputObject,
Self: serde::Serialize,
{
type SchemaType = Vec<T::SchemaType>;
}
impl<T> InputObject for Box<T>
where
T: InputObject,
{
type SchemaType = T::SchemaType;
}
impl<T: ?Sized> InputObject for &T
where
T: InputObject,
{
type SchemaType = T::SchemaType;
}