Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Aeson does not support Maybe on nested records #80

Closed
sseveran opened this Issue · 12 comments

4 participants

@sseveran

This may be related to some of the other issues listed. I am unable to mark fields on nested records as Maybe. It compiles fine buy requires the fields to be in the JSON at runtime.

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Aeson
import Data.Text
import qualified Data.ByteString.Lazy as BL
import Data.ByteString.Lazy.Char8 ()

import GHC.Generics
import Data.Attoparsec.ByteString.Lazy as ABl

data RootRecord = RootRecord{
  field1 :: Maybe Text,
  field2 :: SubRecord
} deriving (Generic,Show)

data SubRecord = SubRecord{
  field3 :: Maybe Text
} deriving (Generic, Show)

instance FromJSON RootRecord
instance FromJSON SubRecord

main = do
  let jsonString :: BL.ByteString = "{ \"field1\" :\"foo\", \"field2\": {}}"
  let val :: Maybe (Value) = maybeResult $ ABl.parse json' jsonString
  foo <- case val of
        Just x -> 
          case fromJSON x of
            Success y -> return y
            Error str -> fail str
        Nothing -> error "No Parse"
  print (foo :: RootRecord)
@basvandijk
Collaborator

Note that this has nothing to do with nested records. If you leave out field1 of the RootRecord it also gives an error.

I would like to have this special case for Maybe fields myself. I'm planning to work on aeson next week (probably the weekend). I'll see if I can add this to both the GHC Generics and TH code (I think it's important that both have the same semantics).

@sseveran

I had not noticed that and you are indeed correct. @NathanHowell is also working on this issue for Generics on our side so he should hopefully send a patch over.

@sseveran

We have decided to wait for a fix since it needs to be done for both Generics and TH.

@sseveran

Any movement on this?

@basvandijk
Collaborator

I have a patch ready for TH but it's not really polished and documented yet. The patch also allows you to parameterize the encoding using these options:

data Options = Options
    { fieldNameModifier :: String -> String
    , nullaryToString   :: Bool
    , sumEncoding       :: SumEncoding
    }

data SumEncoding =
    TwoElemArray
  | ObjectWithType { typeFieldName  :: String
                   , valueFieldName :: String
                   }

defaultOptions :: Options
defaultOptions = Options
                 { fieldNameModifier = id
                 , nullaryToString   = True
                 , sumEncoding       = TwoElemArray
                 }

I try to submit a pull request this week.

@clockfort

Was this ever resolved? I just ran into this issue myself.

@sseveran

I used the patch referenced above for TH and that has worked out ok for me.

@clockfort

Cool, I was just wondering if the patch was upstream and I didn't have to do anything except update. I'm lazy like that :-)

@basvandijk
Collaborator

I've made a pull request for the TH code. See #97.

@bos
Owner

I've applied @basvandijk's patch (thanks!), still waiting on what to do for GHC Generics.

@basvandijk
Collaborator

The GHC Generics and TH encoders/decoders now both accept the encoding Options. So I consider this issue fixed.

@basvandijk basvandijk closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.