Reputation: 185
I have a data which I want to parse from json:
data MyData = MyData
{ myDataId :: UUID
, myDataVar1 :: Bool
, myDataVar2 :: Maybe (UUID, String)
}
instance FromJSON MyData where
parseJSON (Object v) =
MyData <$> v .: "id"
<*> v .: "var1"
<*> ((,) <$> ((v .: "var2") >>= (.: "id")) <*> ((v .: "var2") >>= (.: "name"))) --- ??? doesn't work
How can I parse myDataVar2?
Upvotes: 0
Views: 87
Reputation: 52280
this based on the suspected JSON @zeta gave and the idea of @dfeuer
here is a compiling/working example
{-# LANGUAGE OverloadedStrings #-}
module ParseJson where
import Data.Aeson
import Data.Text
import Data.Text.Encoding
import Data.ByteString.Lazy (fromStrict)
testData :: Text
testData = "{ \"id\" :\"A211MNLR\", \"var1\": false, \"var2\": { \"id\": \"GA23210X\", \"name\": \"child\"} }"
testData2 :: Text
testData2 = "{ \"id\" :\"GA23210X\", \"var1\": false, \"var2\": null}"
data MyData = MyData
{ myDataId :: Text
, myDataVar1 :: Bool
, myDataVar2 :: Maybe (Text, Text)
} deriving Show
instance FromJSON MyData where
parseJSON (Object v) =
MyData <$> v .: "id"
<*> v .: "var1"
<*> (v .:? "var2" >>= parsePair)
where parsePair (Just (Object o)) = Just <$> ((,) <$> o .: "id" <*> o.: "name")
parsePair _ = pure Nothing
parse :: Text -> Maybe MyData
parse = decode . fromStrict . encodeUtf8
here are the tests:
λ> parse testData
Just (MyData {myDataId = "A211MNLR", myDataVar1 = False, myDataVar2 = Just ("GA23210X","child")})
λ> parse testData2
Just (MyData {myDataId = "GA23210X", myDataVar1 = False, myDataVar2 = Nothing})
Text
instead of UUID
- as far as I can see there is a fromText
in the uuid
package you can use to transform it further (but it's a Maybe UUID
as well) or you could write the FromJSON
instance for it - sadly I have no time to do it right - sorry :(parsePair
already there but it should be a start for you to figure it out
Upvotes: 1