{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Data.Morpheus.Server.Types.GQLType
  ( GQLType
      ( KIND,
        description,
        getDescriptions,
        typeOptions,
        getDirectives,
        defaultValues,
        __type
      ),
    GQLTypeOptions (..),
    defaultTypeOptions,
    TypeData (..),
    __isEmptyType,
    __typeData,
  )
where

-- MORPHEUS

import Data.Morpheus.App.Internal.Resolving
  ( Resolver,
    SubscriptionField,
  )
import Data.Morpheus.Kind
  ( CUSTOM,
    DerivingKind,
    SCALAR,
    TYPE,
    WRAPPER,
  )
import Data.Morpheus.NamedResolvers (NamedResolverT (..))
import Data.Morpheus.Server.Deriving.Utils.Kinded (CategoryValue (..))
import Data.Morpheus.Server.Types.SchemaT
  ( TypeFingerprint (..),
  )
import Data.Morpheus.Server.Types.Types
  ( Arg,
    Pair,
    TypeGuard,
    Undefined (..),
  )
import Data.Morpheus.Types.ID (ID)
import Data.Morpheus.Types.Internal.AST
  ( CONST,
    Description,
    Directives,
    TypeCategory (..),
    TypeName,
    TypeWrapper (..),
    Value,
    mkBaseType,
    packName,
    toNullable,
    unpackName,
  )
import Data.Sequence (Seq)
import Data.Text
  ( intercalate,
    pack,
    unpack,
  )
import Data.Typeable
  ( TyCon,
    TypeRep,
    splitTyConApp,
    tyConFingerprint,
    tyConName,
    typeRep,
    typeRepTyCon,
  )
import Data.Vector (Vector)
import Relude hiding (Seq, Undefined, intercalate)

data TypeData = TypeData
  { TypeData -> TypeName
gqlTypeName :: TypeName,
    TypeData -> TypeWrapper
gqlWrappers :: TypeWrapper,
    TypeData -> TypeFingerprint
gqlFingerprint :: TypeFingerprint
  }
  deriving (Int -> TypeData -> ShowS
[TypeData] -> ShowS
TypeData -> String
(Int -> TypeData -> ShowS)
-> (TypeData -> String) -> ([TypeData] -> ShowS) -> Show TypeData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TypeData] -> ShowS
$cshowList :: [TypeData] -> ShowS
show :: TypeData -> String
$cshow :: TypeData -> String
showsPrec :: Int -> TypeData -> ShowS
$cshowsPrec :: Int -> TypeData -> ShowS
Show)

-- | Options that specify how to map GraphQL field, type, and constructor names
-- to and from their Haskell equivalent.
--
-- Options can be set using record syntax on 'defaultOptions' with the fields
-- below.
data GQLTypeOptions = GQLTypeOptions
  { -- | Function applied to field labels.
    -- Handy for removing common record prefixes for example.
    GQLTypeOptions -> ShowS
fieldLabelModifier :: String -> String,
    -- | Function applied to constructor tags.
    GQLTypeOptions -> ShowS
constructorTagModifier :: String -> String,
    -- | Construct a new type name depending on whether it is an input,
    -- and being given the original type name.
    GQLTypeOptions -> Bool -> ShowS
typeNameModifier :: Bool -> String -> String
  }

-- | Default encoding 'GQLTypeOptions':
--
-- @
-- 'GQLTypeOptions'
--   { 'fieldLabelModifier'      = id
--   , 'constructorTagModifier'  = id
--   , 'typeNameModifier'        = const id
--   }
-- @
defaultTypeOptions :: GQLTypeOptions
defaultTypeOptions :: GQLTypeOptions
defaultTypeOptions =
  GQLTypeOptions :: ShowS -> ShowS -> (Bool -> ShowS) -> GQLTypeOptions
GQLTypeOptions
    { fieldLabelModifier :: ShowS
fieldLabelModifier = ShowS
forall a. a -> a
id,
      constructorTagModifier :: ShowS
constructorTagModifier = ShowS
forall a. a -> a
id,
      -- default is just a pass through for the original type name
      typeNameModifier :: Bool -> ShowS
typeNameModifier = ShowS -> Bool -> ShowS
forall a b. a -> b -> a
const ShowS
forall a. a -> a
id
    }

__typeData ::
  forall kinded (kind :: TypeCategory) (a :: Type).
  (GQLType a, CategoryValue kind) =>
  kinded kind a ->
  TypeData
