@@ -35,49 +35,50 @@ import qualified Data.Vector.Mutable as VM
3535-- Generic toJSON
3636
3737instance (GToJSON a) => GToJSON (M1 i c a) where
38− gToJSON = gToJSON . unM1
38+ gToJSON opts = gToJSON opts . unM1
3939 {-# INLINE gToJSON #-}
4040
4141instance (ToJSON a) => GToJSON (K1 i a) where
42− gToJSON = toJSON . unK1
42+ gToJSON _opts = toJSON . unK1
4343 {-# INLINE gToJSON #-}
4444
4545instance GToJSON U1 where
46− gToJSON _ = emptyArray
46+ gToJSON _opts _ = emptyArray
4747 {-# INLINE gToJSON #-}
4848
4949instance (ConsToJSON a) => GToJSON (C1 c a) where
50− gToJSON = consToJSON . unM1
50+ gToJSON opts = consToJSON opts . unM1
5151 {-# INLINE gToJSON #-}
5252
5353instance ( GProductToValues a, GProductToValues b
5454 , ProductSize a, ProductSize b) => GToJSON (a :*: b) where
55− gToJSON p = Array $ V.create $ do
56− mv <- VM.unsafeNew lenProduct
57− gProductToValues mv 0 lenProduct p
58− return mv
55+ gToJSON opts p =
56+ Array $ V.create $ do
57+ mv <- VM.unsafeNew lenProduct
58+ gProductToValues opts mv 0 lenProduct p
59+ return mv
5960 where
6061 lenProduct = unTagged2 (productSize :: Tagged2 (a :*: b) Int)
6162 {-# INLINE gToJSON #-}
6263
6364instance (GObject a, GObject b) => GToJSON (a :+: b) where
64− gToJSON (L1 x) = Object $ gObject x
65− gToJSON (R1 x) = Object $ gObject x
65+ gToJSON opts (L1 x) = Object $ gObject opts x
66+ gToJSON opts (R1 x) = Object $ gObject opts x
6667 {-# INLINE gToJSON #-}
6768
6869--------------------------------------------------------------------------------
6970
70−class ConsToJSON f where consToJSON :: f a -> Value
71−class ConsToJSON' b f where consToJSON' :: Tagged b (f a -> Value)
71+class ConsToJSON f where consToJSON :: Options -> f a -> Value
72+class ConsToJSON' b f where consToJSON' :: Tagged b (Options -> f a -> Value)
7273
7374newtype Tagged s b = Tagged {unTagged :: b}
7475
7576instance (IsRecord f b, ConsToJSON' b f) => ConsToJSON f where
76− consToJSON = unTagged (consToJSON' :: Tagged b (f a -> Value))
77+ consToJSON = unTagged (consToJSON' :: Tagged b (Options -> f a -> Value))
7778 {-# INLINE consToJSON #-}
7879
7980instance (GRecordToPairs f) => ConsToJSON' True f where
80− consToJSON' = Tagged (object . toList . gRecordToPairs)
81+ consToJSON' = Tagged (\opts -> object . toList . gRecordToPairs opts)
8182 {-# INLINE consToJSON' #-}
8283
8384instance GToJSON f => ConsToJSON' False f where
@@ -87,24 +88,33 @@ instance GToJSON f => ConsToJSON' False f where
8788--------------------------------------------------------------------------------
8889
8990class GRecordToPairs f where
90− gRecordToPairs :: f a -> DList Pair
91+ gRecordToPairs :: Options -> f a -> DList Pair
9192
9293instance (GRecordToPairs a, GRecordToPairs b) => GRecordToPairs (a :*: b) where
93− gRecordToPairs (a :*: b) = gRecordToPairs a `mappend` gRecordToPairs b
94+ gRecordToPairs opts (a :*: b) = gRecordToPairs opts a `mappend`
95+ gRecordToPairs opts b
9496 {-# INLINE gRecordToPairs #-}
9597
9698instance (Selector s, GToJSON a) => GRecordToPairs (S1 s a) where
97− gRecordToPairs m1 = pure (pack (selName m1), gToJSON (unM1 m1))
99+ gRecordToPairs opts m1 = pure ( pack $ fieldNameModifier opts $ selName m1
100+ , gToJSON opts (unM1 m1)
101+ )
98102 {-# INLINE gRecordToPairs #-}
99103
100104--------------------------------------------------------------------------------
101105
102106class GProductToValues f where
103− gProductToValues :: VM.MVector s Value -> Int -> Int -> f a -> ST s ()
107+ gProductToValues :: Options
108+ -> VM.MVector s Value
109+ -> Int -- ^ index
110+ -> Int -- ^ length
111+ -> f a
112+ -> ST s ()
104113
105114instance (GProductToValues a, GProductToValues b) => GProductToValues (a :*: b) where
106− gProductToValues mv ix len (a :*: b) = do gProductToValues mv ix lenL a
107− gProductToValues mv ixR lenR b
115+ gProductToValues opts mv ix len (a :*: b) = do
116+ gProductToValues opts mv ix lenL a
117+ gProductToValues opts mv ixR lenR b
108118 where
109119 lenL = len `shiftR` 1
110120 ixR = ix + lenL
@@ -112,48 +122,50 @@ instance (GProductToValues a, GProductToValues b) => GProductToValues (a :*: b)
112122 {-# INLINE gProductToValues #-}
113123
114124instance (GToJSON a) => GProductToValues a where
115− gProductToValues mv ix _ = VM.unsafeWrite mv ix . gToJSON
125+ gProductToValues opts mv ix _ = VM.unsafeWrite mv ix . gToJSON opts
116126 {-# INLINE gProductToValues #-}
117127
118128--------------------------------------------------------------------------------
119129
120130class GObject f where
121− gObject :: f a -> Object
131+ gObject :: Options -> f a -> Object
122132
123133instance (GObject a, GObject b) => GObject (a :+: b) where
124− gObject (L1 x) = gObject x
125− gObject (R1 x) = gObject x
134+ gObject opts (L1 x) = gObject opts x
135+ gObject opts (R1 x) = gObject opts x
126136 {-# INLINE gObject #-}
127137
128138instance (Constructor c, GToJSON a, ConsToJSON a) => GObject (C1 c a) where
129− gObject = H.singleton (pack $ conName (undefined :: t c a p)) . gToJSON
139+ gObject opts = H.singleton (pack $ constructorNameModifier opts
140+ $ conName (undefined :: t c a p))
141+ . gToJSON opts
130142 {-# INLINE gObject #-}
131143
132144--------------------------------------------------------------------------------
133145-- Generic parseJSON
134146
135147instance (GFromJSON a) => GFromJSON (M1 i c a) where
136− gParseJSON = fmap M1 . gParseJSON
148+ gParseJSON opts = fmap M1 . gParseJSON opts
137149 {-# INLINE gParseJSON #-}
138150
139151instance (FromJSON a) => GFromJSON (K1 i a) where
140− gParseJSON = fmap K1 . parseJSON
152+ gParseJSON _opts = fmap K1 . parseJSON
141153 {-# INLINE gParseJSON #-}
142154
143155instance GFromJSON U1 where
144− gParseJSON v
156+ gParseJSON _opts v
145157 | isEmptyArray v = pure U1
146158 | otherwise = typeMismatch "unit constructor (U1)" v
147159 {-# INLINE gParseJSON #-}
148160
149161instance (ConsFromJSON a) => GFromJSON (C1 c a) where
150− gParseJSON = fmap M1 . consParseJSON
162+ gParseJSON opts = fmap M1 . consParseJSON opts
151163 {-# INLINE gParseJSON #-}
152164
153165instance ( GFromProduct a, GFromProduct b
154166 , ProductSize a, ProductSize b) => GFromJSON (a :*: b) where
155− gParseJSON (Array arr)
156− | lenArray == lenProduct = gParseProduct arr 0 lenProduct
167+ gParseJSON opts (Array arr)
168+ | lenArray == lenProduct = gParseProduct opts arr 0 lenProduct
157169 | otherwise =
158170 fail $ "When expecting a product of " ++ show lenProduct ++
159171 " values, encountered an Array of " ++ show lenArray ++
@@ -162,15 +174,15 @@ instance ( GFromProduct a, GFromProduct b
162174 lenArray = V.length arr
163175 lenProduct = unTagged2 (productSize :: Tagged2 (a :*: b) Int)
164176
165− gParseJSON v = typeMismatch "product (:*:)" v
177+ gParseJSON _opts v = typeMismatch "product (:*:)" v
166178 {-# INLINE gParseJSON #-}
167179
168180instance (GFromSum a, GFromSum b) => GFromJSON (a :+: b) where
169− gParseJSON (Object (H.toList -> [keyVal@(key, _)])) =
170− case gParseSum keyVal of
181+ gParseJSON opts (Object (H.toList -> [keyVal@(key, _)])) =
182+ case gParseSum opts keyVal of
171183 Nothing -> notFound $ unpack key
172184 Just p -> p
173− gParseJSON v = typeMismatch "sum (:+:)" v
185+ gParseJSON _opts v = typeMismatch "sum (:+:)" v
174186 {-# INLINE gParseJSON #-}
175187
176188notFound :: String -> Parser a
@@ -179,18 +191,21 @@ notFound key = fail $ "The key \"" ++ key ++ "\" was not found"
179191
180192--------------------------------------------------------------------------------
181193
182−class ConsFromJSON f where consParseJSON :: Value -> Parser (f a)
183−class ConsFromJSON' b f where consParseJSON' :: Tagged b (Value -> Parser (f a))
194+class ConsFromJSON f where
195+ consParseJSON :: Options -> Value -> Parser (f a)
196+class ConsFromJSON' b f where
197+ consParseJSON' :: Tagged b (Options -> Value -> Parser (f a))
184198
185199instance (IsRecord f b, ConsFromJSON' b f) => ConsFromJSON f where
186− consParseJSON = unTagged (consParseJSON' :: Tagged b (Value -> Parser (f a)))
200+ consParseJSON =
201+ unTagged (consParseJSON' :: Tagged b (Options -> Value -> Parser (f a)))
187202 {-# INLINE consParseJSON #-}
188203
189204instance (GFromRecord f) => ConsFromJSON' True f where
190205 consParseJSON' = Tagged parseRecord
191206 where
192− parseRecord (Object obj) = gParseRecord obj
193− parseRecord v = typeMismatch "record (:*:)" v
207+ parseRecord opts (Object obj) = gParseRecord opts obj
208+ parseRecord _opts v = typeMismatch "record (:*:)" v
194209 {-# INLINE consParseJSON' #-}
195210
196211instance (GFromJSON f) => ConsFromJSON' False f where
@@ -200,16 +215,18 @@ instance (GFromJSON f) => ConsFromJSON' False f where
200215--------------------------------------------------------------------------------
201216
202217class GFromRecord f where
203− gParseRecord :: Object -> Parser (f a)
218+ gParseRecord :: Options -> Object -> Parser (f a)
204219
205220instance (GFromRecord a, GFromRecord b) => GFromRecord (a :*: b) where
206− gParseRecord obj = (:*:) <$> gParseRecord obj <*> gParseRecord obj
221+ gParseRecord opts obj = (:*:) <$> gParseRecord opts obj
222+ <*> gParseRecord opts obj
207223 {-# INLINE gParseRecord #-}
208224
209225instance (Selector s, GFromJSON a) => GFromRecord (S1 s a) where
210− gParseRecord = maybe (notFound key) gParseJSON . H.lookup (T.pack key)
226+ gParseRecord opts = maybe (notFound key) (gParseJSON opts)
227+ . H.lookup (T.pack key)
211228 where
212− key = selName (undefined :: t s a p)
229+ key = fieldNameModifier opts $ selName (undefined :: t s a p)
213230 {-# INLINE gParseRecord #-}
214231
215232--------------------------------------------------------------------------------
@@ -229,11 +246,12 @@ instance ProductSize (S1 s a) where
229246--------------------------------------------------------------------------------
230247
231248class GFromProduct f where
232− gParseProduct :: Array -> Int -> Int -> Parser (f a)
249+ gParseProduct :: Options -> Array -> Int -> Int -> Parser (f a)
233250
234251instance (GFromProduct a, GFromProduct b) => GFromProduct (a :*: b) where
235− gParseProduct arr ix len = (:*:) <$> gParseProduct arr ix lenL
236− <*> gParseProduct arr ixR lenR
252+ gParseProduct opts arr ix len =
253+ (:*:) <$> gParseProduct opts arr ix lenL
254+ <*> gParseProduct opts arr ixR lenR
237255 where
238256 lenL = len `shiftR` 1
239257 ixR = ix + lenL
@@ -241,22 +259,25 @@ instance (GFromProduct a, GFromProduct b) => GFromProduct (a :*: b) where
241259 {-# INLINE gParseProduct #-}
242260
243261instance (GFromJSON a) => GFromProduct (S1 s a) where
244− gParseProduct arr ix _ = gParseJSON $ V.unsafeIndex arr ix
262+ gParseProduct opts arr ix _ = gParseJSON opts $ V.unsafeIndex arr ix
245263 {-# INLINE gParseProduct #-}
246264
247265--------------------------------------------------------------------------------
248266
249267class GFromSum f where
250− gParseSum :: Pair -> Maybe (Parser (f a))
268+ gParseSum :: Options -> Pair -> Maybe (Parser (f a))
251269
252270instance (GFromSum a, GFromSum b) => GFromSum (a :+: b) where
253− gParseSum keyVal = (fmap L1 <$> gParseSum keyVal) <|>
254− (fmap R1 <$> gParseSum keyVal)
271+ gParseSum opts keyVal = (fmap L1 <$> gParseSum opts keyVal) <|>
272+ (fmap R1 <$> gParseSum opts keyVal)
255273 {-# INLINE gParseSum #-}
256274
257275instance (Constructor c, GFromJSON a, ConsFromJSON a) => GFromSum (C1 c a) where
258− gParseSum (key, value)
259− | key == pack (conName (undefined :: t c a p)) = Just $ gParseJSON value
276+ gParseSum opts (key, value)
277+ | key == pack ( constructorNameModifier opts
278+ $ conName (undefined :: t c a p)
279+ )
280+ = Just $ gParseJSON opts value
260281 | otherwise = Nothing
261282 {-# INLINE gParseSum #-}
262283