type GoalDescription = Text
data GoalStatus = Created | Accomplished | InProgress | GivenUp deriving (Show , Eq , Generic )
data Goal = Goal {workspaceId ::WorkspaceId , goalId :: GoalId , description :: GoalDescription , status :: GoalStatus} deriving (Show , Eq , Generic )
instance ToJSON Goal where
toJSON (Goal {workspaceId, goalId ,description,status } ) = object [
"workspaceId" .= workspaceId,
"goalId" .= goalId,
"description" .= description,
"status" .= status]
instance FromJSON Goal where
parseJSON (Object jsonObject) = Goal <$> jsonObject .: "workspaceId" <*> jsonObject .: "goalId" <*> jsonObject .: "description" <*> jsonObject .: "status"
parseJSON _ = error $ "Json format not expected"
I want to implement the FromJSON and ToJSON of GoalStatus that way: Goal {.. status:"accomplished"}
or Goal {.. status:"inProgress"}
etc... somehow I don't know how to implement these type classes without having a key -> value structure... GoalStatus
should be only converted into a String Text
without Keys attached to the value..
I have this temporary solution where I had to add an unnecessary key named "value" :
instance ToJSON GoalStatus where
toJSON (Created) = object ["value" .= String "created"]
toJSON (InProgress) = object ["value" .= String "inProgress"]
toJSON (Accomplished) = object ["value" .= String "accomplished"]
toJSON (GivenUp) = object ["value" .= String "GivenUp"]
instance FromJSON GoalStatus where
parseJSON (Object o) = do
value <- o .: "value"
case value of
String status | (unpack status) == "created" -> return Created
String status | (unpack status) == "inProgress" -> return InProgress
String status | (unpack status) == "accomplished" -> return Accomplished
String status | (unpack status) == "accomplished" -> return GivenUp
_ -> error $ "Json format not expected"
parseJSON _ = error $ "Json format not expected"
String !Text
is a constructor of Value
and object
has the type signature [Pair] -> Value
where Pair
is (Text, Value)
. You can use String
to make the Value
in ToJSON
and then match on the particular shapes of the String
when parsing in FromJSON
.
instance ToJSON GoalStatus where
toJSON (Created) = String "created"
toJSON (InProgress) = String "inProgress"
toJSON (Accomplished) = String "accomplished"
toJSON (GivenUp) = String "givenUp"
instance FromJSON GoalStatus where
parseJSON (String s) = case unpack s of
"created" -> return Created
"inProgress" -> return InProgress
"accomplished" -> return Accomplished
"givenUp" -> return GivenUp
_ -> error $ "Json format not expected"
parseJSON _ = error $ "Json format not expected"