__typeData :: kinded kind a -> TypeData
__typeData kinded kind a
proxy = kinded kind a -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type kinded kind a
proxy (Proxy kind -> TypeCategory
forall (c :: TypeCategory) (f :: TypeCategory -> *).
CategoryValue c =>
f c -> TypeCategory
categoryValue (Proxy kind
forall k (t :: k). Proxy t
Proxy @kind))

getTypename :: Typeable a => f a -> TypeName
getTypename :: f a -> TypeName
getTypename = Text -> TypeName
forall a (t :: NAME). NamePacking a => a -> Name t
packName (Text -> TypeName) -> (f a -> Text) -> f a -> TypeName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> Text
intercalate Text
"" ([Text] -> Text) -> (f a -> [Text]) -> f a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f a -> [Text]
forall a (f :: * -> *). Typeable a => f a -> [Text]
getTypeConstructorNames

getTypeConstructorNames :: Typeable a => f a -> [Text]
getTypeConstructorNames :: f a -> [Text]
getTypeConstructorNames = (TyCon -> Text) -> [TyCon] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> Text
pack (String -> Text) -> (TyCon -> String) -> TyCon -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyCon -> String
tyConName (TyCon -> String) -> (TyCon -> TyCon) -> TyCon -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyCon -> TyCon
replacePairCon) ([TyCon] -> [Text]) -> (f a -> [TyCon]) -> f a -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f a -> [TyCon]
forall a (f :: * -> *). Typeable a => f a -> [TyCon]
getTypeConstructors

getTypeConstructors :: Typeable a => f a -> [TyCon]
getTypeConstructors :: f a -> [TyCon]
getTypeConstructors = (TyCon, [TypeRep]) -> [TyCon]
ignoreResolver ((TyCon, [TypeRep]) -> [TyCon])
-> (f a -> (TyCon, [TypeRep])) -> f a -> [TyCon]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeRep -> (TyCon, [TypeRep])
splitTyConApp (TypeRep -> (TyCon, [TypeRep]))
-> (f a -> TypeRep) -> f a -> (TyCon, [TypeRep])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f a -> TypeRep
forall k (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep

prefixInputs :: GQLTypeOptions -> GQLTypeOptions
prefixInputs :: GQLTypeOptions -> GQLTypeOptions
prefixInputs GQLTypeOptions
options = GQLTypeOptions
options {typeNameModifier :: Bool -> ShowS
typeNameModifier = \Bool
isInput String
name -> if Bool
isInput then String
"Input" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
name else String
name}

deriveTypeData :: Typeable a => f a -> (Bool -> String -> String) -> TypeCategory -> TypeData
deriveTypeData :: f a -> (Bool -> ShowS) -> TypeCategory -> TypeData
deriveTypeData f a
proxy Bool -> ShowS
typeNameModifier TypeCategory
cat =
  TypeData :: TypeName -> TypeWrapper -> TypeFingerprint -> TypeData
TypeData
    { gqlTypeName :: TypeName
gqlTypeName = Text -> TypeName
forall a (t :: NAME). NamePacking a => a -> Name t
packName (Text -> TypeName) -> (String -> Text) -> String -> TypeName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> TypeName) -> String -> TypeName
forall a b. (a -> b) -> a -> b
$ Bool -> ShowS
typeNameModifier (TypeCategory
cat TypeCategory -> TypeCategory -> Bool
forall a. Eq a => a -> a -> Bool
== TypeCategory
IN) String
originalTypeName,
      gqlWrappers :: TypeWrapper
gqlWrappers = TypeWrapper
mkBaseType,
      gqlFingerprint :: TypeFingerprint
gqlFingerprint = TypeCategory -> f a -> TypeFingerprint
forall a (f :: * -> *).
Typeable a =>
TypeCategory -> f a -> TypeFingerprint
getFingerprint TypeCategory
cat f a
proxy
    }
  where
    originalTypeName :: String
originalTypeName = Text -> String
unpack (Text -> String) -> (TypeName -> Text) -> TypeName -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeName -> Text
forall a (t :: NAME). NamePacking a => Name t -> a
unpackName (TypeName -> String) -> TypeName -> String
forall a b. (a -> b) -> a -> b
$ f a -> TypeName
forall a (f :: * -> *). Typeable a => f a -> TypeName
getTypename f a
proxy

