How can I declare an instance of FromJSON of the following data type:
data Privacy = Everyone |
AllFriends |
FriendsOfFriends |
Self
So that the following string to enumerated data type is honored:
"EVERYONE" -> Everyone
"ALL_FRIENDS" -> AllFriends
"FRIENDS_OF_FRIENDS" -> FriendsOfFriends
"SELF" -> Self
_ -> Parsing error
A possible solution is hinted here, but I cannot make that code compile.
Thanks!
This way involves less boilerplate, but it may not be as efficient due to the T.unpack
data Privacy = Everyone | AllFriends | FriendsOfFriends | Self deriving (Read, Show)
instance FromJSON Privacy where
parseJSON (String s) = fmap read (pure $ T.unpack s)
parseJSON _ = mzero
The FromJSON definition should read:
instance FromJSON Privacy where
parseJSON (Object v) = createPrivacy <$> (v .: "value")
Complete working example:
{-# LANGUAGE OverloadedStrings #-}
import Data.Text
import Data.Aeson
import Control.Applicative
import Control.Monad
data Privacy = Everyone |
AllFriends |
FriendsOfFriends |
Self
deriving (Show)
instance FromJSON Privacy where
parseJSON (Object v) = createPrivacy <$> (v .: "value")
parseJSON _ = mzero
createPrivacy :: String -> Privacy
createPrivacy "EVERYONE" = Everyone
createPrivacy "ALL_FRIENDS" = AllFriends
createPrivacy "FRIENDS_OF_FRIENDS" = FriendsOfFriends
createPrivacy "SELF" = Self
createPrivacy _ = error "Invalid privacy setting!"
main = do
let a = decode "{\"value\":\"ALL_FRIENDS\",\"foo\":12}" :: Maybe Privacy
print a
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With