Haskell, Aeson & JSON parsing into custom type

后端 未结 3 1927
春和景丽
春和景丽 2021-01-02 01:26

Following on from a previous post, I\'ve found I\'m totally stuck. I\'m trying to parse a JSON structure into my own type, and not only am I stuck on how to parse the Array,

3条回答
  •  太阳男子
    2021-01-02 02:17

    A slightly newer build of the aeson library (0.3.2.12) supports autogenerating JSON instances.

    {-# LANGUAGE TemplateHaskell #-}
    
    import Data.Aeson
    import Data.Aeson.TH (deriveJSON)
    import Data.Attoparsec
    import qualified Data.ByteString as B
    import qualified Data.Text as T
    
    data Exif = Exif [(T.Text, ExifValue)] deriving (Show)
    data ExifValue = 
        ExifText T.Text | 
        ExifInt Integer | 
        ExifDouble Double | 
        ExifBool Bool | 
        ExifArray [ExifValue] 
        deriving (Show)
    
    deriveJSON id ''Exif
    deriveJSON id ''ExifValue
    
    parseExifFile = fmap parseExifData . B.readFile
    
    parseExifData :: B.ByteString -> Data.Attoparsec.Result (Data.Aeson.Result [Exif])
    parseExifData content = parse (fmap fromJSON json) content
    

    Produces:

    instance ToJSON Exif where
      { toJSON
          = \ value_a1Va
              -> case value_a1Va of { Exif arg1_a1Vb -> toJSON arg1_a1Vb } }
    instance FromJSON Exif where
      { parseJSON
          = \ value_a1Vc
              -> case value_a1Vc of {
                   arg_a1Vd -> (Exif Data.Functor.<$> parseJSON arg_a1Vd) } }
    
    instance ToJSON ExifValue where
      { toJSON
          = \ value_a1Wd
              -> case value_a1Wd of {
                   ExifText arg1_a1We
                     -> object [(T.pack "ExifText" .= toJSON arg1_a1We)]
                   ExifInt arg1_a1Wf
                     -> object [(T.pack "ExifInt" .= toJSON arg1_a1Wf)]
                   ExifDouble arg1_a1Wg
                     -> object [(T.pack "ExifDouble" .= toJSON arg1_a1Wg)]
                   ExifBool arg1_a1Wh
                     -> object [(T.pack "ExifBool" .= toJSON arg1_a1Wh)]
                   ExifArray arg1_a1Wi
                     -> object [(T.pack "ExifArray" .= toJSON arg1_a1Wi)] } }
    instance FromJSON ExifValue where
      { parseJSON
          = \ value_a1Wj
              -> case value_a1Wj of {
                   Object obj_a1Wk
                     -> case Data.Map.toList obj_a1Wk of {
                          [(conKey_a1Wl, conVal_a1Wm)]
                            -> case conKey_a1Wl of {
                                 _ | (conKey_a1Wl == T.pack "ExifText")
                                   -> case conVal_a1Wm of {
                                        arg_a1Wn
                                          -> (ExifText Data.Functor.<$> parseJSON arg_a1Wn) }
                                   | (conKey_a1Wl == T.pack "ExifInt")
                                   -> case conVal_a1Wm of {
                                        arg_a1Wo
                                          -> (ExifInt Data.Functor.<$> parseJSON arg_a1Wo) }
                                   | (conKey_a1Wl == T.pack "ExifDouble")
                                   -> case conVal_a1Wm of {
                                        arg_a1Wp
                                          -> (ExifDouble Data.Functor.<$> parseJSON arg_a1Wp) }
                                   | (conKey_a1Wl == T.pack "ExifBool")
                                   -> case conVal_a1Wm of {
                                        arg_a1Wq
                                          -> (ExifBool Data.Functor.<$> parseJSON arg_a1Wq) }
                                   | (conKey_a1Wl == T.pack "ExifArray")
                                   -> case conVal_a1Wm of {
                                        arg_a1Wr
                                          -> (ExifArray Data.Functor.<$> parseJSON arg_a1Wr) }
                                   | otherwise -> Control.Monad.mzero }
                          _ -> Control.Monad.mzero }
                   _ -> Control.Monad.mzero } }
    

提交回复
热议问题