on master help sign in
Parameterize the gParseJSON and gToJSON with encoding Options
commit2e9f2face88649da7596008e04ca6e89c399bb1d authorBas van Dijk <v.dijk.bas@gmail.com> dateFri 18 Jan 2013, 19:10 (14 years ago) parentb8e917e
6 files changed+187−128
Data/Aeson.hs+7 Data/Aeson/TH.hs+10−71 Data/Aeson/Types.hs+12 Data/Aeson/Types/Class.hs+10−4 Data/Aeson/Types/Generic.hs+74−53 Data/Aeson/Types/Internal.hs+74
Data/Aeson.hs+7
@@ -1,3 +1,5 @@
1+{-# LANGUAGE CPP #-}
2+
13-- |
24-- Module: Data.Aeson
35-- Copyright: (c) 2011, 2012 Bryan O'Sullivan
@@ -49,6 +51,11 @@ module Data.Aeson
4951 , Result(..)
5052 , fromJSON
5153 , ToJSON(..)
54+#ifdef GENERICS
55+ -- ** Generic JSON classes
56+ , GFromJSON(..)
57+ , GToJSON(..)
58+#endif
5259 -- * Inspecting @'Value's@
5360 , withObject
5461 , withText
Data/Aeson/TH.hs+10−71
@@ -59,8 +59,10 @@ $('deriveJSON' 'defaultOptions' ''(,,,))
5959-}
6060
6161module Data.Aeson.TH
62− ( Options(..), SumEncoding(..), defaultOptions, defaultObjectWithType
62+ ( -- * Encoding configuration
63+ Options(..), SumEncoding(..), defaultOptions, defaultObjectWithType
6364
65+ -- * FromJSON and ToJSON derivation
6466 , deriveJSON
6567
6668 , deriveToJSON
@@ -79,13 +81,18 @@ import Data.Aeson ( toJSON, Object, object, (.=), (.:), (.:?)
7981 , ToJSON, toJSON
8082 , FromJSON, parseJSON
8183 )
82−import Data.Aeson.Types ( Value(..), Parser )
84+import Data.Aeson.Types ( Value(..), Parser
85+ , Options(..)
86+ , SumEncoding(..)
87+ , defaultOptions
88+ , defaultObjectWithType
89+ )
8390-- from base:
8491import Control.Applicative ( pure, (<$>), (<*>) )
8592import Control.Monad ( return, mapM, liftM2, fail )
8693import Data.Bool ( Bool(False, True), otherwise, (&&) )
8794import Data.Eq ( (==) )
88−import Data.Function ( ($), (.), id )
95+import Data.Function ( ($), (.) )
8996import Data.Functor ( fmap )
9097import Data.Int ( Int )
9198import Data.Either ( Either(Left, Right) )
@@ -112,74 +119,6 @@ import qualified Data.Vector as V ( unsafeIndex, null, length, create, fromList
112119import qualified Data.Vector.Mutable as VM ( unsafeNew, unsafeWrite )
113120
114121
115−--------------------------------------------------------------------------------
116−-- Configuration
117−--------------------------------------------------------------------------------
118−
119−-- | Options that specify how to encode your datatype to JSON.
120−data Options = Options
121− { fieldNameModifier :: String -> String
122− -- ^ Function applied to field names.
123− -- Handy for removing common record prefixes for example.
124− , constructorNameModifier :: String -> String
125− -- ^ Function applied to constructor names.
126− -- Handy for lower-casing constructor names for example.
127− , nullaryToString :: Bool
128− -- ^ If 'True' the constructors of a datatypes, with all nullary
129− -- constructors, will be encoded to a string with the
130− -- constructor name. If 'False' the encoding will always follow
131− -- the `sumEncoding`.
132− , sumEncoding :: SumEncoding
133− -- ^ Specifies how to encode constructors of a sum datatype.
134− }
135−
136−-- | Specifies how to encode constructors of a sum datatype.
137−data SumEncoding =
138− TwoElemArray -- ^ A constructor will be encoded to a 2-element
139− -- array where the first element is the name of the
140− -- constructor (modified by the
141− -- 'constructorNameModifier') and the second element
142− -- the content of the constructor.
143− | ObjectWithType { typeFieldName :: String
144− , valueFieldName :: String
145− }
146− -- ^ A constructor will be encoded to an object with a field
147− -- 'typeFieldName' which specifies the constructor name (modified
148− -- by the 'constructorNameModifier'). If the constructor is not a
149− -- record the constructor content will be stored under the
150− -- 'valueFieldName' field.
151− | ObjectWithSingleField
152− -- ^ A constructor will be encoded to an object with a single
153− -- field named after the constructor (modified by the
154− -- 'constructorNameModifier') and the value will be the contents
155− -- of the constructor.
156−
157−-- | Default encoding options which specify to not modify field and
158−-- constructor names, encode the constructors of a datatype with all
159−-- nullary constructors to just strings with the name of the
160−-- constructor and use a 2-element array for other sum datatypes.
161−defaultOptions :: Options
162−defaultOptions = Options
163− { fieldNameModifier = id
164− , constructorNameModifier = id
165− , nullaryToString = True
166− , sumEncoding = TwoElemArray
167− }
168−
169−-- | Note that:
170−--
171−-- @
172−-- defaultObjectWithType = 'ObjectWithType'
173−-- { 'typeFieldName' = \"type\"
174−-- , 'valueFieldName' = \"value\"
175−-- }
176−-- @
177−defaultObjectWithType :: SumEncoding
178−defaultObjectWithType = ObjectWithType
179− { typeFieldName = "type"
180− , valueFieldName = "value"
181− }
182−
183122--------------------------------------------------------------------------------
184123-- Convenience
185124--------------------------------------------------------------------------------
Data/Aeson/Types.hs+12
@@ -34,6 +34,12 @@ module Data.Aeson.Types
3434 , ToJSON(..)
3535 , modifyFailure
3636
37+#ifdef GENERICS
38+ -- ** Generic JSON classes
39+ , GFromJSON(..)
40+ , GToJSON(..)
41+#endif
42+
3743 -- * Inspecting @'Value's@
3844 , withObject
3945 , withText
@@ -47,6 +53,12 @@ module Data.Aeson.Types
4753 , (.:?)
4854 , (.!=)
4955 , object
56+
57+ -- * Generic and TH encoding configuration
58+ , Options(..)
59+ , SumEncoding(..)
60+ , defaultOptions
61+ , defaultObjectWithType
5062 ) where
5163
5264import Data.Aeson.Types.Class
Data/Aeson/Types/Class.hs+10−4
@@ -88,11 +88,17 @@ import qualified Data.Vector.Mutable as VM ( unsafeNew, unsafeWrite )
8888#ifdef GENERICS
8989import GHC.Generics
9090
91+-- | Class of generic representation types ('Rep') that can be converted to JSON.
9192class GToJSON f where
92− gToJSON :: f a -> Value
93+ -- | This method (applied to 'defaultOptions') is used as the
94+ -- default generic implementation of 'toJSON'.
95+ gToJSON :: Options -> f a -> Value
9396
97+-- | Class of generic representation types ('Rep') that can be converted from JSON.
9498class GFromJSON f where
95− gParseJSON :: Value -> Parser (f a)
99+ -- | This method (applied to 'defaultOptions') is used as the
100+ -- default generic implementation of 'parseJSON'.
101+ gParseJSON :: Options -> Value -> Parser (f a)
96102#endif
97103
98104-- | A type that can be converted to JSON.
@@ -143,7 +149,7 @@ class ToJSON a where
143149
144150#ifdef GENERICS
145151 default toJSON :: (Generic a, GToJSON (Rep a)) => a -> Value
146− toJSON = gToJSON . from
152+ toJSON = gToJSON defaultOptions . from
147153#endif
148154
149155-- | A type that can be converted from JSON, with the possibility of
@@ -204,7 +210,7 @@ class FromJSON a where
204210
205211#ifdef GENERICS
206212 default parseJSON :: (Generic a, GFromJSON (Rep a)) => Value -> Parser a
207− parseJSON = fmap to . gParseJSON
213+ parseJSON = fmap to . gParseJSON defaultOptions
208214#endif
209215
210216instance (ToJSON a) => ToJSON (Maybe a) where
Data/Aeson/Types/Generic.hs+74−53
@@ -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
Data/Aeson/Types/Internal.hs+74
@@ -29,6 +29,12 @@ module Data.Aeson.Types.Internal
2929 , modifyFailure
3030 -- * Constructors and accessors
3131 , object
32+
33+ -- * Generic and TH encoding configuration
34+ , Options(..)
35+ , SumEncoding(..)
36+ , defaultOptions
37+ , defaultObjectWithType
3238 ) where
3339
3440import Control.Applicative
@@ -238,3 +244,71 @@ object = Object . H.fromList
238244-- Since 0.6.2.0
239245modifyFailure :: (String -> String) -> Parser a -> Parser a
240246modifyFailure f (Parser p) = Parser $ \kf -> p (kf . f)
247+
248+--------------------------------------------------------------------------------
249+-- Generic and TH encoding configuration
250+--------------------------------------------------------------------------------
251+
252+-- | Options that specify how to encode your datatype to JSON.
253+data Options = Options
254+ { fieldNameModifier :: String -> String
255+ -- ^ Function applied to field names.
256+ -- Handy for removing common record prefixes for example.
257+ , constructorNameModifier :: String -> String
258+ -- ^ Function applied to constructor names.
259+ -- Handy for lower-casing constructor names for example.
260+ , nullaryToString :: Bool
261+ -- ^ If 'True' the constructors of a datatypes, with all nullary
262+ -- constructors, will be encoded to a string with the
263+ -- constructor name. If 'False' the encoding will always follow
264+ -- the `sumEncoding`.
265+ , sumEncoding :: SumEncoding
266+ -- ^ Specifies how to encode constructors of a sum datatype.
267+ }
268+
269+-- | Specifies how to encode constructors of a sum datatype.
270+data SumEncoding =
271+ TwoElemArray -- ^ A constructor will be encoded to a 2-element
272+ -- array where the first element is the name of the
273+ -- constructor (modified by the
274+ -- 'constructorNameModifier') and the second element
275+ -- the content of the constructor.
276+ | ObjectWithType { typeFieldName :: String
277+ , valueFieldName :: String
278+ }
279+ -- ^ A constructor will be encoded to an object with a field
280+ -- 'typeFieldName' which specifies the constructor name (modified
281+ -- by the 'constructorNameModifier'). If the constructor is not a
282+ -- record the constructor content will be stored under the
283+ -- 'valueFieldName' field.
284+ | ObjectWithSingleField
285+ -- ^ A constructor will be encoded to an object with a single
286+ -- field named after the constructor (modified by the
287+ -- 'constructorNameModifier') and the value will be the contents
288+ -- of the constructor.
289+
290+-- | Default encoding options which specify to not modify field and
291+-- constructor names, encode the constructors of a datatype with all
292+-- nullary constructors to just strings with the name of the
293+-- constructor and use a 2-element array for other sum datatypes.
294+defaultOptions :: Options
295+defaultOptions = Options
296+ { fieldNameModifier = id
297+ , constructorNameModifier = id
298+ , nullaryToString = True
299+ , sumEncoding = TwoElemArray
300+ }
301+
302+-- | Note that:
303+--
304+-- @
305+-- defaultObjectWithType = 'ObjectWithType'
306+-- { 'typeFieldName' = \"type\"
307+-- , 'valueFieldName' = \"value\"
308+-- }
309+-- @
310+defaultObjectWithType :: SumEncoding
311+defaultObjectWithType = ObjectWithType
312+ { typeFieldName = "type"
313+ , valueFieldName = "value"
314+ }