getFingerprint :: Typeable a => TypeCategory -> f a -> TypeFingerprint
getFingerprint :: TypeCategory -> f a -> TypeFingerprint
getFingerprint TypeCategory
category = TypeCategory -> [Fingerprint] -> TypeFingerprint
TypeableFingerprint TypeCategory
category ([Fingerprint] -> TypeFingerprint)
-> (f a -> [Fingerprint]) -> f a -> TypeFingerprint
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TyCon -> Fingerprint) -> [TyCon] -> [Fingerprint]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TyCon -> Fingerprint
tyConFingerprint ([TyCon] -> [Fingerprint])
-> (f a -> [TyCon]) -> f a -> [Fingerprint]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f a -> [TyCon]
forall a (f :: * -> *). Typeable a => f a -> [TyCon]
getTypeConstructors

mkTypeData :: TypeName -> a -> TypeData
mkTypeData :: TypeName -> a -> TypeData
mkTypeData TypeName
name a
_ =
  TypeData :: TypeName -> TypeWrapper -> TypeFingerprint -> TypeData
TypeData
    { gqlTypeName :: TypeName
gqlTypeName = TypeName
name,
      gqlFingerprint :: TypeFingerprint
gqlFingerprint = TypeName -> TypeFingerprint
InternalFingerprint TypeName
name,
      gqlWrappers :: TypeWrapper
gqlWrappers = TypeWrapper
mkBaseType
    }

list :: TypeWrapper -> TypeWrapper
list :: TypeWrapper -> TypeWrapper
list = (TypeWrapper -> Bool -> TypeWrapper)
-> Bool -> TypeWrapper -> TypeWrapper
forall a b c. (a -> b -> c) -> b -> a -> c
flip TypeWrapper -> Bool -> TypeWrapper
TypeList Bool
True

wrapper :: (TypeWrapper -> TypeWrapper) -> TypeData -> TypeData
wrapper :: (TypeWrapper -> TypeWrapper) -> TypeData -> TypeData
wrapper TypeWrapper -> TypeWrapper
f TypeData {TypeWrapper
TypeName
TypeFingerprint
gqlFingerprint :: TypeFingerprint
gqlWrappers :: TypeWrapper
gqlTypeName :: TypeName
gqlFingerprint :: TypeData -> TypeFingerprint
gqlWrappers :: TypeData -> TypeWrapper
gqlTypeName :: TypeData -> TypeName
..} = TypeData :: TypeName -> TypeWrapper -> TypeFingerprint -> TypeData
TypeData {gqlWrappers :: TypeWrapper
gqlWrappers = TypeWrapper -> TypeWrapper
f TypeWrapper
gqlWrappers, TypeName
TypeFingerprint
gqlFingerprint :: TypeFingerprint
gqlTypeName :: TypeName
gqlFingerprint :: TypeFingerprint
gqlTypeName :: TypeName
..}

-- | replaces typeName (A,B) with Pair_A_B
replacePairCon :: TyCon -> TyCon
replacePairCon :: TyCon -> TyCon
replacePairCon TyCon
x | TyCon
hsPair TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
x = TyCon
gqlPair
  where
    hsPair :: TyCon
hsPair = TypeRep -> TyCon
typeRepTyCon (TypeRep -> TyCon) -> TypeRep -> TyCon
forall a b. (a -> b) -> a -> b
$ Proxy (Int, Int) -> TypeRep
forall k (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy (Int, Int) -> TypeRep) -> Proxy (Int, Int) -> TypeRep
forall a b. (a -> b) -> a -> b
$ Proxy (Int, Int)
forall k (t :: k). Proxy t
Proxy @(Int, Int)
    gqlPair :: TyCon
gqlPair = TypeRep -> TyCon
typeRepTyCon (TypeRep -> TyCon) -> TypeRep -> TyCon
forall a b. (a -> b) -> a -> b
$ Proxy (Pair Int Int) -> TypeRep
forall k (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy (Pair Int Int) -> TypeRep)
-> Proxy (Pair Int Int) -> TypeRep
forall a b. (a -> b) -> a -> b
$ Proxy (Pair Int Int)
forall k (t :: k). Proxy t
Proxy @(Pair Int Int)
replacePairCon TyCon
x = TyCon
x

