{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

module Jordan.Servant.Client
  ( HasClient (..),
    JordanQuery',
    ReportingRequestBody,
  )
where

import Data.Proxy
import Jordan
import Jordan.Servant
import Jordan.Servant.Client.Query
import Network.HTTP.Media
import Servant.API
import Servant.API.Modifiers
import Servant.Client.Core

-- | Note: This instance assumes that the 'Jordan.FromJSON' and 'Jordan.ToJSON' instances match.
-- This should be true for all types, ideally.
instance forall a m api. (ToJSON a, HasClient m api) => HasClient m (ReportingRequestBody a :> api) where
  type Client m (ReportingRequestBody a :> api) = a -> Client m api
  clientWithRoute :: Proxy m
-> Proxy (ReportingRequestBody a :> api)
-> Request
-> Client m (ReportingRequestBody a :> api)
clientWithRoute Proxy m
pm Proxy (ReportingRequestBody a :> api)
Proxy Request
req a
body =
    Proxy m -> Proxy api -> Request -> Client m api
forall (m :: * -> *) api.
HasClient m api =>
Proxy m -> Proxy api -> Request -> Client m api
clientWithRoute Proxy m
pm (Proxy api
forall k (t :: k). Proxy t
Proxy :: Proxy api) (Request -> Client m api) -> Request -> Client m api
forall a b. (a -> b) -> a -> b
$ ByteString -> MediaType -> Request -> Request
setRequestBodyLBS (a -> ByteString
forall a. ToJSON a => a -> ByteString
toJSONViaBuilder a
body) (ByteString
"application" ByteString -> ByteString -> MediaType
// ByteString
"json") Request
req
  hoistClientMonad :: Proxy m
-> Proxy (ReportingRequestBody a :> api)
-> (forall x. mon x -> mon' x)
-> Client mon (ReportingRequestBody a :> api)
-> Client mon' (ReportingRequestBody a :> api)
hoistClientMonad Proxy m
pm Proxy (ReportingRequestBody a :> api)
Proxy forall x. mon x -> mon' x
f Client mon (ReportingRequestBody a :> api)
cl = Proxy m
-> Proxy api
-> (forall x. mon x -> mon' x)
-> Client mon api
-> Client mon' api
forall (m :: * -> *) api (mon :: * -> *) (mon' :: * -> *).
HasClient m api =>
Proxy m
-> Proxy api
-> (forall x. mon x -> mon' x)
-> Client mon api
-> Client mon' api
hoistClientMonad Proxy m
pm (Proxy api
forall k (t :: k). Proxy t
Proxy @api) forall x. mon x -> mon' x
f (Client mon api -> Client mon' api)
-> (a -> Client mon api) -> a -> Client mon' api
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Client mon (ReportingRequestBody a :> api)
a -> Client mon api
cl