Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://gitlab.com/igrep/deriveJsonNoPrefix
Template Haskell macros to derive ToJSON/FromJSON instances in a more prefix-friendly manner.
https://gitlab.com/igrep/deriveJsonNoPrefix
haskell json template haskell
Last synced: about 1 month ago
JSON representation
Template Haskell macros to derive ToJSON/FromJSON instances in a more prefix-friendly manner.
- Host: gitlab.com
- URL: https://gitlab.com/igrep/deriveJsonNoPrefix
- Owner: igrep
- License: apache-2.0
- Created: 2018-07-16T05:32:34.313Z (over 6 years ago)
- Default Branch: master
- Last Synced: 2024-04-25T23:31:23.299Z (7 months ago)
- Topics: haskell, json, template haskell
- Stars: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: ChangeLog.md
- License: LICENSE
Awesome Lists containing this project
README
# deriveJsonNoPrefix
Template Haskell macros to derive ToJSON/FromJSON instances in a more prefix-friendly manner.
## Example
Suppose you want to create a JSON like this:
```json
{
"id": "ID STRING",
"max": 0.789,
"min": 0.123
}
```You'd want to define a record type to derive the instance of [ToJSON](http://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON) (and possibly [FromJSON](http://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON)) automatically:
```hs
{-# LANGUAGE TemplateHaskell #-}import Data.Aeson.TH
data SomeRecord = SomeRecord
{ id :: String
, max :: Double
, min :: Double
} deriving (Eq, Show)$(deriveToJSON ''SomeRecord)
```But you shouldn't define such a record because both `id`, `max`, and `min` are predefined functions of `Prelude`!!
As a workaround, we frequently prefix the record labels with their type name:
```hs
data SomeRecord = SomeRecord
{ someRecordId :: String
, someRecordMax :: Double
, someRecordMin :: Double
} deriving (Eq, Show)
```Then `deriveToJSON` with a modified option:
```hs
deriveToJSON Json.defaultOptions { fieldLabelModifier = firstLower . drop (length "SomeRecord") } ''SomeRecordfirstLower :: String -> String
firstLower (x:xs) = toLower x : xs
firstLower _ = error "firstLower: Assertion failed: empty string"
```That's almost exactly what `deriveToJsonNoTypeNamePrefix` does!!
`deriveToJsonNoTypeNamePrefix` is essentially defined as:```hs
deriveToJsonNoTypeNamePrefix :: Name -> Q [Dec]
deriveToJsonNoTypeNamePrefix deriver name =
deriveToJSON Json.defaultOptions { fieldLabelModifier = dropPrefix name } namedropPrefix :: Name -> String -> String
dropPrefix name = firstLower . drop (length $ nameBase name)firstLower :: String -> String
firstLower (x:xs) = toLower x : xs
firstLower _ = error "firstLower: Assertion failed: empty string"
```So now, you don't have reimplement the `fieldLabelModifier` anymore!
```hs
import Data.Aeson.DeriveNoPrefix$(deriveJsonNoTypeNamePrefix ''SomeRecord)
```## Other libraries which would solve the same problem
- [extensible](https://hackage.haskell.org/package/extensible).
- And other libraries providing extensible records with `ToJSON` / `FromJSON` instances.So use this package all of them are too heavy in learning cost / dependency footprint / etc.