{-# LANGUAGE ConstrainedClassMethods #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskellQuotes #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE NoImplicitPrelude #-} module Data.Morpheus.Client.Declare.Fetch ( declareFetch, ) where import Data.Morpheus.Client.Fetch (Fetch (..)) import Data.Morpheus.Client.Internal.Types ( FetchDefinition (..), TypeNameTH (..), ) import Data.Morpheus.CodeGen.Internal.TH ( applyCons, toCon, typeInstanceDec, ) import qualified Data.Text as T import Language.Haskell.TH ( Dec, Q, Type, clause, cxt, funD, instanceD, normalB, ) import Relude hiding (ByteString, Type) declareFetch :: Text -> FetchDefinition -> Q [Dec] declareFetch :: Text -> FetchDefinition -> Q [Dec] declareFetch Text query FetchDefinition {Maybe TypeNameTH clientArgumentsTypeName :: FetchDefinition -> Maybe TypeNameTH clientArgumentsTypeName :: Maybe TypeNameTH clientArgumentsTypeName, TypeNameTH rootTypeName :: FetchDefinition -> TypeNameTH rootTypeName :: TypeNameTH rootTypeName} = forall (f :: * -> *) a. Applicative f => a -> f a pure forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall (m :: * -> *). Quote m => m Cxt -> m Type -> [m Dec] -> m Dec instanceD (forall (m :: * -> *). Quote m => [m Type] -> m Cxt cxt []) Q Type iHead [Q Dec] methods where queryString :: String queryString = Text -> String T.unpack Text query typeName :: TypeName typeName = TypeNameTH -> TypeName typename TypeNameTH rootTypeName iHead :: Q Type iHead = forall con cons. (ToName con, ToName cons) => con -> [cons] -> Q Type applyCons ''Fetch [TypeName typeName] methods :: [Q Dec] methods = [ forall (m :: * -> *). Quote m => Name -> [m Clause] -> m Dec funD 'fetch [forall (m :: * -> *). Quote m => [m Pat] -> m Body -> [m Dec] -> m Clause clause [] (forall (m :: * -> *). Quote m => m Exp -> m Body normalB [|__fetch queryString typeName|]) []], forall (f :: * -> *) a. Applicative f => a -> f a pure forall a b. (a -> b) -> a -> b $ Name -> Type -> Type -> Dec typeInstanceDec ''Args (forall a b. ToCon a b => a -> b toCon TypeName typeName) (Maybe TypeNameTH -> Type argumentType Maybe TypeNameTH clientArgumentsTypeName) ] argumentType :: Maybe TypeNameTH -> Type argumentType :: Maybe TypeNameTH -> Type argumentType Maybe TypeNameTH Nothing = forall a b. ToCon a b => a -> b toCon (String "()" :: String) argumentType (Just TypeNameTH clientTypeName) = forall a b. ToCon a b => a -> b toCon (TypeNameTH -> TypeName typename TypeNameTH clientTypeName)