如何使用aeson将JSON的非字符串部分保存为字符串?

时间:2013-07-15 01:49:53

标签: haskell aeson

我有一台接收JSON的服务器,如下所示:

{ "foo": "bar", "bono": "bobo",
  "result": { "some": ["complex", "JSON", "structure",...
}

其中所有内容都是服务器除了之外的“结果”,它将被转发到客户端(Worker --JSON - > Server - value of“result” - - >客户端)。因此,当用aeson解析这个东西时,我希望将“result”的值保持为字符串(或Text或whatnot),这样我就可以将它转发给客户端而不需要关心内部的内容。问题是“结果”可以是任何东西(数组,对象等)。 所以如果我这样做

data RPCResult = RPCResult { foo :: Text, result :: Text }

aeson的decode函数将返回Nothing,因为“result”不一定是JSON字符串......

我如何告诉aeson保留JSON对象的部分内容并将它们交给我,以便我可以用它们做我想做的事情?

1 个答案:

答案 0 :(得分:3)

我似乎通过将result的类型设为Data.Aeson.Value来获得某种解决方案,然后在对传入的JSON执行decode之后,我提取result并在转发前运行encode。我不确定这是否是最好的解决方案(因为我不是“将它保持为字符串”,如问题所述,但解码然后重新编码...)但它有效:

import Data.Aeson
import Data.Maybe
import Data.ByteString.Lazy (fromStrict, ByteString)
import Data.ByteString.UTF8 (fromString)
import Control.Applicative

data RPCResult = RPCResult { foo :: Text, result :: Value }

instance FromJSON RPCResult where
  parseJSON (Object v) = RPCResult <$> v .: "foo" <*> v .: "result"

-- example just so you get the idea:
toRPCResult :: String -> RPCResult
toRPCResult = fromJust . decode . fromStrict . fromString

getResult :: String -> ByteString
getResult = encode . result . toRPCResult