I am trying to parse a JSON from API with a data structure like
{
"en": {
"translation": {
"name": "Name",
"description": ["I am a", "en person"]
}
},
"jp": {
"translation": {
"name": "JP Name",
"description": ["I am a", "jp person"]
}
}
}
So I will just want to parse them to something like newtype Translations = Map String String
. locale will be key name and the value will be just the string of JSON translation like {"name": "Name", "description": ["I am a", en person"]}
because the value could be arbitrarily complex and I dun care/need to convert it to other Haskell data structure.
I tried so many way to write a proper parseJSON
for Translation
but still can't make it.
Any help would be appreciated!
We can decode the ByteString
with:
Prelude Data.Aeson Bs Hm Mp Tx> decode text :: Maybe Object
Just (fromList [("jp",Object (fromList [("translation",Object (fromList [("name",String "JP Name"),("description",Array [String "I am a",String "jp person"])]))])),("en",Object (fromList [("translation",Object (fromList [("name",String "Name"),("description",Array [String "I am a",String "en person"])]))]))])
So then we only need to perform a mapping on the HashMap Text Object
wrapped in the `Object constructor:
import Data.Aeson
import qualified Data.ByteString.Lazy.Char8 as Bs
import qualified Data.HashMap.Lazy as Hm
import qualified Data.Map as Mp
import qualified Data.Text as Tx
process :: Value -> Maybe (Mp.Map String String)
process (Object m) = Just ((Mp.fromList . map f) (Hm.toList m))
where f (x, y) = (Tx.unpack x, Bs.unpack (encode y))
process _ = Nothing
We then obtain a Map String String
wrapped in a Maybe
(since both decoding, and the processing can go wrong, it is probably better to use a Maybe
), that maps String
s on String
s:
Prelude Data.Aeson Bs Hm Mp Tx> decode text >>= process
Just (fromList [("en","{\"translation\":{\"name\":\"Name\",\"description\":[\"I am a\",\"en person\"]}}"),("jp","{\"translation\":{\"name\":\"JP Name\",\"description\":[\"I am a\",\"jp person\"]}}")])
That being said, I'm not sure that a JSON blob as value is here what you want, since now one can not "look into" the value and inspect what is inside that element. Furthermore if you want to do a lot of lookups, Text
is typically an order of magnitude faster when you want to check if two Text
s are the same.