@@ -155,6 +155,7 @@ module Network.HTTP.Req
155 -- $query-parameters
155 -- $query-parameters
157 queryFlag,
157 queryFlag,
158 QueryParam (..),
159 QueryParam (..),
160 -- *** Headers
161 -- *** Headers
@@ -272,6 +273,8 @@ import Text.URI (URI)
272import qualified Text.URI as URI
273import qualified Text.URI as URI
273import qualified Text.URI.QQ as QQ
274import qualified Text.URI.QQ as QQ
274import qualified Web.Authenticate.OAuth as OAuth
275import qualified Web.Authenticate.OAuth as OAuth
276+import Web.FormUrlEncoded (FromForm (..), ToForm (..))
277+import qualified Web.FormUrlEncoded as Form
275import Web.HttpApiData (ToHttpApiData (..))
278import Web.HttpApiData (ToHttpApiData (..))
277----------------------------------------------------------------------------
280----------------------------------------------------------------------------
@@ -1303,6 +1306,13 @@ newtype FormUrlEncodedParam = FormUrlEncodedParam [(Text, Maybe Text)]
1303instance QueryParam FormUrlEncodedParam where
1306instance QueryParam FormUrlEncodedParam where
1304 queryParam name mvalue =
1307 queryParam name mvalue =
1305 FormUrlEncodedParam [(name, toQueryParam <$> mvalue)]
1308 FormUrlEncodedParam [(name, toQueryParam <$> mvalue)]
1309+ queryParamToList (FormUrlEncodedParam p) = p
1311+-- | Use 'formToQuery'.
1314+instance FromForm FormUrlEncodedParam where
1315+ fromForm = Right . formToQuery
1307-- | Multipart form data. Please consult the
1317-- | Multipart form data. Please consult the
1308-- "Network.HTTP.Client.MultipartFormData" module for how to construct
1318-- "Network.HTTP.Client.MultipartFormData" module for how to construct
@@ -1428,6 +1438,12 @@ instance Monoid (Option scheme) where
1428 mempty = Option mempty Nothing
1438 mempty = Option mempty Nothing
1429 mappend = (<>)
1439 mappend = (<>)
1441+-- | Use 'formToQuery'.
1444+instance FromForm (Option scheme) where
1445+ fromForm = Right . formToQuery
1431-- | A helper to create an 'Option' that modifies only collection of query
1447-- | A helper to create an 'Option' that modifies only collection of query
1432-- parameters. This helper is not a part of the public API.
1448-- parameters. This helper is not a part of the public API.
1433withQueryParams :: (Y.QueryText -> Y.QueryText) -> Option scheme
1449withQueryParams :: (Y.QueryText -> Y.QueryText) -> Option scheme
@@ -1482,6 +1498,24 @@ name =: value = queryParam name (pure value)
1482queryFlag :: QueryParam param => Text -> param
1498queryFlag :: QueryParam param => Text -> param
1483queryFlag name = queryParam name (Nothing :: Maybe ())
1499queryFlag name = queryParam name (Nothing :: Maybe ())
1501+-- | Construct query parameters from a 'ToForm' instance. This function
1502+-- produces the same query params as 'Form.urlEncodeAsFormStable'.
1504+-- Note that 'Form.Form' doesn't have the concept of parameters with the
1505+-- empty value (i.e. what you can get by @key =: ""@). If the value is
1506+-- empty, it will be encoded as a valueless parameter (i.e. what you can get
1507+-- by @queryFlag key@).
1510+formToQuery :: (QueryParam param, Monoid param, ToForm f) => f -> param
1511+formToQuery f = mconcat . fmap toParam . Form.toListStable $ toForm f
1513+ toParam (key, val) =
1485-- | A type class for query-parameter-like things. The reason to have an
1519-- | A type class for query-parameter-like things. The reason to have an
1486-- overloaded 'queryParam' is to be able to use it as an 'Option' and as a
1520-- overloaded 'queryParam' is to be able to use it as an 'Option' and as a
1487-- 'FormUrlEncodedParam' when constructing form URL encoded request bodies.
1521-- 'FormUrlEncodedParam' when constructing form URL encoded request bodies.
@@ -1493,9 +1527,15 @@ class QueryParam param where
1493 -- method, because they are easier to read.
1527 -- method, because they are easier to read.
1494 queryParam :: ToHttpApiData a => Text -> Maybe a -> param
1528 queryParam :: ToHttpApiData a => Text -> Maybe a -> param
1530+ -- | Get the query parameter names and values set by 'queryParam'.
1533+ queryParamToList :: param -> [(Text, Maybe Text)]
1496instance QueryParam (Option scheme) where
1535instance QueryParam (Option scheme) where
1497 queryParam name mvalue =
1536 queryParam name mvalue =
1498 withQueryParams ((:) (name, toQueryParam <$> mvalue))
1537 withQueryParams ((:) (name, toQueryParam <$> mvalue))
1538+ queryParamToList (Option f _) = fst $ appEndo f ([], L.defaultRequest)
1500----------------------------------------------------------------------------
1540----------------------------------------------------------------------------
1501-- Request—Optional parameters—Headers
1541-- Request—Optional parameters—Headers