git.iko.soy/typeable/aeson-inflections
on master help sign in
4 files changed+115−21
since splitsnapshots
unifiedsplit
LICENSE+2 aeson-inflections.cabal+29−19 src/Data/Aeson/Inflections.hs+38−2 src/Data/Aeson/Inflections/Generic.hs+46
LICENSEnew file+2
@@ -0,0 +1,2 @@
1+Copyright © 2020, Antorica LLC
2+All rights reserved
aeson-inflections.cabal+29−19
@@ -1,21 +1,31 @@
1−name: aeson-inflections
2−version: 0.1.0.0
3−synopsis: Collection of useful functions for aeson instances and stuff
4−author: Author name here
5−maintainer: example@example.com
6−copyright: 2020 Author name here
7−category: Web
8−build-type: Simple
9−cabal-version: >=1.10
1+cabal-version: 2.4
2+name: aeson-inflections
3+version: 0.1.0.0
4+synopsis:
5+ Collection of useful functions for aeson instances and stuff
6+
7+author: Author name here
8+maintainer: example@example.com
9+license-file: LICENSE
10+category: Web
11+build-type: Simple
1012
1113library
12− hs-source-dirs: src
13− ghc-options: -Wall
14− exposed-modules: Data.Aeson.Inflections
15− build-depends: base >= 4.7 && < 5
16− , aeson
17− , inflections
18− , lens
19− , megaparsec
20− , text
21− default-language: Haskell2010
14+ hs-source-dirs: src
15+ ghc-options: -Wall
16+ exposed-modules:
17+ Data.Aeson.Inflections
18+ Data.Aeson.Inflections.Generic
19+
20+ build-depends:
21+ , aeson
22+ , base >=4.12 && <5
23+ , deriving-aeson >=0.2
24+ , inflections
25+ , lens
26+ , megaparsec >=7.0
27+ , template-haskell
28+ , text
29+
30+ default-extensions: DataKinds
31+ default-language: Haskell2010
src/Data/Aeson/Inflections.hs+38−2
@@ -1,10 +1,28 @@
1−module Data.Aeson.Inflections where
1+module Data.Aeson.Inflections
2+ ( defaultFieldLabelModifier
3+ , defaultFieldLabelModifier'
4+ , deriveDefaultJSON
5+ , deriveEnumJSON
6+ , dropPrefix
7+ , dropPrefixLower
8+ , dropByPrefixLength
9+ , cutPrefix
10+ , cutOptionalPrefix
11+ , toUnderscore
12+ , toDashed
13+ , toSpaced
14+ ) where
215
316import Control.Lens
417import Control.Monad
18+import Data.Aeson
19+import Data.Aeson.TH
520import Data.Char
6−import Data.Text as T (Text, pack, unpack)
21+import Data.Maybe
22+import Data.Text (Text)
23+import qualified Data.Text as T
724import Data.Void
25+import Language.Haskell.TH
826import qualified Text.Inflections as I
927import Text.Megaparsec.Error
1028
@@ -17,10 +35,24 @@ defaultFieldLabelModifier = toUnderscore . dropPrefix
1735defaultFieldLabelModifier' :: Text -> Text
1836defaultFieldLabelModifier' = T.pack . defaultFieldLabelModifier . T.unpack
1937
38+deriveDefaultJSON :: Name -> Q [Dec]
39+deriveDefaultJSON = deriveJSON defaultOptions
40+ { fieldLabelModifier = defaultFieldLabelModifier }
41+
42+deriveEnumJSON :: String -> Name -> Q [Dec]
43+deriveEnumJSON prefix = deriveJSON defaultOptions
44+ { constructorTagModifier = toUnderscore . cutPrefix prefix }
45+
2046-- | Just drops prefix
2147dropPrefix :: String -> String
2248dropPrefix = dropWhile (not . isUpper)
2349
50+-- | The same as @Prelude.drop@, but takes a string, instead of a length.
51+-- This makes code more explicit (easier to see what exactly we are expecting to
52+-- @drop@)
53+dropByPrefixLength :: Text -> (String -> String)
54+dropByPrefixLength t = drop (T.length t)
55+
2456-- | Cuts the prefix or throws error if prefix does not match. For TH
2557-- modifiers only
2658cutPrefix :: String -> String -> String
@@ -30,6 +62,10 @@ cutPrefix pref s = if pref == take plen s
3062 where
3163 plen = length pref
3264
65+-- | Drop prefix if exists
66+cutOptionalPrefix :: Text -> Text -> Text
67+cutOptionalPrefix prefix txt = fromMaybe txt $ T.stripPrefix prefix txt
68+
3369-- | Drops prefix and turns first character to lowercase
3470dropPrefixLower :: String -> String
3571dropPrefixLower = over _head toLower . dropPrefix
src/Data/Aeson/Inflections/Generic.hsnew file+46
@@ -0,0 +1,46 @@
1+{-# LANGUAGE KindSignatures #-}
2+
3+module Data.Aeson.Inflections.Generic
4+ -- Reexports from Deriving.Aeson
5+ ( CustomJSON(..)
6+ , FieldLabelModifier
7+ , ConstructorTagModifier
8+ , CamelToSnake
9+ , StripPrefix
10+ , OmitNothingFields
11+
12+ , DropPrefix
13+ , DropPrefixLower
14+ , ToLower
15+ , DefaultFieldLabelModifier
16+ , DefaultJSON
17+ , DefaultEnumJSON
18+ )
19+ where
20+
21+import Data.Aeson.Inflections
22+import Data.Char
23+import Deriving.Aeson
24+import GHC.TypeLits
25+
26+data DropPrefix
27+
28+instance StringModifier DropPrefix where
29+ getStringModifier = dropPrefix
30+
31+data DropPrefixLower
32+
33+instance StringModifier DropPrefixLower where
34+ getStringModifier = dropPrefixLower
35+
36+data ToLower
37+
38+instance StringModifier ToLower where
39+ getStringModifier = map toLower
40+
41+type DefaultFieldLabelModifier = (DropPrefix, CamelToSnake)
42+
43+type DefaultJSON = CustomJSON '[FieldLabelModifier DefaultFieldLabelModifier]
44+
45+type DefaultEnumJSON (prefix :: Symbol)
46+ = CustomJSON '[ConstructorTagModifier (StripPrefix prefix, CamelToSnake)]