{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Data.Morpheus.Server.Deriving.App
  ( RootResolverConstraint,
    deriveSchema,
    deriveApp,
  )
where

-- MORPHEUS

import Control.Monad (Monad)
import Data.Functor.Identity (Identity (..))
import Data.Morpheus.App
  ( App (..),
    mkApp,
  )
import Data.Morpheus.App.Internal.Resolving
  ( resultOr,
  )
import Data.Morpheus.Server.Deriving.Encode
  ( EncodeConstraints,
    deriveModel,
  )
import Data.Morpheus.Server.Deriving.Schema
  ( SchemaConstraints,
    deriveSchema,
  )
import Data.Morpheus.Types
  ( RootResolver (..),
  )

type RootResolverConstraint m e query mutation subscription =
  ( EncodeConstraints e m query mutation subscription,
    SchemaConstraints e m query mutation subscription,
    Monad m
  )

deriveApp ::
  RootResolverConstraint m event query mut sub =>
  RootResolver m event query mut sub ->
  App event m
deriveApp :: RootResolver m event query mut sub -> App event m
deriveApp RootResolver m event query mut sub
root =
  (GQLErrors -> App event m)
-> (Schema CONST -> App event m)
-> Result Any (Schema CONST)
-> App event m
forall a' a e. (GQLErrors -> a') -> (a -> a') -> Result e a -> a'
resultOr
    GQLErrors -> App event m
forall event (m :: * -> *). GQLErrors -> App event m
FailApp
    (Schema CONST -> RootResolverValue event m -> App event m
forall (s :: Stage) e (m :: * -> *).
ValidateSchema s =>
Schema s -> RootResolverValue e m -> App e m
`mkApp` RootResolver m event query mut sub -> RootResolverValue event m
forall e (m :: * -> *) (query :: (* -> *) -> *)
       (mut :: (* -> *) -> *) (sub :: (* -> *) -> *).
(Monad m, EncodeConstraints e m query mut sub) =>
RootResolver m e query mut sub -> RootResolverValue e m
deriveModel RootResolver m event query mut sub
root)
    (Identity (RootResolver m event query mut sub)
-> Result Any (Schema CONST)
forall k
       (root :: (* -> *)
                -> * -> ((* -> *) -> *) -> ((* -> *) -> *) -> ((* -> *) -> *) -> k)
       (proxy :: k -> *) (m :: * -> *) e (query :: (* -> *) -> *)
       (mut :: (* -> *) -> *) (subs :: (* -> *) -> *) (f :: * -> *).
(SchemaConstraints e m query mut subs, Failure GQLErrors f) =>
proxy (root m e query mut subs) -> f (Schema CONST)
deriveSchema (RootResolver m event query mut sub
-> Identity (RootResolver m event query mut sub)
forall a. a -> Identity a
Identity RootResolver m event query mut sub
root))