inferno-vc-0.1.0: src/Inferno/VersionControl/Client.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Inferno.VersionControl.Client where
import Codec.Compression.GZip (compress)
import Data.Aeson (FromJSON, ToJSON)
import qualified Data.ByteString.Lazy as BSL
import Data.Proxy (Proxy (..))
import Inferno.VersionControl.Server (VCServerError, VersionControlAPI)
import Network.HTTP.Client (Request (..), RequestBody (..))
import Network.HTTP.Client.Internal (Manager (..))
import Network.HTTP.Types.Header (hContentEncoding)
import Servant.Client (BaseUrl, Client, ClientEnv, ClientM, client, mkClientEnv)
import Servant.Typed.Error (TypedClientM)
mkVCClientEnv :: Manager -> BaseUrl -> ClientEnv
mkVCClientEnv man@Manager {mModifyRequest = modReq} baseUrl =
mkClientEnv man {mModifyRequest = modReq'} baseUrl
where
modReq' :: Request -> IO Request
modReq' r = do
x <- modReq r
pure $
if ((hContentEncoding, "gzip") `elem` requestHeaders x)
then x
else
let new_hdrs = (hContentEncoding, "gzip") : requestHeaders x
(hrds, body) = case requestBody x of
RequestBodyBuilder _ _ -> (requestHeaders x, requestBody x)
RequestBodyStream _ _ -> (requestHeaders x, requestBody x)
RequestBodyStreamChunked _ -> (requestHeaders x, requestBody x)
b -> (new_hdrs, compressBody b)
in x {requestHeaders = hrds, requestBody = body}
compressBody :: RequestBody -> RequestBody
compressBody = \case
RequestBodyLBS bsl -> RequestBodyLBS $ compress bsl
RequestBodyBS bs -> RequestBodyLBS $ compress $ BSL.fromStrict bs
RequestBodyIO iob -> RequestBodyIO $ compressBody <$> iob
b -> b
api :: Proxy (VersionControlAPI a g)
api = Proxy
infernoVcClient :: (FromJSON a, FromJSON g, ToJSON a, ToJSON g) => Client ClientM (VersionControlAPI a g)
infernoVcClient = client api
-- TODO Generate this block below using TH given a and g:
type ClientMWithVCStoreError a = TypedClientM VCServerError a
-- fetchFunction :: forall a g. VCObjectHash -> ClientMWithVCStoreError (VCMeta a g (Expr (Pinned VCObjectHash) (), TCScheme))
-- fetchFunctionsForGroups :: forall a g. Set g -> ClientMWithVCStoreError [VCMeta a g VCObjectHash]
-- fetchVCObject :: forall a g. VCObjectHash -> ClientMWithVCStoreError (VCMeta a g VCObject)
-- fetchVCObjectHistory :: forall a g. VCObjectHash -> ClientMWithVCStoreError [VCMeta a g VCObjectHash]
-- fetchVCObjects :: forall a g. [VCObjectHash] -> ClientMWithVCStoreError (Map.Map VCObjectHash (VCMeta a g VCObject))
-- fetchVCObjectClosureHashes :: VCObjectHash -> ClientMWithVCStoreError [VCObjectHash]
-- pushFunction :: forall a g. VCMeta a g (Expr (Pinned VCObjectHash) (), TCScheme) -> ClientMWithVCStoreError VCObjectHash
-- deleteAutosavedFunction :: VCObjectHash -> ClientMWithVCStoreError ()
-- deleteVCObjects :: VCObjectHash -> ClientMWithVCStoreError ()
-- fetchFunction
-- :<|> fetchFunctionsForGroups
-- :<|> fetchVCObject
-- :<|> fetchVCObjectHistory
-- :<|> fetchVCObjects
-- :<|> fetchVCObjectClosureHashes
-- :<|> pushFunction
-- :<|> deleteAutosavedFunction
-- :<|> deleteVCObjects = typedClient $ client api