-- Ignores Resolver name  from typeName
ignoreResolver :: (TyCon, [TypeRep]) -> [TyCon]
ignoreResolver :: (TyCon, [TypeRep]) -> [TyCon]
ignoreResolver (TyCon
con, [TypeRep]
_) | TyCon
con TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TypeRep -> TyCon
typeRepTyCon (Proxy Resolver -> TypeRep
forall k (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy Resolver -> TypeRep) -> Proxy Resolver -> TypeRep
forall a b. (a -> b) -> a -> b
$ Proxy Resolver
forall k (t :: k). Proxy t
Proxy @Resolver) = []
ignoreResolver (TyCon
con, [TypeRep]
_) | TyCon
con TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TypeRep -> TyCon
typeRepTyCon (Proxy NamedResolverT -> TypeRep
forall k (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy NamedResolverT -> TypeRep)
-> Proxy NamedResolverT -> TypeRep
forall a b. (a -> b) -> a -> b
$ Proxy NamedResolverT
forall k (t :: k). Proxy t
Proxy @NamedResolverT) = []
ignoreResolver (TyCon
con, [TypeRep]
args) =
  TyCon
con TyCon -> [TyCon] -> [TyCon]
forall a. a -> [a] -> [a]
: (TypeRep -> [TyCon]) -> [TypeRep] -> [TyCon]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((TyCon, [TypeRep]) -> [TyCon]
ignoreResolver ((TyCon, [TypeRep]) -> [TyCon])
-> (TypeRep -> (TyCon, [TypeRep])) -> TypeRep -> [TyCon]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeRep -> (TyCon, [TypeRep])
splitTyConApp) [TypeRep]
args

-- | GraphQL type, every graphQL type should have an instance of 'GHC.Generics.Generic' and 'GQLType'.
--
--  @
--    ... deriving (Generic, GQLType)
--  @
--
-- if you want to add description
--
--  @
--       ... deriving (Generic)
--
--     instance GQLType ... where
--       description = const "your description ..."
--  @
class GQLType a where
  type KIND a :: DerivingKind
  type KIND a = TYPE

  -- | A description of the type.
  --
  -- Used for documentation in the GraphQL schema.
  description :: f a -> Maybe Text
  description f a
_ = Maybe Text
forall a. Maybe a
Nothing

  -- | A dictionary of descriptions for fields, keyed on field name.
  --
  -- Used for documentation in the GraphQL schema.
  getDescriptions :: f a -> Map Text Description
  getDescriptions f a
_ = Map Text Text
forall a. Monoid a => a
mempty

  typeOptions :: f a -> GQLTypeOptions -> GQLTypeOptions
  typeOptions f a
_ = GQLTypeOptions -> GQLTypeOptions
forall a. a -> a
id

  getDirectives :: f a -> Map Text (Directives CONST)
  getDirectives f a
_ = Map Text (Directives CONST)
forall a. Monoid a => a
mempty

  defaultValues :: f a -> Map Text (Value CONST)
  defaultValues f a
_ = Map Text (Value CONST)
forall a. Monoid a => a
mempty

  __isEmptyType :: f a -> Bool
  __isEmptyType f a
_ = Bool
False

  __type :: f a -> TypeCategory -> TypeData
  default __type :: Typeable a => f a -> TypeCategory -> TypeData
  __type f a
proxy = f a -> (Bool -> ShowS) -> TypeCategory -> TypeData
forall a (f :: * -> *).
Typeable a =>
f a -> (Bool -> ShowS) -> TypeCategory -> TypeData
deriveTypeData f a
proxy Bool -> ShowS
typeNameModifier
    where
      GQLTypeOptions {Bool -> ShowS
typeNameModifier :: Bool -> ShowS
typeNameModifier :: GQLTypeOptions -> Bool -> ShowS
typeNameModifier} = f a -> GQLTypeOptions -> GQLTypeOptions
forall a (f :: * -> *).
GQLType a =>
f a -> GQLTypeOptions -> GQLTypeOptions
typeOptions f a
proxy GQLTypeOptions
defaultTypeOptions

instance GQLType Int where
  type KIND Int = SCALAR
  __type :: f Int -> TypeCategory -> TypeData
__type f Int
_ = TypeName -> TypeCategory -> TypeData
forall a. TypeName -> a -> TypeData
mkTypeData TypeName
"Int"

instance GQLType Double where
  type KIND Double = SCALAR
  __type :: f Double -> TypeCategory -> TypeData
__type f Double
_ = TypeName -> TypeCategory -> TypeData
forall a. TypeName -> a -> TypeData
mkTypeData TypeName
"Float"

