aeson icon indicating copy to clipboard operation
aeson copied to clipboard

Allow customization of record field unpacking for TaggedObject

Open tysonzero opened this issue 1 year ago • 0 comments

Currently the only way to get record field unpacking when using a sum-of-records is to avoid intermediate types and use the horrible misfeature that is partial record fields.

data Vehicle = Car { make :: String, speed :: Int } | Bicycle { brand :: String, gears :: Int }
    deriving (Generic, ToJSON)

encode $ Car { make = "MINI", speed = 150 }
> {"tag":"Car","make":"MINI","speed":150}

vs:

data Vehicle = VehicleCar Car | VehicleBicycle Bicycle
    deriving (Generic, ToJSON)

data Car = Car { make :: String, speed :: Int }
    deriving (Generic, ToJSON)

data Bicycle = Bicycle { brand :: String, gears :: Int }
    deriving (Generic, ToJSON)

encode . VehicleCar $ Car { make = "MINI", speed = 150 }
> {"tag":"VehicleCar","contents":{"speed":150,"make":"MINI"}}

If TaggedObject had an unpack :: Bool parameter users would be able to decide if they want unpacking or not, using contentsFieldName when it's False. Alternatively you could make contentsFieldName a Maybe String, this would just prevent any kind of error recovery if one of the sub-objects serializes to something other than a record, although it's unclear if such error recovery would be desirable anyway.

tysonzero avatar Apr 04 '24 18:04 tysonzero