4

I would like to convert my json to below format. And to convert from below format to my record. Please check the code that I have written below.

{
    "uid" : "bob",
    "emailid" : "bob@bob.com",
    "email_verified" : "Y" // "Y" for EmailVerified and "N" for EmailNotVerified
}

I have below code where I am trying to convert user type to and from json using Aeson library in Haskell

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}

import Data.Monoid ((<>))
import GHC.Generics
import Data.Aeson (FromJSON, ToJSON)
import Data.Aeson.Types

data User = User {
    userId :: String,
    userEmail :: String,
    userEmailVerified :: EmailState
  } deriving (Show, Generic)

data EmailState = EmailVerified | EmailNotVerified deriving (Generic, Show)

instance ToJSON User where
    toJSON u = object [
       "uid" .= userId u,
       "emailid" .= userEmail u,
       "email_verified" .= userEmailVerified u
       ]

instance FromJSON User where
    parseJSON = withObject "User" $ \v -> User
        <$> v .: "uid"
        <*> v .: "emailid"
        <*> v .: "email_verified"

instance ToJSON EmailState
instance FromJSON EmailState

However, My format that I am currently able to generate is like below

{
    "uid" : "bob",
    "emailid" : "bob@bob.com",
    "email_verified" : "EmailVerified"
}
navin
  • 165
  • 1
  • 12

2 Answers2

5

You need to implement the ToJSON of EmailState yourself (so remove the instance ToJSON EmailState, and write it like):

instance ToJSON EmailState where
    toJSON EmailVerified = String "Y"
    toJSON EmailNotVerified = String "N"

You also will need to alter yhe parser:

instance FromJSON EmailState where
    parseJSON (String "Y") = return EmailVerified
    parseJSON (String "N") = return EmailNotVerified
    parseJSON _ = fail "Invalid JSON value to parse"
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • Thanks Willem . Your solution does work . If possible can you also update your answer or point to a good resource so that a new comer to haskell like me can understand hackage documentation. Like in above case I was trying instance ToJSON EmailState where toJSON _ = "Y" which did not work obviously. – navin Nov 27 '17 at 11:40
0

Awesome answer by Willem, Just to add to the syntax you can use -

instance FromJSON EmailState where
    parseJSON (String s) 
        | s == "Y" = return EmailVerified
        | s == "N" = return EmailNotVerified
        | otherwise = fail "Invalid JSON value to parse"

-- Note: otherwise = mzero -- is prefered

ref: https://mail.haskell.org/pipermail/beginners/2011-October/008791.html