@@ -1,69 +1,74 @@
1−{-# LANGUAGE AllowAmbiguousTypes #-}
1+{-# LANGUAGE AllowAmbiguousTypes #-}
2−{-# LANGUAGE CPP #-}
2+{-# LANGUAGE CPP #-}
3−{-# LANGUAGE DataKinds #-}
3+{-# LANGUAGE DataKinds #-}
4−{-# LANGUAGE FlexibleContexts #-}
4+{-# LANGUAGE FlexibleContexts #-}
5−{-# LANGUAGE FlexibleInstances #-}
5+{-# LANGUAGE FlexibleInstances #-}
6−{-# LANGUAGE InstanceSigs #-}
6+{-# LANGUAGE InstanceSigs #-}
7−{-# LANGUAGE OverloadedStrings #-}
8−{-# LANGUAGE PolyKinds #-}
9−{-# LANGUAGE ScopedTypeVariables #-}
10−{-# LANGUAGE TupleSections #-}
11−{-# LANGUAGE TypeFamilies #-}
12−{-# LANGUAGE TypeOperators #-}
13−{-# LANGUAGE UndecidableInstances #-}
14{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8+{-# LANGUAGE OverloadedStrings #-}
9+{-# LANGUAGE PolyKinds #-}
10+{-# LANGUAGE ScopedTypeVariables #-}
11+{-# LANGUAGE TupleSections #-}
12+{-# LANGUAGE TypeFamilies #-}
13+{-# LANGUAGE TypeOperators #-}
14+{-# LANGUAGE UndecidableInstances #-}
16+module Servant.Reflex.Multi (
17+ -- * Compute servant client functions
22+ -- * Build QueryParam arguments
26+ -- * Access response data
16−module Servant.Reflex.Multi
18 , HasClientMulti(..)
33 , HasClientMulti(..)
21------------------------------------------------------------------------------
36------------------------------------------------------------------------------
22−import Control.Applicative
37+import Control.Applicative (liftA2)
23−import Control.Arrow (second)
24−import Data.Functor.Compose
38+import Data.Functor.Compose (Compose (..), getCompose)
25−import Data.Monoid ((<>))
39+import Data.Proxy (Proxy (..))
26−import qualified Data.Set as Set
40+import qualified Data.Set as Set
41+import Data.Text (Text)
42+import qualified Data.Text as T
27−import qualified Data.Text.Encoding as E
43+import qualified Data.Text.Encoding as E
28−import Data.CaseInsensitive (mk)
29−import Data.Proxy (Proxy (..))
30−import qualified Data.Map as Map
31−import Data.Text (Text)
32−import qualified Data.Text as T
33−import GHC.TypeLits (KnownSymbol, symbolVal)
44+import GHC.TypeLits (KnownSymbol, symbolVal)
34−import Servant.API ((:<|>)(..),(:>), BasicAuth,
45+import Servant.API ((:<|>) (..), (:>), BasicAuth,
35− BasicAuthData, BuildHeadersTo(..),
46+ BasicAuthData, BuildHeadersTo (..),
36− Capture, contentType, Header,
47+ Capture, Header, Headers (..),
37− Headers(..), HttpVersion, IsSecure,
48+ HttpVersion, IsSecure, MimeRender (..),
38− MimeRender(..), MimeUnrender,
39− NoContent, QueryFlag, QueryParam,
49+ MimeUnrender, NoContent, QueryFlag,
40− QueryParams, Raw, ReflectMethod(..),
50+ QueryParam, QueryParams, Raw,
41− RemoteHost, ReqBody,
51+ ReflectMethod (..), RemoteHost,
42− ToHttpApiData(..), Vault, Verb)
52+ ReqBody, ToHttpApiData (..), Vault,
43−
53+ Verb, contentType)
44−import Reflex.Dom (Dynamic, Event, Reflex,
55+import Reflex.Dom (Dynamic, Event, Reflex,
45− XhrRequest(..),
56+ XhrRequest (..),
46− XhrResponseHeaders(..),
57+ XhrResponseHeaders (..),
47− XhrResponse(..), constDyn, ffor, fmapMaybe,
48− leftmost, performRequestAsync, attachPromptlyDynWith,
58+ attachPromptlyDynWith, constDyn)
50------------------------------------------------------------------------------
59------------------------------------------------------------------------------
51−import Servant.Common.BaseUrl (BaseUrl(..), Scheme(..), baseUrlWidget,
60+import Servant.Common.BaseUrl (BaseUrl (..), Scheme (..),
53− SupportsServantReflex)
61+ SupportsServantReflex)
54−import Servant.Common.Req (Req, ReqResult(..), QParam(..),
62+import Servant.Common.Req (QParam (..), QueryPart (..), Req,
55− QueryPart(..), addHeader, authData,
63+ ReqResult (..), addHeader, authData,
56− defReq, prependToPathParts,
58− performRequestsCT,
64+ defReq, performRequestsCT,
59− -- performRequestNoBody,
60− performRequestsNoBody,
65+ performRequestsNoBody,
61− performSomeRequestsAsync,
66+ performSomeRequestsAsync,
62− qParamToQueryPart, reqBody,
67+ prependToPathParts, qParamToQueryPart,
63− reqSuccess, reqFailure,
68+ qParams, reqBody, reqFailure,
69+ reqMethod, reqSuccess, reqSuccess',
64− reqMethod, respHeaders, response,
70+ respHeaders, response)
66−import Servant.Reflex (BuildHeaderKeysTo(..), toHeaders)
71+import Servant.Reflex (BuildHeaderKeysTo (..), toHeaders)
69------------------------------------------------------------------------------
74------------------------------------------------------------------------------
@@ -102,7 +107,8 @@ instance (SupportsServantReflex t m,
102 type ClientMulti t m (Capture capture a :> sublayout) f tag =
107 type ClientMulti t m (Capture capture a :> sublayout) f tag =
103 f (Dynamic t (Either Text a)) -> ClientMulti t m sublayout f tag
108 f (Dynamic t (Either Text a)) -> ClientMulti t m sublayout f tag
110+ clientWithRouteMulti _ q f tag reqs baseurl vals =
105− clientWithRouteMulti l q f tag reqs baseurl vals = clientWithRouteMulti (Proxy :: Proxy sublayout) q f tag reqs' baseurl
111+ clientWithRouteMulti (Proxy :: Proxy sublayout) q f tag reqs' baseurl
107 reqs' = (prependToPathParts <$> ps <*>) <$> reqs
113 reqs' = (prependToPathParts <$> ps <*>) <$> reqs
108 ps = (fmap . fmap . fmap) toUrlPiece vals
114 ps = (fmap . fmap . fmap) toUrlPiece vals
@@ -122,7 +128,7 @@ instance {-# OVERLAPPABLE #-}
122 type ClientMulti t m (Verb method status cts' a) f tag =
128 type ClientMulti t m (Verb method status cts' a) f tag =
123 Event t tag -> m (Event t (f (ReqResult tag a)))
129 Event t tag -> m (Event t (f (ReqResult tag a)))
125− clientWithRouteMulti _ _ f tag reqs baseurl =
131+ clientWithRouteMulti _ _ _ _ reqs baseurl =
126 performRequestsCT (Proxy :: Proxy ct) method reqs' baseurl
132 performRequestsCT (Proxy :: Proxy ct) method reqs' baseurl
127 where method = E.decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
133 where method = E.decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
128 reqs' = fmap (\r -> r { reqMethod = method }) <$> reqs
134 reqs' = fmap (\r -> r { reqMethod = method }) <$> reqs
@@ -137,7 +143,7 @@ instance {-# OVERLAPPING #-}
137 Event t tag -> m (Event t (f (ReqResult tag NoContent)))
143 Event t tag -> m (Event t (f (ReqResult tag NoContent)))
138 -- TODO: how to access input types here?
144 -- TODO: how to access input types here?
139 -- ExceptT ServantError IO NoContent
145 -- ExceptT ServantError IO NoContent
140− clientWithRouteMulti Proxy _ _ tag req baseurl =
146+ clientWithRouteMulti Proxy _ _ _ req baseurl =
141 performRequestsNoBody method req baseurl
147 performRequestsNoBody method req baseurl
142 where method = E.decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
148 where method = E.decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
@@ -223,7 +229,6 @@ instance (KnownSymbol sym,
223 ToHttpApiData a,
229 ToHttpApiData a,
224 HasClientMulti t m sublayout f tag,
230 HasClientMulti t m sublayout f tag,
225 Reflex t,
231 Reflex t,
227 Applicative f)
232 Applicative f)
228 => HasClientMulti t m (QueryParam sym a :> sublayout) f tag where
233 => HasClientMulti t m (QueryParam sym a :> sublayout) f tag where
@@ -249,7 +254,6 @@ instance (KnownSymbol sym,
249 ToHttpApiData a,
254 ToHttpApiData a,
250 HasClientMulti t m sublayout f tag,
255 HasClientMulti t m sublayout f tag,
251 Reflex t,
256 Reflex t,
253 Applicative f)
257 Applicative f)
254 => HasClientMulti t m (QueryParams sym a :> sublayout) f tag where
258 => HasClientMulti t m (QueryParams sym a :> sublayout) f tag where
@@ -264,21 +268,19 @@ instance (KnownSymbol sym,
264 params' l = QueryPartParams $ (fmap . fmap) (toQueryParam)
268 params' l = QueryPartParams $ (fmap . fmap) (toQueryParam)
266 reqs' = liftA2 req' <$> paramlists <*> reqs
270 reqs' = liftA2 req' <$> paramlists <*> reqs
267− -- reqs' = req' <$> paramlists <*> reqs
270instance (KnownSymbol sym,
273instance (KnownSymbol sym,
271 HasClientMulti t m sublayout f tag,
274 HasClientMulti t m sublayout f tag,
272 Reflex t,
275 Reflex t,
274 Applicative f)
276 Applicative f)
275 => HasClientMulti t m (QueryFlag sym :> sublayout) f tag where
277 => HasClientMulti t m (QueryFlag sym :> sublayout) f tag where
277 type ClientMulti t m (QueryFlag sym :> sublayout) f tag =
279 type ClientMulti t m (QueryFlag sym :> sublayout) f tag =
278 Dynamic t (f Bool) -> ClientMulti t m sublayout f tag
280 Dynamic t (f Bool) -> ClientMulti t m sublayout f tag
280− clientWithRouteMulti Proxy q f tag reqs baseurl flags =
282+ clientWithRouteMulti Proxy q f' tag reqs baseurl flags =
281− clientWithRouteMulti (Proxy :: Proxy sublayout) q f tag reqs' baseurl
283+ clientWithRouteMulti (Proxy :: Proxy sublayout) q f' tag reqs' baseurl
283 where req' f req = req { qParams = thisPair (constDyn f) : qParams req }
285 where req' f req = req { qParams = thisPair (constDyn f) : qParams req }
284 thisPair f = (T.pack pName, QueryPartFlag f) :: (Text, QueryPart t)
286 thisPair f = (T.pack pName, QueryPartFlag f) :: (Text, QueryPart t)
@@ -292,10 +294,9 @@ instance (SupportsServantReflex t m,
292 -> Event t tag
294 -> Event t tag
293 -> m (Event t (f (ReqResult tag ())))
295 -> m (Event t (f (ReqResult tag ())))
295− clientWithRouteMulti _ _ _ _ oldReqs baseurl rawReqs triggers = do
297+ clientWithRouteMulti _ _ _ _ _ _ rawReqs triggers = do
296 let rawReqs' = sequence rawReqs :: Dynamic t (f (Either Text (XhrRequest ())))
298 let rawReqs' = sequence rawReqs :: Dynamic t (f (Either Text (XhrRequest ())))
297 rawReqs'' = attachPromptlyDynWith (\fxhr t -> Compose (t, fxhr)) rawReqs' triggers
299 rawReqs'' = attachPromptlyDynWith (\fxhr t -> Compose (t, fxhr)) rawReqs' triggers
298−-- resps <- fmap (second (fmap aux) . getCompose) <$> performSomeRequestsAsync rawReqs''
299 resps <- fmap (fmap aux . sequenceA . getCompose) <$> performSomeRequestsAsync rawReqs''
300 resps <- fmap (fmap aux . sequenceA . getCompose) <$> performSomeRequestsAsync rawReqs''
300 return resps
301 return resps
@@ -306,7 +307,6 @@ instance (SupportsServantReflex t m,
306instance (MimeRender ct a,
307instance (MimeRender ct a,
307 HasClientMulti t m sublayout f tag,
308 HasClientMulti t m sublayout f tag,
308 Reflex t,
309 Reflex t,
310 Applicative f)
310 Applicative f)
311 => HasClientMulti t m (ReqBody (ct ': cts) a :> sublayout) f tag where
311 => HasClientMulti t m (ReqBody (ct ': cts) a :> sublayout) f tag where
@@ -359,7 +359,7 @@ instance HasClientMulti t m api f tag => HasClientMulti t m (IsSecure :> api) f
359 clientWithRouteMulti (Proxy :: Proxy api) q f tag reqs baseurl
359 clientWithRouteMulti (Proxy :: Proxy api) q f tag reqs baseurl
362−instance (HasClientMulti t m api f tag, Reflex t, Traversable f, Applicative f)
362+instance (HasClientMulti t m api f tag, Reflex t, Applicative f)
363 => HasClientMulti t m (BasicAuth realm usr :> api) f tag where
363 => HasClientMulti t m (BasicAuth realm usr :> api) f tag where
365 type ClientMulti t m (BasicAuth realm usr :> api) f tag = Dynamic t (f (Maybe BasicAuthData))
365 type ClientMulti t m (BasicAuth realm usr :> api) f tag = Dynamic t (f (Maybe BasicAuthData))