{-# LANGUAGE UndecidableInstances #-}
module Tendermint.Utils.QueryClient.Class where

import           Control.Lens                           ((^.))
import           Control.Monad.Reader                   (ReaderT)
import qualified Data.ByteArray.Base64String            as Base64
import qualified Data.ByteArray.HexString               as Hex
import           Data.ByteString                        (ByteString)
import           Data.Kind                              (Type)
import           Data.Proxy
import           Data.String.Conversions                (cs)
import           Data.Text                              (Text, intercalate)
import           Data.Word                              (Word64)
import           GHC.TypeLits                           (KnownSymbol, symbolVal)
import           Network.ABCI.Types.Messages.FieldTypes (WrappedVal (..))
import qualified Network.ABCI.Types.Messages.Request    as Req
import qualified Network.ABCI.Types.Messages.Response   as Resp
import qualified Network.Tendermint.Client              as RPC
import           Servant.API
import           Servant.API.Modifiers
import           Tendermint.SDK.BaseApp.Errors          (queryAppError)
import           Tendermint.SDK.BaseApp.Query.Store     (StoreLeaf)
import           Tendermint.SDK.BaseApp.Query.Types     (EmptyQueryServer, Leaf,
                                                         QA, QueryArgs (..),
                                                         QueryData (..),
                                                         QueryResult (..))
import qualified Tendermint.SDK.BaseApp.Store.Array     as A
import qualified Tendermint.SDK.BaseApp.Store.Map       as M
import qualified Tendermint.SDK.BaseApp.Store.Var       as V
import           Tendermint.SDK.Codec                   (HasCodec (decode))
import           Tendermint.Utils.QueryClient.Types

class Monad m => RunQueryClient m where
    -- | How to make a request.
    runQuery :: Req.Query -> m Resp.Query

instance RunQueryClient (ReaderT RPC.Config IO) where
  runQuery :: Query -> ReaderT Config IO Query
runQuery Req.Query{..} =
    let rpcQ :: RequestABCIQuery
rpcQ = RequestABCIQuery :: Maybe Text
-> HexString
-> Maybe (WrappedVal Int64)
-> Bool
-> RequestABCIQuery
RPC.RequestABCIQuery
          { requestABCIQueryPath :: Maybe Text
RPC.requestABCIQueryPath = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
queryPath
          , requestABCIQueryData :: HexString
RPC.requestABCIQueryData = ByteArrayAccess ByteString => ByteString -> HexString
forall ba. ByteArrayAccess ba => ba -> HexString
Hex.fromBytes @ByteString (ByteString -> HexString)
-> (Base64String -> ByteString) -> Base64String -> HexString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base64String -> ByteString
forall ba. ByteArray ba => Base64String -> ba
Base64.toBytes (Base64String -> HexString) -> Base64String -> HexString
forall a b. (a -> b) -> a -> b
$ Base64String
queryData
          , requestABCIQueryHeight :: Maybe (WrappedVal Int64)
RPC.requestABCIQueryHeight = WrappedVal Int64 -> Maybe (WrappedVal Int64)
forall a. a -> Maybe a
Just (WrappedVal Int64 -> Maybe (WrappedVal Int64))
-> WrappedVal Int64 -> Maybe (WrappedVal Int64)
forall a b. (a -> b) -> a -> b
$ WrappedVal Int64
queryHeight
          , requestABCIQueryProve :: Bool
RPC.requestABCIQueryProve  = Bool
queryProve
          }
    in ResultABCIQuery -> Query
RPC.resultABCIQueryResponse (ResultABCIQuery -> Query)
-> ReaderT Config IO ResultABCIQuery -> ReaderT Config IO Query
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RequestABCIQuery -> ReaderT Config IO ResultABCIQuery
RPC.abciQuery RequestABCIQuery
rpcQ

type QueryStringList = [(Text, Text)]

class HasQueryClient m layout where

    type ClientQ (m :: Type -> Type) layout :: Type
    genClientQ :: Proxy m -> Proxy layout -> (Req.Query, QueryStringList) -> ClientQ m layout

instance (HasQueryClient m a, HasQueryClient m b) => HasQueryClient m (a :<|> b) where
    type ClientQ m (a :<|> b) = ClientQ m a :<|> ClientQ m b
    genClientQ :: Proxy m
-> Proxy (a :<|> b)
-> (Query, QueryStringList)
-> ClientQ m (a :<|> b)
genClientQ pm :: Proxy m
pm _ (q :: Query
q,qs :: QueryStringList
qs) = Proxy m -> Proxy a -> (Query, QueryStringList) -> ClientQ m a
forall (m :: * -> *) layout.
HasQueryClient m layout =>
Proxy m
-> Proxy layout -> (Query, QueryStringList) -> ClientQ m layout
genClientQ Proxy m
pm (Proxy a
forall k (t :: k). Proxy t
Proxy @a) (Query
q,QueryStringList
qs) ClientQ m a -> ClientQ m b -> ClientQ m a :<|> ClientQ m b
forall a b. a -> b -> a :<|> b
:<|> Proxy m -> Proxy b -> (Query, QueryStringList) -> ClientQ m b
forall (m :: * -> *) layout.
HasQueryClient m layout =>
Proxy m
-> Proxy layout -> (Query, QueryStringList) -> ClientQ m layout
genClientQ Proxy m
pm (Proxy b
forall k (t :: k). Proxy t
Proxy @b) (Query
q,QueryStringList
qs)

instance (KnownSymbol path, HasQueryClient m a) => HasQueryClient m (path :> a) where
    type ClientQ m (path :> a) = ClientQ m a
    genClientQ :: Proxy m
-> Proxy (path :> a)
-> (Query, QueryStringList)
-> ClientQ m (path :> a)
genClientQ pm :: Proxy m
pm _ (q :: Query
q,qs :: QueryStringList
qs) = Proxy m -> Proxy a -> (Query, QueryStringList) -> ClientQ m a
forall (m :: * -> *) layout.
HasQueryClient m layout =>
Proxy m
-> Proxy layout -> (Query, QueryStringList) -> ClientQ m layout
genClientQ Proxy m
pm (Proxy a
forall k (t :: k). Proxy t
Proxy @a)
      (Query
q {queryPath :: Text
Req.queryPath = Query -> Text
Req.queryPath Query
q Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (Proxy path -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (Proxy path
forall k (t :: k). Proxy t
Proxy @path))}, QueryStringList
qs)

appendToQueryString
  :: Text       -- ^ param name
  -> Maybe Text -- ^ param value
  -> QueryStringList
  -> QueryStringList
appendToQueryString :: Text -> Maybe Text -> QueryStringList -> QueryStringList
appendToQueryString pname :: Text
pname pvalue :: Maybe Text
pvalue qs :: QueryStringList
qs =
  QueryStringList
-> (Text -> QueryStringList) -> Maybe Text -> QueryStringList
forall b a. b -> (a -> b) -> Maybe a -> b
maybe QueryStringList
qs (\v :: Text
v -> (Text
pname, Text
v) (Text, Text) -> QueryStringList -> QueryStringList
forall a. a -> [a] -> [a]
: QueryStringList
qs) Maybe Text
pvalue

instance (KnownSymbol sym, ToHttpApiData a, HasQueryClient m api, SBoolI (FoldRequired mods))
      => HasQueryClient m (QueryParam' mods sym a :> api) where

  type ClientQ m (QueryParam' mods sym a :> api) = RequiredArgument mods a -> ClientQ m api

  -- if mparam = Nothing, we don't add it to the query string
  genClientQ :: Proxy m
-> Proxy (QueryParam' mods sym a :> api)
-> (Query, QueryStringList)
-> ClientQ m (QueryParam' mods sym a :> api)
genClientQ pm :: Proxy m
pm Proxy (q :: Query
q,qs :: QueryStringList
qs) mparam :: If (FoldRequired mods) a (Maybe a)
mparam =
    Proxy m -> Proxy api -> (Query, QueryStringList) -> ClientQ m api
forall (m :: * -> *) layout.
HasQueryClient m layout =>
Proxy m
-> Proxy layout -> (Query, QueryStringList) -> ClientQ m layout
genClientQ Proxy m
pm (Proxy api
forall k (t :: k). Proxy t
Proxy :: Proxy api) ((Query, QueryStringList) -> ClientQ m api)
-> (Query, QueryStringList) -> ClientQ m api
forall a b. (a -> b) -> a -> b
$ Proxy mods
-> (a -> (Query, QueryStringList))
-> (Maybe a -> (Query, QueryStringList))
-> If (FoldRequired mods) a (Maybe a)
-> (Query, QueryStringList)
forall (mods :: [*]) a r.
SBoolI (FoldRequired mods) =>
Proxy mods
-> (a -> r) -> (Maybe a -> r) -> RequiredArgument mods a -> r
foldRequiredArgument
      (Proxy mods
forall k (t :: k). Proxy t
Proxy :: Proxy mods) a -> (Query, QueryStringList)
add ((Query, QueryStringList)
-> (a -> (Query, QueryStringList))
-> Maybe a
-> (Query, QueryStringList)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Query
q,QueryStringList
qs) a -> (Query, QueryStringList)
add) If (FoldRequired mods) a (Maybe a)
mparam
    where
      add :: a -> (Req.Query, QueryStringList)
      add :: a -> (Query, QueryStringList)
add param :: a
param = (Query
q, Text -> Maybe Text -> QueryStringList -> QueryStringList
appendToQueryString Text
pname (Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ a -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam a
param) QueryStringList
qs)

      pname :: Text
      pname :: Text
pname  = String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Proxy sym -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (Proxy sym
forall k (t :: k). Proxy t
Proxy :: Proxy sym)

instance (QueryData k, HasQueryClient m a) => HasQueryClient m (QA k :> a) where
    type ClientQ m (QA k :> a) = QueryArgs k -> ClientQ m a
    genClientQ :: Proxy m
-> Proxy (QA k :> a)
-> (Query, QueryStringList)
-> ClientQ m (QA k :> a)
genClientQ pm :: Proxy m
pm _ (q :: Query
q,qs :: QueryStringList
qs) QueryArgs{..} = Proxy m -> Proxy a -> (Query, QueryStringList) -> ClientQ m a
forall (m :: * -> *) layout.
HasQueryClient m layout =>
Proxy m
-> Proxy layout -> (Query, QueryStringList) -> ClientQ m layout
genClientQ Proxy m
pm (Proxy a
forall k (t :: k). Proxy t
Proxy @a)
      (Query
q { queryData :: Base64String
Req.queryData = k -> Base64String
forall a. QueryData a => a -> Base64String
toQueryData k
queryArgsData
         , queryHeight :: WrappedVal Int64
Req.queryHeight = Int64 -> WrappedVal Int64
forall a. a -> WrappedVal a
WrappedVal Int64
queryArgsHeight
         , queryProve :: Bool
Req.queryProve = Bool
queryArgsProve
         }, QueryStringList
qs)

instance (ToHttpApiData a, HasQueryClient m api) => HasQueryClient m (Capture' mods capture a :> api) where

  type ClientQ m (Capture' mods capture a :> api) = a -> ClientQ m api

  genClientQ :: Proxy m
-> Proxy (Capture' mods capture a :> api)
-> (Query, QueryStringList)
-> ClientQ m (Capture' mods capture a :> api)
genClientQ pm :: Proxy m
pm _ (q :: Query
q,qs :: QueryStringList
qs) val :: a
val =
    let p :: Text
p = a -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece a
val
        q' :: Query
q' = Query
q { queryPath :: Text
Req.queryPath = Query -> Text
Req.queryPath Query
q Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
p }
    in Proxy m -> Proxy api -> (Query, QueryStringList) -> ClientQ m api
forall (m :: * -> *) layout.
HasQueryClient m layout =>
Proxy m
-> Proxy layout -> (Query, QueryStringList) -> ClientQ m layout
genClientQ Proxy m
pm (Proxy api
forall k (t :: k). Proxy t
Proxy :: Proxy api) (Query
q', QueryStringList
qs)

addQueryParamsToPath
  :: QueryStringList
  -> Text
  -> Text
addQueryParamsToPath :: QueryStringList -> Text -> Text
addQueryParamsToPath qs :: QueryStringList
qs path :: Text
path =
  let qParams :: Text
qParams = Text -> [Text] -> Text
intercalate "&" ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ ((Text, Text) -> Text) -> QueryStringList -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (\(n :: Text
n,v :: Text
v) -> Text
n Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
v) QueryStringList
qs
  in case QueryStringList
qs of
       [] -> Text
path
       _  -> Text
path Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "?" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
qParams

instance (HasCodec a, RunQueryClient m) => HasQueryClient m (Leaf a) where
    type ClientQ m (Leaf a) = m (QueryClientResponse a)
    genClientQ :: Proxy m
-> Proxy (Leaf a) -> (Query, QueryStringList) -> ClientQ m (Leaf a)
genClientQ _ _ = (Query, QueryStringList) -> ClientQ m (Leaf a)
forall a (m :: * -> *).
(HasCodec a, RunQueryClient m) =>
(Query, QueryStringList) -> m (QueryClientResponse a)
leafGenClient

leafGenClient
  :: HasCodec a
  => RunQueryClient m
  => (Req.Query, QueryStringList)
  -> m (QueryClientResponse a)
leafGenClient :: (Query, QueryStringList) -> m (QueryClientResponse a)
leafGenClient (q :: Query
q,qs :: QueryStringList
qs) = do
  let reqPath :: Text
reqPath = QueryStringList -> Text -> Text
addQueryParamsToPath QueryStringList
qs (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Query -> Text
Req.queryPath Query
q
  r :: Query
r@Resp.Query{..} <- Query -> m Query
forall (m :: * -> *). RunQueryClient m => Query -> m Query
runQuery Query
q { queryPath :: Text
Req.queryPath = Text
reqPath }
  -- anything other than 0 code is a failure: https://tendermint.readthedocs.io/en/latest/abci-spec.html
  -- and will result in queryValue decoding to a "empty/default" object
  QueryClientResponse a -> m (QueryClientResponse a)
forall (m :: * -> *) a. Monad m => a -> m a
return (QueryClientResponse a -> m (QueryClientResponse a))
-> QueryClientResponse a -> m (QueryClientResponse a)
forall a b. (a -> b) -> a -> b
$ case Word32
queryCode of
    0 -> case ByteString -> Either Text a
forall a. HasCodec a => ByteString -> Either Text a
decode (ByteString -> Either Text a) -> ByteString -> Either Text a
forall a b. (a -> b) -> a -> b
$ Base64String -> ByteString
forall ba. ByteArray ba => Base64String -> ba
Base64.toBytes Base64String
queryValue of
           Left err :: Text
err -> String -> QueryClientResponse a
forall a. HasCallStack => String -> a
error (String -> QueryClientResponse a)
-> String -> QueryClientResponse a
forall a b. (a -> b) -> a -> b
$ "Impossible parse error: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
forall a b. ConvertibleStrings a b => a -> b
cs Text
err
           Right a :: a
a  -> QueryResult a -> QueryClientResponse a
forall a. QueryResult a -> QueryClientResponse a
QueryResponse (QueryResult a -> QueryClientResponse a)
-> QueryResult a -> QueryClientResponse a
forall a b. (a -> b) -> a -> b
$ QueryResult :: forall a.
a -> Int64 -> Base64String -> Maybe Proof -> Int64 -> QueryResult a
QueryResult
             { queryResultData :: a
queryResultData = a
a
             , queryResultIndex :: Int64
queryResultIndex = WrappedVal Int64 -> Int64
forall a. WrappedVal a -> a
unWrappedVal WrappedVal Int64
queryIndex
             , queryResultHeight :: Int64
queryResultHeight =  WrappedVal Int64 -> Int64
forall a. WrappedVal a -> a
unWrappedVal WrappedVal Int64
queryHeight
             , queryResultProof :: Maybe Proof
queryResultProof = Maybe Proof
queryProof
             , queryResultKey :: Base64String
queryResultKey = Base64String
queryKey
             }
    _ -> AppError -> QueryClientResponse a
forall a. AppError -> QueryClientResponse a
QueryError (AppError -> QueryClientResponse a)
-> AppError -> QueryClientResponse a
forall a b. (a -> b) -> a -> b
$ Query
r Query -> Getting AppError Query AppError -> AppError
forall s a. s -> Getting a s a -> a
^. Getting AppError Query AppError
Lens' Query AppError
queryAppError

instance (HasCodec a, RunQueryClient m) => HasQueryClient m (StoreLeaf (V.Var a)) where
    type ClientQ m (StoreLeaf (V.Var a)) = ClientQ m (QA () :> Leaf a)
    genClientQ :: Proxy m
-> Proxy (StoreLeaf (Var a))
-> (Query, QueryStringList)
-> ClientQ m (StoreLeaf (Var a))
genClientQ pm :: Proxy m
pm _ = Proxy m
-> Proxy (QA () :> Leaf a)
-> (Query, QueryStringList)
-> ClientQ m (QA () :> Leaf a)
forall (m :: * -> *) layout.
HasQueryClient m layout =>
Proxy m
-> Proxy layout -> (Query, QueryStringList) -> ClientQ m layout
genClientQ Proxy m
pm (Proxy (QA () :> Leaf a)
forall k (t :: k). Proxy t
Proxy @(QA () :> Leaf a))

instance (HasCodec a, RunQueryClient m) => HasQueryClient m (StoreLeaf (A.Array a)) where
    type ClientQ m (StoreLeaf (A.Array a)) = ClientQ m (QA Word64 :> Leaf a)
    genClientQ :: Proxy m
-> Proxy (StoreLeaf (Array a))
-> (Query, QueryStringList)
-> ClientQ m (StoreLeaf (Array a))
genClientQ pm :: Proxy m
pm _ = Proxy m
-> Proxy (QA Word64 :> Leaf a)
-> (Query, QueryStringList)
-> ClientQ m (QA Word64 :> Leaf a)
forall (m :: * -> *) layout.
HasQueryClient m layout =>
Proxy m
-> Proxy layout -> (Query, QueryStringList) -> ClientQ m layout
genClientQ Proxy m
pm (Proxy (QA Word64 :> Leaf a)
forall k (t :: k). Proxy t
Proxy @(QA Word64 :> Leaf a))

instance (QueryData k, HasCodec v, RunQueryClient m) => HasQueryClient m (StoreLeaf (M.Map k v)) where
    type ClientQ m (StoreLeaf (M.Map k v)) = ClientQ m (QA k :> Leaf v)
    genClientQ :: Proxy m
-> Proxy (StoreLeaf (Map k v))
-> (Query, QueryStringList)
-> ClientQ m (StoreLeaf (Map k v))
genClientQ pm :: Proxy m
pm _ = Proxy m
-> Proxy (QA k :> Leaf v)
-> (Query, QueryStringList)
-> ClientQ m (QA k :> Leaf v)
forall (m :: * -> *) layout.
HasQueryClient m layout =>
Proxy m
-> Proxy layout -> (Query, QueryStringList) -> ClientQ m layout
genClientQ Proxy m
pm (Proxy (QA k :> Leaf v)
forall k (t :: k). Proxy t
Proxy @(QA k :> Leaf v))

-- | Singleton type representing a client for an empty API.
data EmptyQueryClient = EmptyQueryClient deriving (EmptyQueryClient -> EmptyQueryClient -> Bool
(EmptyQueryClient -> EmptyQueryClient -> Bool)
-> (EmptyQueryClient -> EmptyQueryClient -> Bool)
-> Eq EmptyQueryClient
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EmptyQueryClient -> EmptyQueryClient -> Bool
$c/= :: EmptyQueryClient -> EmptyQueryClient -> Bool
== :: EmptyQueryClient -> EmptyQueryClient -> Bool
$c== :: EmptyQueryClient -> EmptyQueryClient -> Bool
Eq, Int -> EmptyQueryClient -> String -> String
[EmptyQueryClient] -> String -> String
EmptyQueryClient -> String
(Int -> EmptyQueryClient -> String -> String)
-> (EmptyQueryClient -> String)
-> ([EmptyQueryClient] -> String -> String)
-> Show EmptyQueryClient
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [EmptyQueryClient] -> String -> String
$cshowList :: [EmptyQueryClient] -> String -> String
show :: EmptyQueryClient -> String
$cshow :: EmptyQueryClient -> String
showsPrec :: Int -> EmptyQueryClient -> String -> String
$cshowsPrec :: Int -> EmptyQueryClient -> String -> String
Show, EmptyQueryClient
EmptyQueryClient -> EmptyQueryClient -> Bounded EmptyQueryClient
forall a. a -> a -> Bounded a
maxBound :: EmptyQueryClient
$cmaxBound :: EmptyQueryClient
minBound :: EmptyQueryClient
$cminBound :: EmptyQueryClient
Bounded, Int -> EmptyQueryClient
EmptyQueryClient -> Int
EmptyQueryClient -> [EmptyQueryClient]
EmptyQueryClient -> EmptyQueryClient
EmptyQueryClient -> EmptyQueryClient -> [EmptyQueryClient]
EmptyQueryClient
-> EmptyQueryClient -> EmptyQueryClient -> [EmptyQueryClient]
(EmptyQueryClient -> EmptyQueryClient)
-> (EmptyQueryClient -> EmptyQueryClient)
-> (Int -> EmptyQueryClient)
-> (EmptyQueryClient -> Int)
-> (EmptyQueryClient -> [EmptyQueryClient])
-> (EmptyQueryClient -> EmptyQueryClient -> [EmptyQueryClient])
-> (EmptyQueryClient -> EmptyQueryClient -> [EmptyQueryClient])
-> (EmptyQueryClient
    -> EmptyQueryClient -> EmptyQueryClient -> [EmptyQueryClient])
-> Enum EmptyQueryClient
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: EmptyQueryClient
-> EmptyQueryClient -> EmptyQueryClient -> [EmptyQueryClient]
$cenumFromThenTo :: EmptyQueryClient
-> EmptyQueryClient -> EmptyQueryClient -> [EmptyQueryClient]
enumFromTo :: EmptyQueryClient -> EmptyQueryClient -> [EmptyQueryClient]
$cenumFromTo :: EmptyQueryClient -> EmptyQueryClient -> [EmptyQueryClient]
enumFromThen :: EmptyQueryClient -> EmptyQueryClient -> [EmptyQueryClient]
$cenumFromThen :: EmptyQueryClient -> EmptyQueryClient -> [EmptyQueryClient]
enumFrom :: EmptyQueryClient -> [EmptyQueryClient]
$cenumFrom :: EmptyQueryClient -> [EmptyQueryClient]
fromEnum :: EmptyQueryClient -> Int
$cfromEnum :: EmptyQueryClient -> Int
toEnum :: Int -> EmptyQueryClient
$ctoEnum :: Int -> EmptyQueryClient
pred :: EmptyQueryClient -> EmptyQueryClient
$cpred :: EmptyQueryClient -> EmptyQueryClient
succ :: EmptyQueryClient -> EmptyQueryClient
$csucc :: EmptyQueryClient -> EmptyQueryClient
Enum)

instance HasQueryClient m EmptyQueryServer where
  type ClientQ m EmptyQueryServer = EmptyQueryClient

  genClientQ :: Proxy m
-> Proxy EmptyQueryServer
-> (Query, QueryStringList)
-> ClientQ m EmptyQueryServer
genClientQ _ _ _ = EmptyQueryClient
ClientQ m EmptyQueryServer
EmptyQueryClient