{-# language ConstraintKinds #-}
{-# language DataKinds #-}
{-# language ExistentialQuantification #-}
{-# language GADTs #-}
{-# language PolyKinds #-}
{-# language TypeFamilies #-}
{-# language TypeOperators #-}
{-# language UndecidableInstances #-}
module Mu.Rpc (
Package', Package(..)
, Service', Service(..), Object
, ServiceAnnotation, Method', Method(..), ObjectField
, LookupService, LookupMethod
, TypeRef(..), Argument', Argument(..), Return(..)
) where
import Data.Kind
import GHC.TypeLits
import qualified Language.Haskell.TH as TH
import Mu.Schema
import Mu.Schema.Registry
type Package' = Package Symbol Symbol Symbol
type Service' = Service Symbol Symbol Symbol
type Method' = Method Symbol Symbol Symbol
type Argument' = Argument Symbol Symbol
type ServiceAnnotation = Type
data Package serviceName methodName argName
= Package (Maybe serviceName)
[Service serviceName methodName argName]
data Service serviceName methodName argName
= Service serviceName
[ServiceAnnotation]
[Method serviceName methodName argName]
data Method serviceName methodName argName
= Method methodName [ServiceAnnotation]
[Argument serviceName argName]
(Return serviceName)
type Object = 'Service
type ObjectField = 'Method
type family LookupService (ss :: [Service snm mnm anm]) (s :: snm) :: Service snm mnm anm where
LookupService '[] s = TypeError ('Text "could not find method " ':<>: 'ShowType s)
LookupService ('Service s anns ms ': ss) s = 'Service s anns ms
LookupService (other ': ss) s = LookupService ss s
type family LookupMethod (s :: [Method snm mnm anm]) (m :: mnm) :: Method snm mnm anm 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 serviceName where
PrimitiveRef :: Type -> TypeRef serviceName
ObjectRef :: serviceName -> TypeRef serviceName
SchemaRef :: Schema typeName fieldName -> typeName -> TypeRef serviceName
RegistryRef :: Registry -> Type -> Nat -> TypeRef serviceName
THRef :: TH.Type -> TypeRef serviceName
ListRef :: TypeRef serviceName -> TypeRef serviceName
OptionalRef :: TypeRef serviceName -> TypeRef serviceName
data Argument serviceName argName where
ArgSingle :: Maybe argName -> [ServiceAnnotation]
-> TypeRef serviceName -> Argument serviceName argName
ArgStream :: Maybe argName -> [ServiceAnnotation]
-> TypeRef serviceName -> Argument serviceName argName
data Return serviceName where
RetNothing :: Return serviceName
RetSingle :: TypeRef serviceName -> Return serviceName
RetStream :: TypeRef serviceName -> Return serviceName
RetThrows :: TypeRef serviceName -> TypeRef serviceName -> Return serviceName