{-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedLists #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -fno-warn-missing-signatures #-} {-# OPTIONS_GHC -fno-warn-unused-binds #-} import Control.Monad import Data.Function (fix) import qualified Data.Text as T import Data.Word import GHC.Generics (Generic) import Network.GRPC.HighLevel.Server import qualified Network.GRPC.HighLevel.Server.Unregistered as U import Network.GRPC.LowLevel import Proto3.Suite.Class serverMeta :: MetadataMap serverMeta = [("test_meta", "test_meta_value")] data SSRqt = SSRqt { ssName :: T.Text, ssNumReplies :: Word32 } deriving (Show, Eq, Ord, Generic) instance Message SSRqt data SSRpy = SSRpy { ssGreeting :: T.Text } deriving (Show, Eq, Ord, Generic) instance Message SSRpy data CSRqt = CSRqt { csMessage :: T.Text } deriving (Show, Eq, Ord, Generic) instance Message CSRqt data CSRpy = CSRpy { csNumRequests :: Word32 } deriving (Show, Eq, Ord, Generic) instance Message CSRpy data BiRqtRpy = BiRqtRpy { biMessage :: T.Text } deriving (Show, Eq, Ord, Generic) instance Message BiRqtRpy expect :: (Eq a, MonadFail m, Show a) => String -> a -> a -> m () expect ctx ex got | ex /= got = fail $ ctx ++ " error: expected " ++ show ex ++ ", got " ++ show got | otherwise = return () helloSS :: Handler 'ServerStreaming helloSS = ServerStreamHandler "/hellos.Hellos/HelloSS" $ \sc send -> do let SSRqt{..} = payload sc replicateM_ (fromIntegral ssNumReplies) $ do eea <- send $ SSRpy $ "Hello there, " <> ssName <> "!" case eea of Left e -> fail $ "helloSS error: " ++ show e Right{} -> return () return (serverMeta, StatusOk, StatusDetails "helloSS response details") helloCS :: Handler 'ClientStreaming helloCS = ClientStreamHandler "/hellos.Hellos/HelloCS" $ \_ recv -> flip fix 0 $ \go n -> recv >>= \case Left e -> fail $ "helloCS error: " ++ show e Right Nothing -> return (Just (CSRpy n), mempty, StatusOk, StatusDetails "helloCS details") Right (Just rqt) -> do expect "helloCS" "client streaming payload" (csMessage rqt) go (n+1) helloBi :: Handler 'BiDiStreaming helloBi = BiDiStreamHandler "/hellos.Hellos/HelloBi" $ \_ recv send -> fix $ \go -> recv >>= \case Left e -> fail $ "helloBi recv error: " ++ show e Right Nothing -> return (mempty, StatusOk, StatusDetails "helloBi details") Right (Just rqt) -> do expect "helloBi" "bidi payload" (biMessage rqt) send rqt >>= \case Left e -> fail $ "helloBi send error: " ++ show e _ -> go highlevelMainUnregistered :: IO () highlevelMainUnregistered = U.serverLoop defaultOptions{ optServerStreamHandlers = [helloSS] , optClientStreamHandlers = [helloCS] , optBiDiStreamHandlers = [helloBi] } main :: IO () main = highlevelMainUnregistered defConfig :: ServerConfig defConfig = ServerConfig "localhost" 50051 [] [] [] [] [] Nothing