instance GQLType Float where
  type KIND Float = SCALAR
  __type :: f Float -> TypeCategory -> TypeData
__type f Float
_ = TypeName -> TypeCategory -> TypeData
forall a. TypeName -> a -> TypeData
mkTypeData TypeName
"Float32"

instance GQLType Text where
  type KIND Text = SCALAR
  __type :: f Text -> TypeCategory -> TypeData
__type f Text
_ = TypeName -> TypeCategory -> TypeData
forall a. TypeName -> a -> TypeData
mkTypeData TypeName
"String"

instance GQLType Bool where
  type KIND Bool = SCALAR
  __type :: f Bool -> TypeCategory -> TypeData
__type f Bool
_ = TypeName -> TypeCategory -> TypeData
forall a. TypeName -> a -> TypeData
mkTypeData TypeName
"Boolean"

instance GQLType ID where
  type KIND ID = SCALAR
  __type :: f ID -> TypeCategory -> TypeData
__type f ID
_ = TypeName -> TypeCategory -> TypeData
forall a. TypeName -> a -> TypeData
mkTypeData TypeName
"ID"

-- WRAPPERS
instance GQLType ()

instance GQLType a => GQLType (Maybe a) where
  type KIND (Maybe a) = WRAPPER
  __type :: f (Maybe a) -> TypeCategory -> TypeData
__type f (Maybe a)
_ = (TypeWrapper -> TypeWrapper) -> TypeData -> TypeData
wrapper TypeWrapper -> TypeWrapper
forall a. Nullable a => a -> a
toNullable (TypeData -> TypeData)
-> (TypeCategory -> TypeData) -> TypeCategory -> TypeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy a -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy a
forall k (t :: k). Proxy t
Proxy @a)

instance GQLType a => GQLType [a] where
  type KIND [a] = WRAPPER
  __type :: f [a] -> TypeCategory -> TypeData
__type f [a]
_ = (TypeWrapper -> TypeWrapper) -> TypeData -> TypeData
wrapper TypeWrapper -> TypeWrapper
list (TypeData -> TypeData)
-> (TypeCategory -> TypeData) -> TypeCategory -> TypeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy a -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy a
forall k (t :: k). Proxy t
Proxy @a)

instance GQLType a => GQLType (Set a) where
  type KIND (Set a) = WRAPPER
  __type :: f (Set a) -> TypeCategory -> TypeData
__type f (Set a)
_ = Proxy [a] -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy [a] -> TypeCategory -> TypeData)
-> Proxy [a] -> TypeCategory -> TypeData
forall a b. (a -> b) -> a -> b
$ Proxy [a]
forall k (t :: k). Proxy t
Proxy @[a]

instance GQLType a => GQLType (NonEmpty a) where
  type KIND (NonEmpty a) = WRAPPER
  __type :: f (NonEmpty a) -> TypeCategory -> TypeData
__type f (NonEmpty a)
_ = Proxy [a] -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy [a] -> TypeCategory -> TypeData)
-> Proxy [a] -> TypeCategory -> TypeData
forall a b. (a -> b) -> a -> b
$ Proxy [a]
forall k (t :: k). Proxy t
Proxy @[a]

instance GQLType a => GQLType (Seq a) where
  type KIND (Seq a) = WRAPPER
  __type :: f (Seq a) -> TypeCategory -> TypeData
__type f (Seq a)
_ = Proxy [a] -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy [a] -> TypeCategory -> TypeData)
-> Proxy [a] -> TypeCategory -> TypeData
forall a b. (a -> b) -> a -> b
$ Proxy [a]
forall k (t :: k). Proxy t
Proxy @[a]

instance GQLType a => GQLType (Vector a) where
  type KIND (Vector a) = WRAPPER
  __type :: f (Vector a) -> TypeCategory -> TypeData
__type f (Vector a)
_ = Proxy [a] -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy [a] -> TypeCategory -> TypeData)
-> Proxy [a] -> TypeCategory -> TypeData
forall a b. (a -> b) -> a -> b
$ Proxy [a]
forall k (t :: k). Proxy t
Proxy @[a]

instance GQLType a => GQLType (SubscriptionField a) where
  type KIND (SubscriptionField a) = WRAPPER
  __type :: f (SubscriptionField a) -> TypeCategory -> TypeData
