{-# LANGUAGE DerivingVia #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE UndecidableInstances #-} module Data.Aeson.Deriving.ModifyField where import Data.Aeson import Data.Aeson.Deriving.Generic import Data.Aeson.Deriving.Known import Data.Aeson.Deriving.Utils import Data.Proxy import GHC.Generics import GHC.TypeLits (KnownSymbol, Symbol) -- | Modify the contents of a particular field while decoding. newtype ModifyFieldIn (fieldName :: Symbol) fun a = ModifyFieldIn a deriving stock Generic deriving ToJSON via a instance ( FromJSON a , KnownSymbol fieldName , KnownJSONFunction fun , LoopWarning (ModifyFieldIn fieldName fun) a) => FromJSON (ModifyFieldIn fieldName fun a) where parseJSON = fmap ModifyFieldIn . parseJSON @a . mapObjects (mapField (textVal $ Proxy @fieldName) (functionVal $ Proxy @fun)) -- | Modify the contents of a particular field while encoding. newtype ModifyFieldOut (fieldName :: Symbol) fun a = ModifyFieldOut a deriving stock Generic deriving FromJSON via a instance ( ToJSON a , KnownSymbol fieldName , KnownJSONFunction fun , LoopWarning (ModifyFieldOut fieldName fun) a) => ToJSON (ModifyFieldOut fieldName fun a) where toJSON (ModifyFieldOut x) = mapObjects (mapField (textVal $ Proxy @fieldName) (functionVal $ Proxy @fun)) $ toJSON x newtype RemapTextField fieldName haskVal jsonVal a = RemapTextField (ModifyFieldOut fieldName (haskVal ==> jsonVal) (ModifyFieldIn fieldName (jsonVal ==> haskVal) a)) deriving newtype (FromJSON, ToJSON)