FromJSON自定义类型

时间:2013-09-13 16:10:31

标签: json haskell aeson

最新版本的Data.Aeson改变了ToJSON和FromJSON对简单类型的工作方式,如:

data Permission = Read | Write

以前是通用调用:

instance ToJSON Permission where 

...会创建看起来像{“Read”:[]}或{“Write”:[]}的JSON。

但现在它创造了: {tag:"Read",contents:"[]"}

这有意义,但打破了我写的代码。我手工编写了一个toJSON来给出正确的东西,但编写fromJSON让我感到困惑。

有什么想法吗?

由于

2 个答案:

答案 0 :(得分:2)

您可以使用allNullaryToStringTag上的Data.Aeson.Options字段控制如何使用所有nullary构造函数编码数据类型。将其设置为True,它将被编码为字符串。

import Data.Aeson.Types (Options (..), defaultOptions)

data Permission = Read | Write

$(deriveToJSON (defaultOptions {allNullaryToStringTag = True}) ''Permission)

看看Options definition,它包含其他方便的字段。

答案 1 :(得分:1)

由于Object的{​​{1}}构造函数中包含的值只是一个严格的Data.Aeson.Value,我们可以从中提取密钥并根据它做出决定。我试过这个并且效果很好。

HashMap

您可以使用{-# LANGUAGE OverloadedStrings #-} module StackOverflow where import Data.Aeson import Control.Monad import Data.HashMap.Strict (keys) data Permission = Read | Write instance FromJSON Permission where parseJSON (Object v) = let ks = keys v in case ks of ["Read"] -> return Read ["Write"] -> return Write _ -> mzero parseJSON _ = mzero 进行测试。 decode "{\"Read\": []}" :: Maybe Permission中的mzero可确保传入其他内容时,它只会返回parseJSON。由于您似乎只想检查是否只有一个密钥与您的两个权限中的一个匹配,因此这非常简单,并且会在所有其他输入上正确返回Nothing

相关问题