@@ -23,6 +23,7 @@ module Servant.Client.Core.HasClient (
23
23
(/:) ,
24
24
foldMapUnion ,
25
25
matchUnion ,
26
+ ToDeepQuery (.. )
26
27
) where
27
28
28
29
import Prelude ()
@@ -46,6 +47,7 @@ import Data.List
46
47
import Data.Sequence
47
48
(fromList )
48
49
import qualified Data.Text as T
50
+ import Data.Text.Encoding (encodeUtf8 )
49
51
import Network.HTTP.Media
50
52
(MediaType , matches , parseAccept )
51
53
import qualified Network.HTTP.Media as Media
@@ -70,17 +72,17 @@ import Network.HTTP.Types
70
72
(Status )
71
73
import qualified Network.HTTP.Types as H
72
74
import Servant.API
73
- ((:<|>) ((:<|>) ), (:>) , AuthProtect , BasicAuth , BasicAuthData ,
74
- BuildHeadersTo (.. ), Capture' , CaptureAll , Description ,
75
- EmptyAPI , Fragment , FramingRender ( .. ), FramingUnrender ( .. ),
76
- FromSourceIO (.. ), Header' , Headers ( .. ), HttpVersion ,
77
- IsSecure , MimeRender ( mimeRender ),
78
- MimeUnrender (mimeUnrender ), NoContent ( NoContent ),
79
- NoContentVerb , QueryFlag , QueryParam' , QueryParams , Raw , RawM ,
80
- ReflectMethod (.. ), RemoteHost , ReqBody' , SBoolI , Stream ,
81
- StreamBody' , Summary , ToHttpApiData , ToSourceIO ( .. ), Vault ,
82
- Verb , WithNamedContext , WithResource , WithStatus ( .. ), contentType , getHeadersHList ,
83
- getResponse , toEncodedUrlPiece , toUrlPiece , NamedRoutes )
75
+ ((:<|>) ((:<|>) ), (:>) ,
76
+ BuildHeadersTo (.. ),
77
+ EmptyAPI ,
78
+ FromSourceIO (.. ),
79
+ IsSecure ,
80
+ MimeUnrender (mimeUnrender ),
81
+ NoContentVerb ,
82
+ ReflectMethod (.. ),
83
+ StreamBody' ,
84
+ Verb ,
85
+ getResponse , AuthProtect , BasicAuth , BasicAuthData , Capture' , CaptureAll , DeepQuery , Description , Fragment , FramingRender ( .. ), FramingUnrender ( .. ), Header' , Headers ( .. ), HttpVersion , MimeRender ( mimeRender ), NoContent ( NoContent ), QueryFlag , QueryParam' , QueryParams , QueryString , Raw , RawM , RemoteHost , ReqBody' , SBoolI , Stream , Summary , ToHttpApiData , ToSourceIO ( .. ), Vault , WithNamedContext , WithResource , WithStatus ( .. ), contentType , getHeadersHList , toEncodedUrlPiece , toUrlPiece , NamedRoutes )
84
86
import Servant.API.Generic
85
87
(GenericMode (.. ), ToServant , ToServantApi
86
88
, GenericServant , toServant , fromServant )
@@ -664,6 +666,44 @@ instance (KnownSymbol sym, HasClient m api)
664
666
hoistClientMonad pm _ f cl = \ b ->
665
667
hoistClientMonad pm (Proxy :: Proxy api ) f (cl b)
666
668
669
+ instance (HasClient m api )
670
+ => HasClient m (QueryString :> api ) where
671
+ type Client m (QueryString :> api ) =
672
+ H. Query -> Client m api
673
+
674
+ clientWithRoute pm Proxy req query =
675
+ clientWithRoute pm (Proxy :: Proxy api )
676
+ (setQueryString query req)
677
+
678
+ hoistClientMonad pm _ f cl = \ b ->
679
+ hoistClientMonad pm (Proxy :: Proxy api ) f (cl b)
680
+
681
+ class ToDeepQuery a where
682
+ toDeepQuery :: a -> [([T. Text ], Maybe T. Text )]
683
+
684
+ generateDeepParam :: T. Text -> ([T. Text ], Maybe T. Text ) -> (T. Text , Maybe T. Text )
685
+ generateDeepParam name (keys, value) =
686
+ let makeKeySegment key = " [" <> key <> " ]"
687
+ in (name <> foldMap makeKeySegment keys, value)
688
+
689
+ instance (KnownSymbol sym , ToDeepQuery a , HasClient m api )
690
+ => HasClient m (DeepQuery sym a :> api ) where
691
+ type Client m (DeepQuery sym a :> api ) =
692
+ a -> Client m api
693
+
694
+ clientWithRoute pm Proxy req deepObject =
695
+ let params = toDeepQuery deepObject
696
+ withParams = foldl' addDeepParam req params
697
+ addDeepParam r' kv =
698
+ let (k, textV) = generateDeepParam paramname kv
699
+ in appendToQueryString k (encodeUtf8 <$> textV) r'
700
+ paramname = pack $ symbolVal (Proxy :: Proxy sym )
701
+ in clientWithRoute pm (Proxy :: Proxy api )
702
+ withParams
703
+
704
+ hoistClientMonad pm _ f cl = \ b ->
705
+ hoistClientMonad pm (Proxy :: Proxy api ) f (cl b)
706
+
667
707
-- | Pick a 'Method' and specify where the server you want to query is. You get
668
708
-- back the full `Response`.
669
709
instance RunClient m => HasClient m Raw where
0 commit comments