{-| Module : Servant.API.Auth.Token.Internal.DeriveJson Description : Helpers for aeson deriving without name prefixes. Copyright : (c) Anton Gushcha, 2016 License : MIT Maintainer : ncrashed@gmail.com Stability : experimental Portability : Portable Common usage: > data PagedList i a = PagedList { > pagedListItems :: ![a] -- ^ Payload > , pagedListPages :: !Word -- ^ Count of available pages > } deriving (Generic, Show) > > $(deriveJSON (derivePrefix "pagedList") ''PagedList) It will work with the following jsons: > { "items": [], "pages": 0 } -} module Servant.API.Auth.Token.Internal.DeriveJson( derivePrefix , deriveJSON ) where import Data.Aeson.TH as TH import Data.Char as C import Data.Text (Text) import qualified Data.Text as T -- | For aeson deriving, drop prefix t and map to lower derivePrefix :: Text -> TH.Options derivePrefix t = defaultOptions { fieldLabelModifier = mapFirst C.toLower . drop (T.length t) , constructorTagModifier = camelCaseToDash } mapFirst :: (a -> a) -> [a] -> [a] mapFirst f cs = case cs of [] -> [] (x:xs) -> f x : xs camelCaseToDash :: String -> String camelCaseToDash = foldr go "" . mapFirst C.toLower where go c acc = if C.isUpper c then '_' : C.toLower c : acc else c : acc