2012-05-15 2 views
11

Data.Aeson을 사용하여 일부 JSON을 레코드 유형으로 구문 분석합니다. 때때로 데이터는 JSON에 추가되고 아이손이의 효과에 뭔가를 불평으로이 내 코드를 나누기 :결함 허용 JSON 구문 분석

예상 (21) 이름/값 쌍을 가진 객체 만 가지고 (23) 이름/값

폴트 톨러런스 방식으로 JSON을 구문 분석하는 것을 선호합니다. 나중에 더 많은 필드가 JSON에 추가되면 걱정하지 않아도됩니다. 이 내결함성을 달성 할 수있는 방법이 있습니까?

myRecordFromJSONString :: BS.ByteString -> Maybe MyRecord 
myRecordFromJSONString s = case Data.Attoparsec.parse json s of 
    Done _rest res -> Data.Aeson.Types.parseMaybe parseJSON res 
    _    -> Nothing 

내가 구문 분석 코드를 생성 Data.Aeson.TH에서 deriveJSON를 사용하고 있음을 추가해야합니다 : 여기에 내 코드입니다. FromJSON 코드를 수동으로 작성하면 내결함성이 있지만 그렇게 할 필요가 없습니다 ...

답변

6

GHC 7.2 또는 7.4를 사용하는 경우 aeson의 새로운 generics 지원은 추가 필드를 확인하지 않습니다 . 이것이 의도적인지 아닌지 잘 모르겠지만 같은 이유로 사용합니다.

{-# LANGUAGE DeriveGeneriC#-} 
{-# LANGUAGE OverloadedStrings #-} 

import Data.Aeson 
import qualified Data.Aeson.Types 
import Data.Attoparsec 
import qualified Data.ByteString as BS 
import Data.ByteString.Char8() 
import GHC.Generics 

data MyRecord = MyRecord 
    { field1 :: Int 
    } deriving (Generic, Show) 

instance FromJSON MyRecord 

myRecordFromJSONString :: BS.ByteString -> Maybe MyRecord 
myRecordFromJSONString s = case Data.Attoparsec.parse json s of 
    Done _rest res -> Data.Aeson.Types.parseMaybe parseJSON res 
    _    -> Nothing 

main :: IO() 
main = do 
    let parsed = myRecordFromJSONString "{ \"field1\": 1, \"field2\": 2 }" 
    print parsed 

'field2'가 레코드에 없기 때문에 TH 파생 인스턴스가 실행되면이 실행이 실패합니다. Generic 인스턴스는 원하는 결과를 반환합니다.

Just (MyRecord {field1 = 1})