__type f (SubscriptionField a)
_ = Proxy a -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy a -> TypeCategory -> TypeData)
-> Proxy a -> TypeCategory -> TypeData
forall a b. (a -> b) -> a -> b
$ Proxy a
forall k (t :: k). Proxy t
Proxy @a

instance (Typeable a, Typeable b, GQLType a, GQLType b) => GQLType (Pair a b) where
  typeOptions :: f (Pair a b) -> GQLTypeOptions -> GQLTypeOptions
typeOptions f (Pair a b)
_ = GQLTypeOptions -> GQLTypeOptions
prefixInputs

-- Manual

instance Typeable m => GQLType (Undefined m) where
  type KIND (Undefined m) = CUSTOM
  __isEmptyType :: f (Undefined m) -> Bool
__isEmptyType f (Undefined m)
_ = Bool
True

instance GQLType b => GQLType (a -> b) where
  type KIND (a -> b) = CUSTOM
  __type :: f (a -> b) -> TypeCategory -> TypeData
__type f (a -> b)
_ = Proxy b -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy b -> TypeCategory -> TypeData)
-> Proxy b -> TypeCategory -> TypeData
forall a b. (a -> b) -> a -> b
$ Proxy b
forall k (t :: k). Proxy t
Proxy @b

instance (GQLType k, GQLType v, Typeable k, Typeable v) => GQLType (Map k v) where
  type KIND (Map k v) = CUSTOM
  __type :: f (Map k v) -> TypeCategory -> TypeData
__type f (Map k v)
_ = Proxy [Pair k v] -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy [Pair k v] -> TypeCategory -> TypeData)
-> Proxy [Pair k v] -> TypeCategory -> TypeData
forall a b. (a -> b) -> a -> b
$ Proxy [Pair k v]
forall k (t :: k). Proxy t
Proxy @[Pair k v]

instance GQLType a => GQLType (Resolver o e m a) where
  type KIND (Resolver o e m a) = CUSTOM
  __type :: f (Resolver o e m a) -> TypeCategory -> TypeData
__type f (Resolver o e m a)
_ = Proxy a -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy a -> TypeCategory -> TypeData)
-> Proxy a -> TypeCategory -> TypeData
forall a b. (a -> b) -> a -> b
$ Proxy a
forall k (t :: k). Proxy t
Proxy @a

instance (Typeable a, Typeable b, GQLType a, GQLType b) => GQLType (a, b) where
  __type :: f (a, b) -> TypeCategory -> TypeData
__type f (a, b)
_ = Proxy (Pair a b) -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy (Pair a b) -> TypeCategory -> TypeData)
-> Proxy (Pair a b) -> TypeCategory -> TypeData
forall a b. (a -> b) -> a -> b
$ Proxy (Pair a b)
forall k (t :: k). Proxy t
Proxy @(Pair a b)
  typeOptions :: f (a, b) -> GQLTypeOptions -> GQLTypeOptions
typeOptions f (a, b)
_ = GQLTypeOptions -> GQLTypeOptions
prefixInputs

instance (GQLType value) => GQLType (Arg name value) where
  type KIND (Arg name value) = CUSTOM
  __type :: f (Arg name value) -> TypeCategory -> TypeData
__type f (Arg name value)
_ = Proxy value -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy value
forall k (t :: k). Proxy t
Proxy @value)

instance (GQLType interface) => GQLType (TypeGuard interface possibleTypes) where
  type KIND (TypeGuard interface possibleTypes) = CUSTOM
  __type :: f (TypeGuard interface possibleTypes) -> TypeCategory -> TypeData
__type f (TypeGuard interface possibleTypes)
_ = Proxy interface -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy interface
forall k (t :: k). Proxy t
Proxy @interface)

instance (GQLType a) => GQLType (Proxy a) where
  type KIND (Proxy a) = KIND a
  __type :: f (Proxy a) -> TypeCategory -> TypeData
__type f (Proxy a)
_ = Proxy a -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy a
forall k (t :: k). Proxy t
Proxy @a)

instance (GQLType a) => GQLType (NamedResolverT m a) where
  type KIND (NamedResolverT m a) = CUSTOM
  __type :: f (NamedResolverT m a) -> TypeCategory -> TypeData
__type f (NamedResolverT m a)
_ = Proxy a -> TypeCategory -> TypeData
forall a (f :: * -> *).
GQLType a =>
f a -> TypeCategory -> TypeData
__type (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a)