{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- | This module exports orphan instances to make -- [@servant-queryparam-core@](https://hackage.haskell.org/package/servant-queryparam-core) work with clients. module Servant.QueryParam.Client.Record () where import Data.Kind import Data.Proxy import GHC.Generics import GHC.TypeLits import Servant.API import Servant.Client.Core.HasClient import Servant.Client.Core.Request import Servant.Client.Core.RunClient import Servant.QueryParam.Record import Servant.QueryParam.TypeLevel instance ( RunClient m , Generic a , GHasClient mod m (Rep a) api ) => HasClient m (RecordParam mod a :> api) where type Client m (RecordParam mod a :> api) = a -> Client m api clientWithRoute pm Proxy req record = gClientWithRoute (Proxy :: Proxy mod) pm (Proxy :: Proxy api) req (from record :: Rep a ()) {-# INLINE clientWithRoute #-} hoistClientMonad pm Proxy f cl as = gHoistClientMonad (Proxy :: Proxy mod) pm (Proxy :: Proxy api) f (cl . to) (from as :: Rep a ()) {-# INLINE hoistClientMonad #-} data GParam (mod :: Symbol -> Exp Symbol) a class GHasClient (mod :: Symbol -> Exp Symbol) m (a :: Type -> Type) api where gClientWithRoute :: RunClient m => Proxy mod -> Proxy m -> Proxy api -> Request -> a () -> Client m api gHoistClientMonad :: RunClient m => Proxy mod -> Proxy m -> Proxy api -> (forall x. mon x -> mon' x) -> (a () -> Client mon api) -> (a () -> Client mon' api) instance ( RunClient m , GHasClient mod m a api ) => HasClient m (GParam mod (a ()) :> api) where type Client m (GParam mod (a ()) :> api) = a () -> Client m api clientWithRoute pm _ = gClientWithRoute (Proxy :: Proxy mod) pm (Proxy :: Proxy api) {-# INLINE clientWithRoute #-} hoistClientMonad pm _ = gHoistClientMonad (Proxy :: Proxy mod) pm (Proxy :: Proxy api) {-# INLINE hoistClientMonad #-} instance GHasClient mod m c api => GHasClient mod m (D1 m3 c) api where gClientWithRoute _ pm _ req (M1 x) = gClientWithRoute (Proxy :: Proxy mod) pm (Proxy :: Proxy api) req x {-# INLINE gClientWithRoute #-} gHoistClientMonad _ pm Proxy f cl x = gHoistClientMonad (Proxy :: Proxy mod) pm (Proxy :: Proxy api) f (cl . M1) (unM1 x) {-# INLINE gHoistClientMonad #-} instance GHasClient mod m a (GParam mod (b ()) :> api) => GHasClient mod m (a :*: b) api where gClientWithRoute _ pm _ req (x :*: y) = gClientWithRoute (Proxy :: Proxy mod) pm (Proxy :: Proxy (GParam mod (b ()) :> api)) req x y {-# INLINE gClientWithRoute #-} gHoistClientMonad _ pm Proxy f cl (x :*: y) = gHoistClientMonad (Proxy :: Proxy mod) pm (Proxy :: Proxy (GParam mod (b ()) :> api)) f (\x' y' -> cl (x' :*: y')) x y {-# INLINE gHoistClientMonad #-} instance GHasClient mod m a api => GHasClient mod m (C1 mon a) api where gClientWithRoute _ pm _ req (M1 x) = gClientWithRoute (Proxy :: Proxy mod) pm (Proxy :: Proxy api) req x {-# INLINE gClientWithRoute #-} gHoistClientMonad _ pm _ f cl (M1 x) = gHoistClientMonad (Proxy :: Proxy mod) pm (Proxy :: Proxy api) f (cl . M1) x {-# INLINE gHoistClientMonad #-} instance {-# OVERLAPPING #-} ( HasClient m api , KnownSymbol sym , KnownSymbol (Eval (mod sym)) ) => GHasClient mod m (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 Bool)) api where gClientWithRoute _ pm _ req (M1 (K1 x)) = clientWithRoute pm (Proxy :: Proxy (QueryFlag (Eval (mod sym)) :> api)) req x {-# INLINE gClientWithRoute #-} gHoistClientMonad _ pm _ f cl (M1 (K1 x)) = hoistClientMonad pm (Proxy :: Proxy (QueryFlag (Eval (mod sym)) :> api)) f (cl . M1 . K1) x {-# INLINE gHoistClientMonad #-} instance {-# OVERLAPPING #-} ( ToHttpApiData a , HasClient m api , KnownSymbol sym , KnownSymbol (Eval (mod sym)) ) => GHasClient mod m (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 [a])) api where gClientWithRoute _ pm _ req (M1 (K1 x)) = clientWithRoute pm (Proxy :: Proxy (QueryParams (Eval (mod sym)) a :> api)) req x {-# INLINE gClientWithRoute #-} gHoistClientMonad _ pm _ f cl (M1 (K1 x)) = hoistClientMonad pm (Proxy :: Proxy (QueryParams (Eval (mod sym)) a :> api)) f (cl . M1 . K1) x {-# INLINE gHoistClientMonad #-} instance {-# OVERLAPPING #-} ( ToHttpApiData a , HasClient m api , KnownSymbol sym , KnownSymbol (Eval (mod sym)) ) => GHasClient mod m (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 (Maybe a))) api where gClientWithRoute _ pm _ req (M1 (K1 x)) = clientWithRoute pm (Proxy :: Proxy (QueryParam' '[Optional, Strict] (Eval (mod sym)) a :> api)) req x {-# INLINE gClientWithRoute #-} gHoistClientMonad _ pm _ f cl (M1 (K1 x)) = hoistClientMonad pm (Proxy :: Proxy (QueryParam' '[Optional, Strict] (Eval (mod sym)) a :> api)) f (cl . M1 . K1) x {-# INLINE gHoistClientMonad #-} instance {-# OVERLAPPABLE #-} ( ToHttpApiData a , HasClient m api , KnownSymbol sym , KnownSymbol (Eval (mod sym)) ) => GHasClient mod m (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 a)) api where gClientWithRoute _ pm _ req (M1 (K1 x)) = clientWithRoute pm (Proxy :: Proxy (QueryParam' '[Required, Strict] (Eval (mod sym)) a :> api)) req x {-# INLINE gClientWithRoute #-} gHoistClientMonad _ pm _ f cl (M1 (K1 x)) = hoistClientMonad pm (Proxy :: Proxy (QueryParam' '[Required, Strict] (Eval (mod sym)) a :> api)) f (cl . M1 . K1) x {-# INLINE gHoistClientMonad #-}