diff --git a/src/Network/GRPC/HighLevel/Client.hs b/src/Network/GRPC/HighLevel/Client.hs index abc5c25..619b31f 100644 --- a/src/Network/GRPC/HighLevel/Client.hs +++ b/src/Network/GRPC/HighLevel/Client.hs @@ -31,6 +31,7 @@ module Network.GRPC.HighLevel.Client -- * Client utility functions , acquireClient + , simplifyServerStreaming , simplifyUnary ) @@ -147,20 +148,57 @@ acquireClient cfg impl = do c <- managed (LL.withClient g cfg) liftIO (impl c) --- | A utility for simplifying gRPC client requests in common cases; you can use --- this to avoid 'ClientRequest' and 'ClientResponse' pattern-matching +-- | A utility for simplifying server-streaming gRPC client requests; you can +-- use this to avoid 'ClientRequest' and 'ClientResult' pattern-matching -- boilerplate at call sites. +simplifyServerStreaming :: TimeoutSeconds + -- ^ RPC call timeout, in seconds + -> MetadataMap + -- ^ RPC call metadata + -> (ClientError -> IO StatusDetails) + -- ^ Handler for client errors + -> (StatusCode -> StatusDetails -> IO StatusDetails) + -- ^ Handler for non-StatusOk response + -> (ClientRequest 'ServerStreaming request response + -> IO (ClientResult 'ServerStreaming response)) + -- ^ Endpoint implementation (typically generated by grpc-haskell) + -> request + -- ^ Request payload + -> (MetadataMap -> StreamRecv response -> IO ()) + -- ^ Stream handler; note that the 'StreamRecv' + -- action must be called repeatedly in order to + -- consume the stream + -> IO StatusDetails +simplifyServerStreaming timeout meta clientError nonStatusOkError f x handler = do + + let request = ClientReaderRequest x timeout meta handler + + response <- f request + + case response of + ClientReaderResponse _ StatusOk details + -> pure details + + ClientReaderResponse _ statusCode details + -> nonStatusOkError statusCode details + + ClientErrorResponse err + -> clientError err + +-- | A utility for simplifying unary gRPC client requests; you can use this to +-- avoid 'ClientRequest' and 'ClientResult' pattern-matching boilerplate at +-- call sites. simplifyUnary :: TimeoutSeconds -- ^ RPC call timeout, in seconds -> MetadataMap -- ^ RPC call metadata - -> (ClientError -> IO (b, StatusDetails)) + -> (ClientError -> IO (response, StatusDetails)) -- ^ Handler for client errors - -> (b -> StatusCode -> StatusDetails -> IO (b, StatusDetails)) + -> (response -> StatusCode -> StatusDetails -> IO (response, StatusDetails)) -- ^ Handler for non-StatusOK responses - -> (ClientRequest 'Normal a b -> IO (ClientResult 'Normal b)) - -- ^ gRPC function implementation (typically generated by gRPC-haskell) - -> (a -> IO (b, StatusDetails)) + -> (ClientRequest 'Normal request response -> IO (ClientResult 'Normal response)) + -- ^ Endpoint implementation (typically generated by grpc-haskell) + -> (request -> IO (response, StatusDetails)) -- ^ The simplified happy-path (StatusOk) unary call action simplifyUnary timeout meta clientError nonStatusOkError f x = do