{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Data.Morpheus.Server.TH.Declare
  ( runDeclare,
  )
where

import Data.Morpheus.CodeGen.Internal.AST
  ( CodeGenConfig (..),
    ServerTypeDefinition,
  )
import Data.Morpheus.Server.TH.Declare.GQLType
  ( deriveGQLType,
  )
import Data.Morpheus.Server.TH.Declare.Type
  ( declareType,
  )
import Data.Morpheus.Server.TH.Utils (ServerDec)
import Language.Haskell.TH
import Relude

runDeclare :: Declare a => CodeGenConfig -> a -> Q [Dec]
runDeclare :: forall a. Declare a => CodeGenConfig -> a -> Q [Dec]
runDeclare CodeGenConfig
ctx a
a = forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (forall a. Declare a => a -> ServerDec [Dec]
declare a
a) CodeGenConfig
ctx

class Declare a where
  declare :: a -> ServerDec [Dec]

instance Declare a => Declare [a] where
  declare :: [a] -> ServerDec [Dec]
declare = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall a. Declare a => a -> ServerDec [Dec]
declare

instance Declare ServerTypeDefinition where
  declare :: ServerTypeDefinition -> ServerDec [Dec]
declare ServerTypeDefinition
typeDef = (ServerTypeDefinition -> [Dec]
declareType ServerTypeDefinition
typeDef forall a. Semigroup a => a -> a -> a
<>) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ServerTypeDefinition -> ServerDec [Dec]
deriveGQLType ServerTypeDefinition
typeDef