2013-07-15 20 views
2

我有收到JSON,看起來像一個服務器:如何使用aeson將JSON的非字符串部分保留爲字符串?

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

,所有的東西是服務器除了的「結果」,這是被轉發到客戶端(工人--JSON- - >服務器 - 「結果」 - >客戶端)的值。因此,在用aeson解析這個東西的時候,我想把「result」的值保存爲一個字符串(或者Text或者whatnot),這樣我就可以將它轉發給客戶端,而不用關心裏面的內容。問題是「結果」可以是任何東西(數組,對象等)。 所以,如果我做

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

埃宋的decode函數將返回Nothing,因爲「結果」不一定是一個JSON字符串...

我如何告訴埃宋保留的部分JSON對象是,只是給我,所以我可以做我想要的東西嗎?

回答

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 
相關問題