@@ -26,6 +26,7 @@ import Data.Aeson.Functions (hashMap, transformMap)
2626import Data.Aeson.Types hiding (FromJSON(..), ToJSON(..), fromJSON)
2727import Data.Attoparsec.Number (Number)
2828import Data.Generics
29+import Data.Hashable (Hashable)
2930import Data.Int (Int8, Int16, Int32, Int64)
3031import Data.IntSet (IntSet)
3132import Data.Maybe (fromJust)
@@ -154,7 +155,7 @@ parseJSON j = parseJSON_generic j
154155 `ext1R` list
155156 `ext1R` vector
156157 `ext2R'` mapAny
157− -- Don't know how to support parsing HashMaps :-(
158+ `ext2R'` hashMapAny
158159 -- Use the standard encoding for all base types.
159160 `extR` (value :: F Integer)
160161 `extR` (value :: F Int)
@@ -206,9 +207,22 @@ parseJSON j = parseJSON_generic j
206207 | otherwise = modError "parseJSON"
207208 "mapAny -- should never happen"
208209 tyrep = typeOf (undefined :: f)
210+ hashMapAny :: forall e f. (Data e, Data f) => Parser (H.HashMap f e)
211+ hashMapAny
212+ | tyrep == typeOf "" = process DT.unpack
213+ | tyrep == typeOf LT.empty = process LT.fromStrict
214+ | tyrep == typeOf DT.empty = process id
215+ | otherwise = myFail
216+ where
217+ process f = maybe myFail return . cast =<< parseWith f
218+ parseWith :: (Eq c, Hashable c) => (Text -> c) -> Parser (H.HashMap c e)
219+ parseWith f = case j of
220+ Object js -> H.fromList . map (first f) . Map.toList <$>
221+ T.mapM parseJSON js
222+ _ -> myFail
223+ tyrep = typeOf (undefined :: f)
209224 myFail = modFail "parseJSON" $ "bad data: " ++ show j
210225
211−
212226parseJSON_generic :: (Data a) => Value -> Parser a
213227parseJSON_generic j = generic
214228 where