{"id":13687413,"url":"https://github.com/fumieval/deriving-aeson","last_synced_at":"2025-04-05T15:05:45.649Z","repository":{"id":46229379,"uuid":"243196682","full_name":"fumieval/deriving-aeson","owner":"fumieval","description":"Scrap your hand-rolled aeson instances","archived":false,"fork":false,"pushed_at":"2024-11-23T02:29:14.000Z","size":256,"stargazers_count":112,"open_issues_count":4,"forks_count":8,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-29T14:06:46.927Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://hackage.haskell.org/package/deriving-aeson","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fumieval.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-26T07:29:42.000Z","updated_at":"2024-12-29T00:19:18.000Z","dependencies_parsed_at":"2025-01-15T04:29:30.720Z","dependency_job_id":"185d576c-6a9c-4db1-9c0d-9ce614e18cd1","html_url":"https://github.com/fumieval/deriving-aeson","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fumieval%2Fderiving-aeson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fumieval%2Fderiving-aeson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fumieval%2Fderiving-aeson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fumieval%2Fderiving-aeson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fumieval","download_url":"https://codeload.github.com/fumieval/deriving-aeson/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247353731,"owners_count":20925329,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T15:00:54.305Z","updated_at":"2025-04-05T15:05:45.615Z","avatar_url":"https://github.com/fumieval.png","language":"Haskell","funding_links":[],"categories":["Haskell"],"sub_categories":[],"readme":"deriving-aeson\n====\n\n[![Hackage](https://img.shields.io/hackage/v/deriving-aeson.svg)](https://hackage.haskell.org/package/deriving-aeson)\n![Haskell CI](https://github.com/fumieval/deriving-aeson/workflows/Haskell%20CI/badge.svg)\n[![Discord](https://img.shields.io/discord/664807830116892674?color=%237095ec\u0026label=Discord\u0026style=plastic)](https://discord.gg/DG93Tgs)\n\n![logo](https://github.com/fumieval/deriving-aeson/blob/master/logo/logo.png?raw=true)\n\nThis package provides a newtype wrapper where you can customise\n[aeson](https://hackage.haskell.org/package/aeson)'s generic methods using a\ntype-level interface, which synergises well with DerivingVia.\n\n```haskell\n{-# LANGUAGE DerivingVia, DataKinds, DeriveGeneric #-}\nimport Data.Aeson\nimport Deriving.Aeson\nimport qualified Data.ByteString.Lazy.Char8 as BL\n\ndata User = User\n  { userId :: Int\n  , userName :: String\n  , userAPIToken :: Maybe String\n  } deriving Generic\n  deriving (FromJSON, ToJSON)\n  via CustomJSON '[OmitNothingFields, FieldLabelModifier '[StripPrefix \"user\", CamelToSnake]] User\n\ntestData :: [User]\ntestData = [User 42 \"Alice\" Nothing, User 43 \"Bob\" (Just \"xyz\")]\n\nmain = BL.putStrLn $ encode testData\n-- [{\"name\":\"Alice\",\"id\":42},{\"api_token\":\"xyz\",\"name\":\"Bob\",\"id\":43}]\n```\n\n`Deriving.Aeson.Stock` contains some aliases for even less boilerplates.\n\n* `Prefixed str` = `CustomJSON '[FieldLabelModifier (StripPrefix str)]`\n* `PrefixedSnake str` = `CustomJSON '[FieldLabelModifier (StripPrefix str, CamelToSnake)]`\n* `Suffixed str` = `CustomJSON '[FieldLabelModifier (StripSuffix str)]`\n* `SuffixedSnake str` = `CustomJSON '[FieldLabelModifier (StripSuffix str, CamelToSnake)]`\n* `Snake` = `CustomJSON '[FieldLabelModifier '[StripPrefix str, CamelToSnake]]`\n* `Vanilla` = `CustomJSON '[]`\n\nHow it works\n----\n\nThe wrapper type has a phantom type parameter `t`, a type-level builder of an [Option](http://hackage.haskell.org/package/aeson-1.4.6.0/docs/Data-Aeson.html#t:Options).\nType-level primitives are reduced to one `Option` by the `AesonOptions` class.\n\n```haskell\nnewtype CustomJSON t a = CustomJSON { unCustomJSON :: a }\n\nclass AesonOptions xs where\n  aesonOptions :: Options\n\ninstance AesonOptions xs =\u003e AesonOptions (OmitNothingFields ': xs) where\n  aesonOptions = (aesonOptions @xs) { omitNothingFields = True }\n\n...\n```\n\nYou can use any (static) function for name modification by adding an instance of `StringModifier`.\n\n```haskell\ndata ToLower\ninstance StringModifier ToLower where\n  getStringModifier \"\" = \"\"\n  getStringModifier (c : xs) = toLower c : xs\n```\n\nPrevious studies\n----\n\n* [Type-driven safe derivation of ToJSON and FromJSON, using DerivingVia in GHC 8.6 and some type-level hacks](https://gist.github.com/konn/27c00f784dd883ec2b90eab8bc84a81d)\n* [Strip prefices from JSON representation](https://gist.github.com/fumieval/5c89205d418d5f9cafac801afbe94969)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffumieval%2Fderiving-aeson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffumieval%2Fderiving-aeson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffumieval%2Fderiving-aeson/lists"}