@@ -20,7 +20,12 @@ import Control.Arrow ((***))
20import Control.Monad ((<=<))
20import Control.Monad ((<=<))
21import qualified Data.ByteString.Lazy as BSL
21import qualified Data.ByteString.Lazy as BSL
22import qualified Data.ByteString.Lazy.Char8 as BSL8
22import qualified Data.ByteString.Lazy.Char8 as BSL8
23+import Data.Hashable (Hashable)
24+import Data.HashMap.Strict (HashMap)
25+import qualified Data.HashMap.Strict as HashMap
23import Data.Int
26import Data.Int
27+import Data.IntMap (IntMap)
28+import qualified Data.IntMap as IntMap
24import Data.Map (Map)
29import Data.Map (Map)
25import qualified Data.Map as Map
30import qualified Data.Map as Map
26import Data.Monoid
31import Data.Monoid
@@ -201,7 +206,17 @@ instance (ToFormKey k, ToHttpApiData v) => ToForm [(k, v)] where
201 toForm = fromList . map (toFormKey *** toQueryParam)
206 toForm = fromList . map (toFormKey *** toQueryParam)
203instance (ToFormKey k, ToHttpApiData v) => ToForm (Map k [v]) where
208instance (ToFormKey k, ToHttpApiData v) => ToForm (Map k [v]) where
209+ toForm = fromEntriesByKey . Map.toList
211+instance (ToFormKey k, ToHttpApiData v) => ToForm (HashMap k [v]) where
212+ toForm = fromEntriesByKey . HashMap.toList
214+instance ToHttpApiData v => ToForm (IntMap [v]) where
215+ toForm = fromEntriesByKey . IntMap.toList
217+-- | Convert a list of entries groupped by key into a 'Form'.
218+fromEntriesByKey :: (ToFormKey k, ToHttpApiData v) => [(k, [v])] -> Form
204− toForm = Form . Map.fromListWith (<>) . map (toFormKey *** map toQueryParam) . Map.toList
219+fromEntriesByKey = Form . Map.fromListWith (<>) . map (toFormKey *** map toQueryParam)
206-- | A 'Generic'-based implementation of 'toForm'.
221-- | A 'Generic'-based implementation of 'toForm'.
207-- This is used as a default implementation in 'ToForm'.
222-- This is used as a default implementation in 'ToForm'.
@@ -273,14 +288,20 @@ class FromForm a where
273instance FromForm Form where fromForm = pure
288instance FromForm Form where fromForm = pure
275instance (FromFormKey k, FromHttpApiData v) => FromForm [(k, v)] where
290instance (FromFormKey k, FromHttpApiData v) => FromForm [(k, v)] where
276− fromForm = fmap (concatMap (\(k, vs) -> map ((,) k) vs)) . entriesByKey
291+ fromForm = fmap (concatMap (\(k, vs) -> map ((,) k) vs)) . toEntriesByKey
278instance (Ord k, FromFormKey k, FromHttpApiData v) => FromForm (Map k [v]) where
293instance (Ord k, FromFormKey k, FromHttpApiData v) => FromForm (Map k [v]) where
279− fromForm = fmap (Map.fromListWith (<>)) . entriesByKey
294+ fromForm = fmap (Map.fromListWith (<>)) . toEntriesByKey
296+instance (Eq k, Hashable k, FromFormKey k, FromHttpApiData v) => FromForm (HashMap k [v]) where
297+ fromForm = fmap (HashMap.fromListWith (<>)) . toEntriesByKey
299+instance FromHttpApiData v => FromForm (IntMap [v]) where
300+ fromForm = fmap (IntMap.fromListWith (<>)) . toEntriesByKey
281-- | Parse a 'Form' into a list of entries groupped by key.
302-- | Parse a 'Form' into a list of entries groupped by key.
282−entriesByKey :: (FromFormKey k, FromHttpApiData v) => Form -> Either Text [(k, [v])]
303+toEntriesByKey :: (FromFormKey k, FromHttpApiData v) => Form -> Either Text [(k, [v])]
283−entriesByKey = traverse parseGroup . Map.toList . unForm
304+toEntriesByKey = traverse parseGroup . Map.toList . unForm
285 parseGroup (k, vs) = (,) <$> parseFormKey k <*> traverse parseQueryParam vs
306 parseGroup (k, vs) = (,) <$> parseFormKey k <*> traverse parseQueryParam vs