{-# language ConstraintKinds #-}
{-# language DataKinds #-}
{-# language ExistentialQuantification #-}
{-# language GADTs #-}
{-# language PolyKinds #-}
{-# language TypeFamilies #-}
{-# language TypeOperators #-}
{-# language UndecidableInstances #-}
module Mu.Rpc (
Service', Service(..)
, ServiceAnnotation, Package, FindPackageName
, Method(..), (:-->:)
, TypeRef(..), Argument(..), Return(..)
) where
import Data.Kind
import GHC.TypeLits
import qualified Language.Haskell.TH as TH
import Mu.Schema
import Mu.Schema.Registry
type Service' = Service Symbol Symbol
type ServiceAnnotation = Type
data Service serviceName methodName
= Service serviceName [ServiceAnnotation] [Method methodName]
data Package (s :: Symbol)
type family FindPackageName (anns :: [ServiceAnnotation]) :: Symbol where
FindPackageName '[] = TypeError ('Text "Cannot find package name for the service")
FindPackageName (Package s ': rest) = s
FindPackageName (other ': rest) = FindPackageName rest
data Method methodName
= Method methodName [ServiceAnnotation] [Argument] Return
type family (:-->:) (s :: Service snm mnm) (m :: mnm) :: Method mnm where
'Service sname anns methods :-->: m = LookupMethod methods m
type family LookupMethod (s :: [Method mnm]) (m :: snm) :: Method snm where
LookupMethod '[] m = TypeError ('Text "could not find method " ':<>: 'ShowType m)
LookupMethod ('Method m anns args r ': ms) m = 'Method m anns args r
LookupMethod (other ': ms) m = LookupMethod ms m
data TypeRef where
ViaSchema :: Schema typeName fieldName -> typeName -> TypeRef
ViaRegistry :: Registry -> Type -> Nat -> TypeRef
ViaTH :: TH.Type -> TypeRef
data Argument where
ArgSingle :: TypeRef -> Argument
ArgStream :: TypeRef -> Argument
data Return where
RetNothing :: Return
RetSingle :: TypeRef -> Return
RetThrows :: TypeRef -> TypeRef -> Return
RetStream :: TypeRef -> Return