{-# language DataKinds #-}
{-# language GADTs #-}
{-# language PolyKinds #-}
{-# language TypeFamilies #-}
{-# language TypeOperators #-}
{-# language UndecidableInstances #-}
module Mu.Rpc.Annotations
( RpcAnnotation (..)
, AnnotatedPackage
, GetPackageAnnotation
, GetPackageAnnotationMay
, GetServiceAnnotation
, GetServiceAnnotationMay
, GetMethodAnnotation
, GetMethodAnnotationMay
, GetArgAnnotation
, GetArgAnnotationMay
)
where
import GHC.TypeLits
import Mu.Rpc
data RpcAnnotation domain serviceName methodName argName where
AnnPackage :: domain
-> RpcAnnotation domain serviceName methodName argName
AnnService :: serviceName -> domain
-> RpcAnnotation domain serviceName methodName argName
AnnMethod :: serviceName -> methodName -> domain
-> RpcAnnotation domain serviceName methodName argName
AnnArg :: serviceName -> methodName -> argName -> domain
-> RpcAnnotation domain serviceName methodName argName
type family AnnotatedPackage domain (sch :: Package serviceName methodName argName tyRef) ::
[RpcAnnotation domain serviceName methodName argName]
type family GetPackageAnnotation (anns :: [RpcAnnotation domain s m a]) :: domain where
GetPackageAnnotation '[]
= TypeError ('Text "cannot find package annotation")
GetPackageAnnotation ('AnnPackage d ': rs) = d
GetPackageAnnotation (r ': rs) = GetPackageAnnotation rs
type family GetPackageAnnotationMay (anns :: [RpcAnnotation domain s m a]) :: Maybe domain where
GetPackageAnnotationMay '[] = 'Nothing
GetPackageAnnotationMay ('AnnPackage d ': rs) = 'Just d
GetPackageAnnotationMay (r ': rs) = GetPackageAnnotationMay rs
type family GetServiceAnnotation (anns :: [RpcAnnotation domain s m a]) (snm :: s) :: domain where
GetServiceAnnotation '[] snm
= TypeError ('Text "cannot find service annotation for " ':<>: 'ShowType snm)
GetServiceAnnotation ('AnnService snm d ': rs) snm = d
GetServiceAnnotation (r ': rs) snm = GetServiceAnnotation rs snm
type family GetServiceAnnotationMay (anns :: [RpcAnnotation domain s m a]) (snm :: s) :: Maybe domain where
GetServiceAnnotationMay '[] snm = 'Nothing
GetServiceAnnotationMay ('AnnService snm d ': rs) snm = 'Just d
GetServiceAnnotationMay (r ': rs) snm = GetServiceAnnotationMay rs snm
type family GetMethodAnnotation (anns :: [RpcAnnotation domain s m a]) (snm :: s) (mnm :: m) :: domain where
GetMethodAnnotation '[] snm mnm
= TypeError ('Text "cannot find method annotation for " ':<>: 'ShowType snm ':<>: 'Text "/" ':<>: 'ShowType mnm)
GetMethodAnnotation ('AnnMethod snm mnm d ': rs) snm mnm = d
GetMethodAnnotation (r ': rs) snm mnm = GetMethodAnnotation rs snm mnm
type family GetMethodAnnotationMay (anns :: [RpcAnnotation domain s m a]) (snm :: s) (mnm :: m) :: Maybe domain where
GetMethodAnnotationMay '[] snm mnm = 'Nothing
GetMethodAnnotationMay ('AnnMethod snm mnm d ': rs) snm mnm = 'Just d
GetMethodAnnotationMay (r ': rs) snm mnm = GetMethodAnnotationMay rs snm mnm
type family GetArgAnnotation (anns :: [RpcAnnotation domain s m a]) (snm :: s) (mnm :: m) (anm :: a) :: domain where
GetArgAnnotation '[] snm mnm anm
= TypeError ('Text "cannot find argument annotation for " ':<>: 'ShowType snm ':<>: 'Text "/" ':<>: 'ShowType mnm ':<>: 'Text "/" ':<>: 'ShowType anm)
GetArgAnnotation ('AnnArg snm mnm anm d ': rs) snm mnm anm = d
GetArgAnnotation (r ': rs) snm mnm anm = GetArgAnnotation rs snm mnm anm
type family GetArgAnnotationMay (anns :: [RpcAnnotation domain s m a]) (snm :: s) (mnm :: m) (anm :: a) :: Maybe domain where
GetArgAnnotationMay '[] snm mnm anm = 'Nothing
GetArgAnnotationMay ('AnnArg snm mnm anm d ': rs) snm mnm anm = 'Just d
GetArgAnnotationMay (r ': rs) snm mnm anm = GetArgAnnotationMay rs snm mnm anm