From 68ae671af040c5bcd443309a17188118557ef38f Mon Sep 17 00:00:00 2001 From: Jens Nolte <git@queezle.net> Date: Wed, 11 Aug 2021 16:23:57 +0200 Subject: [PATCH] Add signature to handler --- src/Quasar/Network/TH.hs | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/Quasar/Network/TH.hs b/src/Quasar/Network/TH.hs index 5ef8d5e..a57db0f 100644 --- a/src/Quasar/Network/TH.hs +++ b/src/Quasar/Network/TH.hs @@ -25,6 +25,7 @@ import GHC.Records.Compat (HasField) import Language.Haskell.TH hiding (interruptible) import Language.Haskell.TH.Syntax import Quasar.Awaitable +import Quasar.Core import Quasar.Network.Multiplexer import Quasar.Network.Runtime import Quasar.Network.Runtime.Observable @@ -160,7 +161,7 @@ clientRequestStub api req = do stubName = clientRequestStubName api req makeStubSig :: Q [Type] -> Q Type makeStubSig arguments = - [t|forall m. MonadIO m => $(buildFunctionType arguments [t|m $(buildTupleType (liftA2 (<>) optionalResultType (resourceTypes req)))|])|] + [t|forall m. MonadIO m => $(buildFunctionType arguments [t|m $(buildTupleType (liftA2 (<>) optionalResultType (stubResourceTypes req)))|])|] optionalResultType :: Q [Type] optionalResultType = case req.mResponse of Nothing -> pure [] @@ -282,12 +283,22 @@ makeServer api@RpcApi{functions} code = sequence [protocolImplDec, logicInstance clause [requestConP, listP (varP <$> channelNames)] (normalB (packResponse req.mResponse (applyResources resourceEs (varE handlerName)))) - [handlerDec handlerName resourceNames ctx] + [ + handlerSig handlerName, + handlerDec handlerName resourceNames ctx + ] + handlerSig :: Name -> Q Dec + handlerSig handlerName = sigD handlerName (buildFunctionType (implResourceTypes req) [t|IO $(resultType)|]) handlerDec :: Name -> [Name] -> RequestHandlerContext -> Q Dec handlerDec handlerName resourceNames ctx = funD handlerName [clause (varP <$> resourceNames) (normalB (req.handlerE ctx)) []] applyResources :: [Q Exp] -> Q Exp -> Q Exp applyResources resourceEs implE = applyM implE resourceEs + resultType :: Q Type + resultType = + case req.mResponse of + Nothing -> [t|()|] + Just resp -> [t|$(buildTupleType (sequence ((.ty) <$> resp.fields)))|] invalidChannelCountClause :: Q Clause invalidChannelCountClause = do @@ -522,26 +533,28 @@ clientRequestStubSig api req = makeStubSig (sequence ((clientType api) : ((.ty) where makeStubSig :: Q [Type] -> Q Type makeStubSig arguments = - [t|forall m. MonadIO m => $(buildFunctionType arguments [t|m $(buildTupleType (liftA2 (<>) optionalResultType resourceTypes))|])|] - resourceTypes :: Q [Type] - resourceTypes = sequence $ resourceType <$> req.createdResources + [t|forall m. MonadIO m => $(buildFunctionType arguments [t|m $(buildTupleType (liftA2 (<>) optionalResultType (stubResourceTypes req)))|])|] optionalResultType :: Q [Type] optionalResultType = case req.mResponse of Nothing -> pure [] Just resp -> sequence [[t|Awaitable $(buildTupleType (sequence ((.ty) <$> resp.fields)))|]] - resourceType :: RequestCreateResource -> Q Type - resourceType RequestCreateChannel = [t|Channel|] - resourceType (RequestCreateStream up down) = [t|Stream $up $down|] clientRequestStubSigDec :: RpcApi -> Request -> Q Dec clientRequestStubSigDec api req = sigD (clientRequestStubName api req) (clientRequestStubSig api req) -resourceTypes :: Request -> Q [Type] -resourceTypes req = sequence $ resourceType <$> req.createdResources +stubResourceTypes :: Request -> Q [Type] +stubResourceTypes req = sequence $ stubResourceType <$> req.createdResources -resourceType :: RequestCreateResource -> Q Type -resourceType RequestCreateChannel = [t|Channel|] -resourceType (RequestCreateStream up down) = [t|Stream $up $down|] +implResourceTypes :: Request -> Q [Type] +implResourceTypes req = sequence $ implResourceType <$> req.createdResources + +stubResourceType :: RequestCreateResource -> Q Type +stubResourceType RequestCreateChannel = [t|Channel|] +stubResourceType (RequestCreateStream up down) = [t|Stream $up $down|] + +implResourceType :: RequestCreateResource -> Q Type +implResourceType RequestCreateChannel = [t|Channel|] +implResourceType (RequestCreateStream up down) = [t|Stream $down $up|] resourceNamePrefix :: RequestCreateResource -> String resourceNamePrefix RequestCreateChannel = "channel" -- GitLab