最新版本的Data.Aeson改变了ToJSON和FromJSON对简单类型的工作方式,如:
data Permission = Read | Write
以前是通用调用:
instance ToJSON Permission where
...会创建看起来像{“Read”:[]}或{“Write”:[]}的JSON。
但现在它创造了:
{tag:"Read",contents:"[]"}
这有意义,但打破了我写的代码。我手工编写了一个toJSON来给出正确的东西,但编写fromJSON让我感到困惑。
有什么想法吗?
由于
答案 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
。