on master help sign in
Add QParam type for encoding ok/missing/invalid query param
db03e68Greg Hale
exec/Example.hs+1−1
@@ -53,7 +53,7 @@ run = do
53 text "Name"
53 text "Name"
54 el "br" $ return ()
54 el "br" $ return ()
55 inp :: Dynamic t String <- fmap value (textInput def)
55 inp :: Dynamic t String <- fmap value (textInput def)
56− let checkedName = fmap (\i -> bool (Right i) (Left "Need a name") (null i)) (current inp)
56+ let checkedName = fmap (\i -> bool (QParamSome i) (QParamInvalid "Need a name") (null i)) (current inp)
57 el "br" $ return ()
57 el "br" $ return ()
58
58
59 text "Greetings (space-separated)"
59 text "Greetings (space-separated)"
src/Servant/Common/Req.hs+13−3
@@ -14,6 +14,7 @@ import qualified Data.Text.Encoding as TE
14-- import qualified Data.Foldable as F
14-- import qualified Data.Foldable as F
15import qualified Data.List as L
15import qualified Data.List as L
16import Data.Proxy
16import Data.Proxy
17+import qualified Data.Text as T
17import qualified Data.Map as Map
18import qualified Data.Map as Map
18-- import Data.Monoid
19-- import Data.Monoid
19-- import Data.String
20-- import Data.String
@@ -58,7 +59,15 @@ response (ResponseSuccess _ x) = Just x
58response (ResponseFailure _ x) = Just x
59response (ResponseFailure _ x) = Just x
59response _ = Nothing
60response _ = Nothing
60
61
62+
63+data QParam a = QParamSome a | QNone | QParamInvalid String
64+
65+qParamToQueryPart :: ToHttpApiData a => QParam a -> Either String (Maybe String)
66+qParamToQueryPart (QParamSome a) = Right (Just . T.unpack $ toQueryParam a)
67+qParamToQueryPart QNone = Right Nothing
68+qParamToQueryPart (QParamInvalid e) = Left e
69+
61−data QueryPart t = QueryPartParam (Behavior t (Either String String))
70+data QueryPart t = QueryPartParam (Behavior t (Either String (Maybe String)))
62 | QueryPartParams (Behavior t [String])
71 | QueryPartParams (Behavior t [String])
63 | QueryPartFlag (Behavior t Bool)
72 | QueryPartFlag (Behavior t Bool)
64
73
@@ -117,8 +126,9 @@ performRequest reqMethod req reqHost trigger = do
117 queryPartString :: (String, QueryPart t) -> Behavior t (Maybe (Either String String))
126 queryPartString :: (String, QueryPart t) -> Behavior t (Maybe (Either String String))
118 queryPartString (pName, qp) = case qp of
127 queryPartString (pName, qp) = case qp of
119 QueryPartParam p -> ffor p $ \case
128 QueryPartParam p -> ffor p $ \case
120− Left e -> Just (Left e)
129+ Left e -> Just (Left e)
121− Right a -> Just (Right $ pName ++ "=" ++ a)
130+ Right (Just a) -> Just (Right $ pName ++ "=" ++ a)
131+ Right Nothing -> Nothing
122 QueryPartParams ps -> ffor ps $ \pStrings ->
132 QueryPartParams ps -> ffor ps $ \pStrings ->
123 if null pStrings
133 if null pStrings
124 then Nothing
134 then Nothing
src/Servant/Reflex.hs+3−2
@@ -209,6 +209,7 @@ instance HasClient t m sublayout
209 clientWithRoute Proxy q =
209 clientWithRoute Proxy q =
210 clientWithRoute (Proxy :: Proxy sublayout) q
210 clientWithRoute (Proxy :: Proxy sublayout) q
211
211
212+
212-- | If you use a 'QueryParam' in one of your endpoints in your API,
213-- | If you use a 'QueryParam' in one of your endpoints in your API,
213-- the corresponding querying function will automatically take
214-- the corresponding querying function will automatically take
214-- an additional argument of the type specified by your 'QueryParam',
215-- an additional argument of the type specified by your 'QueryParam',
@@ -240,7 +241,7 @@ instance (KnownSymbol sym, ToHttpApiData a, HasClient t m sublayout, Reflex t)
240
241
241 type Client t m (QueryParam sym a :> sublayout) =
242 type Client t m (QueryParam sym a :> sublayout) =
242 -- TODO (Maybe a), or (Maybe (Maybe a))? (should the user be able to send a Nothing)
243 -- TODO (Maybe a), or (Maybe (Maybe a))? (should the user be able to send a Nothing)
243− Behavior t (Either String a) -> Client t m sublayout
244+ Behavior t (QParam a) -> Client t m sublayout
244
245
245 -- if mparam = Nothing, we don't add it to the query string
246 -- if mparam = Nothing, we don't add it to the query string
246 clientWithRoute Proxy q req baseurl mparam =
247 clientWithRoute Proxy q req baseurl mparam =
@@ -248,7 +249,7 @@ instance (KnownSymbol sym, ToHttpApiData a, HasClient t m sublayout, Reflex t)
248 (req {qParams = paramPair : qParams req}) baseurl
249 (req {qParams = paramPair : qParams req}) baseurl
249
250
250 where pname = symbolVal (Proxy :: Proxy sym)
251 where pname = symbolVal (Proxy :: Proxy sym)
251− p prm = QueryPartParam $ (fmap . fmap) (unpack . toQueryParam) prm
252+ p prm = QueryPartParam $ fmap (qParamToQueryPart) prm -- (fmap . fmap) (unpack . toQueryParam) prm
252 paramPair = (pname, p mparam)
253 paramPair = (pname, p mparam)
253
254
254-- | If you use a 'QueryParams' in one of your endpoints in your API,
255-- | If you use a 'QueryParams' in one of your endpoints in your API,