on master help sign in
Let there be type safety for direct encoding!
10a76eaBryan O'Sullivan
Data/Aeson.hs+2
@@ -45,6 +45,8 @@ module Data.Aeson
45 , eitherDecodeStrict'
45 , eitherDecodeStrict'
46 -- * Core JSON types
46 -- * Core JSON types
47 , Value(..)
47 , Value(..)
48+ , Encoding
49+ , fromEncoding
48 , Array
50 , Array
49 , Object
51 , Object
50 -- * Convenience types
52 -- * Convenience types
Data/Aeson/Encode/ByteString.hs+10−9
@@ -34,7 +34,7 @@ module Data.Aeson.Encode.ByteString
34 ) where
34 ) where
35
35
36import Data.Aeson.Types.Class (ToJSON(..))
36import Data.Aeson.Types.Class (ToJSON(..))
37−import Data.Aeson.Types.Internal (Value(..), Series(..))
37+import Data.Aeson.Types.Internal (Encoding(..), Series(..), Value(..))
38import Data.ByteString.Builder as B
38import Data.ByteString.Builder as B
39import Data.ByteString.Builder.Prim as BP
39import Data.ByteString.Builder.Prim as BP
40import Data.ByteString.Builder.Scientific (scientificBuilder)
40import Data.ByteString.Builder.Scientific (scientificBuilder)
@@ -128,18 +128,19 @@ number s
128 where
128 where
129 e = base10Exponent s
129 e = base10Exponent s
130
130
131−foldable :: (Foldable t, ToJSON a) => t a -> Builder
131+foldable :: (Foldable t, ToJSON a) => t a -> Encoding
132foldable = series '[' ']' . foldMap (Value . toEncoding)
132foldable = series '[' ']' . foldMap (Value . toEncoding)
133
133
134−series :: Char -> Char -> Series -> Builder
134+series :: Char -> Char -> Series -> Encoding
135−series begin end (Value v) = B.char7 begin <> v <> B.char7 end
135+series begin end (Value v) = Encoding $
136+ B.char7 begin <> fromEncoding v <> B.char7 end
136−series begin end Empty = BP.primBounded (ascii2 (begin,end)) ()
137+series begin end Empty = Encoding (BP.primBounded (ascii2 (begin,end)) ())
137
138
138−emptyArray_ :: Builder
139+emptyArray_ :: Encoding
139−emptyArray_ = BP.primBounded (ascii2 ('[',']')) ()
140+emptyArray_ = Encoding (BP.primBounded (ascii2 ('[',']')) ())
140
141
141−emptyObject_ :: Builder
142+emptyObject_ :: Encoding
142−emptyObject_ = BP.primBounded (ascii2 ('{','}')) ()
143+emptyObject_ = Encoding (BP.primBounded (ascii2 ('{','}')) ())
143
144
144ascii2 :: (Char, Char) -> BP.BoundedPrim a
145ascii2 :: (Char, Char) -> BP.BoundedPrim a
145ascii2 cs = BP.liftFixedToBounded $ (const cs) BP.>$< BP.char7 >*< BP.char7
146ascii2 cs = BP.liftFixedToBounded $ (const cs) BP.>$< BP.char7 >*< BP.char7
Data/Aeson/Types.hs+1
@@ -14,6 +14,7 @@ module Data.Aeson.Types
14 -- * Core JSON types
14 -- * Core JSON types
15 Value(..)
15 Value(..)
16 , Encoding
16 , Encoding
17+ , fromEncoding
17 , Array
18 , Array
18 , emptyArray
19 , emptyArray
19 , Pair
20 , Pair
Data/Aeson/Types/Generic.hs+24−22
@@ -69,7 +69,7 @@ instance (ConsToJSON a) => GToJSON (C1 c a) where
69 gToJSON opts = consToJSON opts . unM1
69 gToJSON opts = consToJSON opts . unM1
70 {-# INLINE gToJSON #-}
70 {-# INLINE gToJSON #-}
71
71
72− gToEncoding opts = consToEncoding opts . unM1
72+ gToEncoding opts = Encoding . consToEncoding opts . unM1
73 {-# INLINE gToEncoding #-}
73 {-# INLINE gToEncoding #-}
74
74
75instance ( WriteProduct a, WriteProduct b
75instance ( WriteProduct a, WriteProduct b
@@ -87,7 +87,8 @@ instance ( WriteProduct a, WriteProduct b
87 productSize
87 productSize
88 {-# INLINE gToJSON #-}
88 {-# INLINE gToJSON #-}
89
89
90+ gToEncoding opts p = Encoding $
90− gToEncoding opts p = B.char7 '[' <> encodeProduct opts p <> B.char7 ']'
91+ B.char7 '[' <> encodeProduct opts p <> B.char7 ']'
91
92
92instance ( AllNullary (a :+: b) allNullary
93instance ( AllNullary (a :+: b) allNullary
93 , SumToJSON (a :+: b) allNullary ) => GToJSON (a :+: b) where
94 , SumToJSON (a :+: b) allNullary ) => GToJSON (a :+: b) where
@@ -98,8 +99,9 @@ instance ( AllNullary (a :+: b) allNullary
98 . sumToJSON opts
99 . sumToJSON opts
99 {-# INLINE gToJSON #-}
100 {-# INLINE gToJSON #-}
100
101
102+ gToEncoding opts = Encoding .
101− gToEncoding opts = (unTagged :: Tagged allNullary B.Builder -> B.Builder)
103+ (unTagged :: Tagged allNullary B.Builder -> B.Builder) .
102− . sumToEncoding opts
104+ sumToEncoding opts
103 {-# INLINE gToEncoding #-}
105 {-# INLINE gToEncoding #-}
104
106
105--------------------------------------------------------------------------------
107--------------------------------------------------------------------------------
@@ -119,7 +121,7 @@ instance ( GetConName f
119 {-# INLINE sumToJSON #-}
121 {-# INLINE sumToJSON #-}
120
122
121 sumToEncoding opts
123 sumToEncoding opts
122− | allNullaryToStringTag opts = Tagged . toEncoding .
124+ | allNullaryToStringTag opts = Tagged . builder .
123 constructorTagModifier opts . getConName
125 constructorTagModifier opts . getConName
124 | otherwise = Tagged . nonAllNullarySumToEncoding opts
126 | otherwise = Tagged . nonAllNullarySumToEncoding opts
125 {-# INLINE sumToEncoding #-}
127 {-# INLINE sumToEncoding #-}
@@ -188,9 +190,9 @@ instance ( IsRecord a isRecord
188
190
189 taggedObjectEnc opts tagFieldName contentsFieldName v =
191 taggedObjectEnc opts tagFieldName contentsFieldName v =
190 B.char7 '{' <>
192 B.char7 '{' <>
191− (toEncoding tagFieldName <>
193+ (builder tagFieldName <>
192 B.char7 ':' <>
194 B.char7 ':' <>
193− toEncoding (constructorTagModifier opts (conName (undefined :: t c a p)))) <>
195+ builder (constructorTagModifier opts (conName (undefined :: t c a p)))) <>
194 B.char7 ',' <>
196 B.char7 ',' <>
195 ((unTagged :: Tagged isRecord B.Builder -> B.Builder) .
197 ((unTagged :: Tagged isRecord B.Builder -> B.Builder) .
196 taggedObjectEnc' opts contentsFieldName . unM1 $ v) <>
198 taggedObjectEnc' opts contentsFieldName . unM1 $ v) <>
@@ -214,8 +216,8 @@ instance (GToJSON f) => TaggedObject' f False where
214 {-# INLINE taggedObjectPairs' #-}
216 {-# INLINE taggedObjectPairs' #-}
215
217
216 taggedObjectEnc' opts contentsFieldName =
218 taggedObjectEnc' opts contentsFieldName =
217− Tagged . (\z -> toEncoding contentsFieldName <> B.char7 ':' <> z) .
219+ Tagged . (\z -> builder contentsFieldName <> B.char7 ':' <> z) .
218− gToEncoding opts
220+ gbuilder opts
219 {-# INLINE taggedObjectEnc' #-}
221 {-# INLINE taggedObjectEnc' #-}
220
222
221--------------------------------------------------------------------------------
223--------------------------------------------------------------------------------
@@ -258,12 +260,9 @@ instance ( GToJSON a, ConsToJSON a
258 return mv
260 return mv
259 {-# INLINE twoElemArrayObj #-}
261 {-# INLINE twoElemArrayObj #-}
260
262
261− twoElemArrayEnc opts x =
263+ twoElemArrayEnc opts x = fromEncoding . tuple $
262− B.char7 '[' <>
263− toEncoding (constructorTagModifier opts (conName (undefined :: t c a p))) <>
264+ builder (constructorTagModifier opts (conName (undefined :: t c a p))) >*<
264− B.char7 ',' <>
265+ gbuilder opts x
265− gToEncoding opts x <>
266− B.char7 ']'
267 {-# INLINE twoElemArrayEnc #-}
266 {-# INLINE twoElemArrayEnc #-}
268
267
269--------------------------------------------------------------------------------
268--------------------------------------------------------------------------------
@@ -299,7 +298,7 @@ instance (RecordTo f) => ConsToJSON' f True where
299instance GToJSON f => ConsToJSON' f False where
298instance GToJSON f => ConsToJSON' f False where
300 consToJSON' opts = Tagged . gToJSON opts
299 consToJSON' opts = Tagged . gToJSON opts
301 {-# INLINE consToJSON' #-}
300 {-# INLINE consToJSON' #-}
302− consToEncoding' opts = Tagged . gToEncoding opts
301+ consToEncoding' opts = Tagged . gbuilder opts
303 {-# INLINE consToEncoding' #-}
302 {-# INLINE consToEncoding' #-}
304
303
305--------------------------------------------------------------------------------
304--------------------------------------------------------------------------------
@@ -344,9 +343,9 @@ fieldToPair opts m1 = pure ( pack $ fieldLabelModifier opts $ selName m1
344
343
345fieldToEncoding :: (Selector s, GToJSON a) => Options -> S1 s a p -> B.Builder
344fieldToEncoding :: (Selector s, GToJSON a) => Options -> S1 s a p -> B.Builder
346fieldToEncoding opts m1 =
345fieldToEncoding opts m1 =
347− toEncoding (fieldLabelModifier opts $ selName m1) <>
346+ builder (fieldLabelModifier opts $ selName m1) <>
348 B.char7 ':' <>
347 B.char7 ':' <>
349− gToEncoding opts (unM1 m1)
348+ gbuilder opts (unM1 m1)
350{-# INLINE fieldToEncoding #-}
349{-# INLINE fieldToEncoding #-}
351
350
352--------------------------------------------------------------------------------
351--------------------------------------------------------------------------------
@@ -380,7 +379,7 @@ instance (GToJSON a) => WriteProduct a where
380 writeProduct opts mv ix _ = VM.unsafeWrite mv ix . gToJSON opts
379 writeProduct opts mv ix _ = VM.unsafeWrite mv ix . gToJSON opts
381 {-# INLINE writeProduct #-}
380 {-# INLINE writeProduct #-}
382
381
383− encodeProduct opts = gToEncoding opts
382+ encodeProduct opts = gbuilder opts
384 {-# INLINE encodeProduct #-}
383 {-# INLINE encodeProduct #-}
385
384
386--------------------------------------------------------------------------------
385--------------------------------------------------------------------------------
@@ -409,13 +408,16 @@ instance ( GToJSON a, ConsToJSON a
409
408
410 objectWithSingleFieldEnc opts v =
409 objectWithSingleFieldEnc opts v =
411 B.char7 '{' <>
410 B.char7 '{' <>
412− toEncoding (constructorTagModifier opts
411+ builder (constructorTagModifier opts
413− (conName (undefined :: t c a p))) <>
412+ (conName (undefined :: t c a p))) <>
414 B.char7 ':' <>
413 B.char7 ':' <>
415− gToEncoding opts v <>
414+ gbuilder opts v <>
416 B.char7 '}'
415 B.char7 '}'
417 {-# INLINE objectWithSingleFieldEnc #-}
416 {-# INLINE objectWithSingleFieldEnc #-}
418
417
418+gbuilder :: GToJSON f => Options -> f a -> Builder
419+gbuilder opts = fromEncoding . gToEncoding opts
420+
419--------------------------------------------------------------------------------
421--------------------------------------------------------------------------------
420-- Generic parseJSON
422-- Generic parseJSON
421
423
Data/Aeson/Types/Instances.hs+202−181
@@ -47,14 +47,16 @@ module Data.Aeson.Types.Instances
47 , (.:)
47 , (.:)
48 , (.:?)
48 , (.:?)
49 , (.!=)
49 , (.!=)
50+ , builder
50 , series
51 , series
52+ , tuple
53+ , (>*<)
51 , typeMismatch
54 , typeMismatch
52 ) where
55 ) where
53
56
54import Control.Applicative ((<$>), (<*>), (<|>), pure, empty)
57import Control.Applicative ((<$>), (<*>), (<|>), pure, empty)
55import qualified Data.Aeson.Encode.ByteString as E
58import qualified Data.Aeson.Encode.ByteString as E
56import qualified Data.ByteString.Builder as B
59import qualified Data.ByteString.Builder as B
57−import qualified Data.ByteString.Builder.Prim as BP
58import Data.Aeson.Functions
60import Data.Aeson.Functions
59import Data.Monoid ((<>), mempty)
61import Data.Monoid ((<>), mempty)
60import Data.Aeson.Types.Class
62import Data.Aeson.Types.Class
@@ -122,7 +124,7 @@ instance (ToJSON a) => ToJSON (Maybe a) where
122 {-# INLINE toJSON #-}
124 {-# INLINE toJSON #-}
123
125
124 toEncoding (Just a) = toEncoding a
126 toEncoding (Just a) = toEncoding a
125− toEncoding Nothing = E.null_
127+ toEncoding Nothing = Encoding E.null_
126
128
127instance (FromJSON a) => FromJSON (Maybe a) where
129instance (FromJSON a) => FromJSON (Maybe a) where
128 parseJSON Null = pure Nothing
130 parseJSON Null = pure Nothing
@@ -134,10 +136,14 @@ instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
134 toJSON (Right b) = object [right .= b]
136 toJSON (Right b) = object [right .= b]
135 {-# INLINE toJSON #-}
137 {-# INLINE toJSON #-}
136
138
137− toEncoding (Left a) =
139+ toEncoding (Left a) = Encoding $
138− B.shortByteString "{\"left\":" <> toEncoding a <> B.char7 '}'
140+ B.shortByteString "{\"left\":" <> builder a <> B.char7 '}'
139− toEncoding (Right a) =
141+ toEncoding (Right a) = Encoding $
140− B.shortByteString "{\"right\":" <> toEncoding a <> B.char7 '}'
142+ B.shortByteString "{\"right\":" <> builder a <> B.char7 '}'
143+
144+builder :: ToJSON a => a -> B.Builder
145+builder = fromEncoding . toEncoding
146+{-# INLINE builder #-}
141
147
142instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
148instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
143 parseJSON (Object (H.toList -> [(key, value)]))
149 parseJSON (Object (H.toList -> [(key, value)]))
@@ -157,7 +163,7 @@ instance ToJSON Bool where
157 toJSON = Bool
163 toJSON = Bool
158 {-# INLINE toJSON #-}
164 {-# INLINE toJSON #-}
159
165
160− toEncoding v = E.bool v
166+ toEncoding = Encoding . E.bool
161
167
162instance FromJSON Bool where
168instance FromJSON Bool where
163 parseJSON = withBool "Bool" pure
169 parseJSON = withBool "Bool" pure
@@ -180,7 +186,7 @@ instance ToJSON [Char] where
180 toJSON = String . T.pack
186 toJSON = String . T.pack
181 {-# INLINE toJSON #-}
187 {-# INLINE toJSON #-}
182
188
183− toEncoding = E.text . T.pack
189+ toEncoding = Encoding . E.text . T.pack
184
190
185instance FromJSON [Char] where
191instance FromJSON [Char] where
186 parseJSON = withText "String" $ pure . T.unpack
192 parseJSON = withText "String" $ pure . T.unpack
@@ -190,7 +196,7 @@ instance ToJSON Char where
190 toJSON = String . T.singleton
196 toJSON = String . T.singleton
191 {-# INLINE toJSON #-}
197 {-# INLINE toJSON #-}
192
198
193− toEncoding = E.text . T.singleton
199+ toEncoding = Encoding . E.text . T.singleton
194
200
195instance FromJSON Char where
201instance FromJSON Char where
196 parseJSON = withText "Char" $ \t ->
202 parseJSON = withText "Char" $ \t ->
@@ -203,7 +209,7 @@ instance ToJSON Scientific where
203 toJSON = Number
209 toJSON = Number
204 {-# INLINE toJSON #-}
210 {-# INLINE toJSON #-}
205
211
206− toEncoding v = E.number v
212+ toEncoding = Encoding . E.number
207 {-# INLINE toEncoding #-}
213 {-# INLINE toEncoding #-}
208
214
209instance FromJSON Scientific where
215instance FromJSON Scientific where
@@ -252,9 +258,9 @@ instance ToJSON (Ratio Integer) where
252 , "denominator" .= denominator r
258 , "denominator" .= denominator r
253 ]
259 ]
254
260
255− toEncoding r =
261+ toEncoding r = Encoding $
256− B.shortByteString "{\"numerator\":" <> toEncoding (numerator r) <>
262+ B.shortByteString "{\"numerator\":" <> builder (numerator r) <>
257− B.shortByteString ",\"denominator\":" <> toEncoding (denominator r) <>
263+ B.shortByteString ",\"denominator\":" <> builder (denominator r) <>
258 B.char7 '}'
264 B.char7 '}'
259
265
260instance FromJSON (Ratio Integer) where
266instance FromJSON (Ratio Integer) where
@@ -267,7 +273,7 @@ instance HasResolution a => ToJSON (Fixed a) where
267 toJSON = Number . realToFrac
273 toJSON = Number . realToFrac
268 {-# INLINE toJSON #-}
274 {-# INLINE toJSON #-}
269
275
270− toEncoding = E.number . realToFrac
276+ toEncoding = Encoding . E.number . realToFrac
271
277
272-- | /WARNING:/ Only parse fixed-precision numbers from trusted input
278-- | /WARNING:/ Only parse fixed-precision numbers from trusted input
273-- since an attacker could easily fill up the memory of the target
279-- since an attacker could easily fill up the memory of the target
@@ -281,7 +287,7 @@ instance ToJSON Int where
281 toJSON = Number . fromIntegral
287 toJSON = Number . fromIntegral
282 {-# INLINE toJSON #-}
288 {-# INLINE toJSON #-}
283
289
284− toEncoding = B.intDec
290+ toEncoding = Encoding . B.intDec
285 {-# INLINE toEncoding #-}
291 {-# INLINE toEncoding #-}
286
292
287instance FromJSON Int where
293instance FromJSON Int where
@@ -292,7 +298,7 @@ instance ToJSON Integer where
292 toJSON = Number . fromInteger
298 toJSON = Number . fromInteger
293 {-# INLINE toJSON #-}
299 {-# INLINE toJSON #-}
294
300
295− toEncoding = B.integerDec
301+ toEncoding = Encoding . B.integerDec
296
302
297-- | /WARNING:/ Only parse Integers from trusted input since an
303-- | /WARNING:/ Only parse Integers from trusted input since an
298-- attacker could easily fill up the memory of the target system by
304-- attacker could easily fill up the memory of the target system by
@@ -306,7 +312,7 @@ instance ToJSON Int8 where
306 toJSON = Number . fromIntegral
312 toJSON = Number . fromIntegral
307 {-# INLINE toJSON #-}
313 {-# INLINE toJSON #-}
308
314
309− toEncoding = B.int8Dec
315+ toEncoding = Encoding . B.int8Dec
310
316
311instance FromJSON Int8 where
317instance FromJSON Int8 where
312 parseJSON = parseIntegral "Int8"
318 parseJSON = parseIntegral "Int8"
@@ -316,7 +322,7 @@ instance ToJSON Int16 where
316 toJSON = Number . fromIntegral
322 toJSON = Number . fromIntegral
317 {-# INLINE toJSON #-}
323 {-# INLINE toJSON #-}
318
324
319− toEncoding = B.int16Dec
325+ toEncoding = Encoding . B.int16Dec
320
326
321instance FromJSON Int16 where
327instance FromJSON Int16 where
322 parseJSON = parseIntegral "Int16"
328 parseJSON = parseIntegral "Int16"
@@ -326,7 +332,7 @@ instance ToJSON Int32 where
326 toJSON = Number . fromIntegral
332 toJSON = Number . fromIntegral
327 {-# INLINE toJSON #-}
333 {-# INLINE toJSON #-}
328
334
329− toEncoding = B.int32Dec
335+ toEncoding = Encoding . B.int32Dec
330
336
331instance FromJSON Int32 where
337instance FromJSON Int32 where
332 parseJSON = parseIntegral "Int32"
338 parseJSON = parseIntegral "Int32"
@@ -336,7 +342,7 @@ instance ToJSON Int64 where
336 toJSON = Number . fromIntegral
342 toJSON = Number . fromIntegral
337 {-# INLINE toJSON #-}
343 {-# INLINE toJSON #-}
338
344
339− toEncoding = B.int64Dec
345+ toEncoding = Encoding . B.int64Dec
340
346
341instance FromJSON Int64 where
347instance FromJSON Int64 where
342 parseJSON = parseIntegral "Int64"
348 parseJSON = parseIntegral "Int64"
@@ -346,7 +352,7 @@ instance ToJSON Word where
346 toJSON = Number . fromIntegral
352 toJSON = Number . fromIntegral
347 {-# INLINE toJSON #-}
353 {-# INLINE toJSON #-}
348
354
349− toEncoding = B.wordDec
355+ toEncoding = Encoding . B.wordDec
350
356
351instance FromJSON Word where
357instance FromJSON Word where
352 parseJSON = parseIntegral "Word"
358 parseJSON = parseIntegral "Word"
@@ -356,7 +362,7 @@ instance ToJSON Word8 where
356 toJSON = Number . fromIntegral
362 toJSON = Number . fromIntegral
357 {-# INLINE toJSON #-}
363 {-# INLINE toJSON #-}
358
364
359− toEncoding = B.word8Dec
365+ toEncoding = Encoding . B.word8Dec
360
366
361instance FromJSON Word8 where
367instance FromJSON Word8 where
362 parseJSON = parseIntegral "Word8"
368 parseJSON = parseIntegral "Word8"
@@ -366,7 +372,7 @@ instance ToJSON Word16 where
366 toJSON = Number . fromIntegral
372 toJSON = Number . fromIntegral
367 {-# INLINE toJSON #-}
373 {-# INLINE toJSON #-}
368
374
369− toEncoding = B.word16Dec
375+ toEncoding = Encoding . B.word16Dec
370
376
371instance FromJSON Word16 where
377instance FromJSON Word16 where
372 parseJSON = parseIntegral "Word16"
378 parseJSON = parseIntegral "Word16"
@@ -376,7 +382,7 @@ instance ToJSON Word32 where
376 toJSON = Number . fromIntegral
382 toJSON = Number . fromIntegral
377 {-# INLINE toJSON #-}
383 {-# INLINE toJSON #-}
378
384
379− toEncoding = B.word32Dec
385+ toEncoding = Encoding . B.word32Dec
380
386
381instance FromJSON Word32 where
387instance FromJSON Word32 where
382 parseJSON = parseIntegral "Word32"
388 parseJSON = parseIntegral "Word32"
@@ -386,7 +392,7 @@ instance ToJSON Word64 where
386 toJSON = Number . fromIntegral
392 toJSON = Number . fromIntegral
387 {-# INLINE toJSON #-}
393 {-# INLINE toJSON #-}
388
394
389− toEncoding = B.word64Dec
395+ toEncoding = Encoding . B.word64Dec
390
396
391instance FromJSON Word64 where
397instance FromJSON Word64 where
392 parseJSON = parseIntegral "Word64"
398 parseJSON = parseIntegral "Word64"
@@ -396,7 +402,7 @@ instance ToJSON Text where
396 toJSON = String
402 toJSON = String
397 {-# INLINE toJSON #-}
403 {-# INLINE toJSON #-}
398
404
399− toEncoding = E.text
405+ toEncoding = Encoding . E.text
400
406
401instance FromJSON Text where
407instance FromJSON Text where
402 parseJSON = withText "Text" pure
408 parseJSON = withText "Text" pure
@@ -406,7 +412,7 @@ instance ToJSON LT.Text where
406 toJSON = String . LT.toStrict
412 toJSON = String . LT.toStrict
407 {-# INLINE toJSON #-}
413 {-# INLINE toJSON #-}
408
414
409− toEncoding t =
415+ toEncoding t = Encoding $
410 B.char7 '"' <>
416 B.char7 '"' <>
411 LT.foldrChunks (\x xs -> E.unquoted x <> xs) mempty t <>
417 LT.foldrChunks (\x xs -> E.unquoted x <> xs) mempty t <>
412 B.char7 '"'
418 B.char7 '"'
@@ -420,11 +426,13 @@ instance (ToJSON a) => ToJSON [a] where
420 {-# INLINE toJSON #-}
426 {-# INLINE toJSON #-}
421
427
422 toEncoding [] = E.emptyArray_
428 toEncoding [] = E.emptyArray_
429+ toEncoding (x:xs) = Encoding $
423− toEncoding (x:xs) = B.char7 '[' <> toEncoding x <> commas xs <> B.char7 ']'
430+ B.char7 '[' <> builder x <> commas xs <> B.char7 ']'
424− where commas = P.foldr (\v vs -> B.char7 ',' <> toEncoding v <> vs) mempty
431+ where commas = P.foldr (\v vs -> B.char7 ',' <> builder v <> vs) mempty
425
432
426instance (FromJSON a) => FromJSON [a] where
433instance (FromJSON a) => FromJSON [a] where
434+ parseJSON = withArray "[a]" $ Tr.sequence .
427− parseJSON = withArray "[a]" $ Tr.sequence . zipWith parseIndexedJSON [0..] . V.toList
435+ zipWith parseIndexedJSON [0..] . V.toList
428 {-# INLINE parseJSON #-}
436 {-# INLINE parseJSON #-}
429
437
430instance (Foldable t, ToJSON a) => ToJSON (t a) where
438instance (Foldable t, ToJSON a) => ToJSON (t a) where
@@ -443,16 +451,18 @@ instance (ToJSON a) => ToJSON (Vector a) where
443
451
444 toEncoding = encodeVector
452 toEncoding = encodeVector
445
453
446−encodeVector :: (ToJSON a, VG.Vector v a) => v a -> B.Builder
454+encodeVector :: (ToJSON a, VG.Vector v a) => v a -> Encoding
447encodeVector xs
455encodeVector xs
448 | VG.null xs = E.emptyArray_
456 | VG.null xs = E.emptyArray_
457+ | otherwise = Encoding $
449− | otherwise = B.char7 '[' <> toEncoding (VG.unsafeHead xs) <>
458+ B.char7 '[' <> builder (VG.unsafeHead xs) <>
450 VG.foldr go mempty (VG.unsafeTail xs) <>
459 VG.foldr go mempty (VG.unsafeTail xs) <>
451 B.char7 ']'
460 B.char7 ']'
452− where go v b = B.char7 ',' <> toEncoding v <> b
461+ where go v b = B.char7 ',' <> builder v <> b
453
462
454instance (FromJSON a) => FromJSON (Vector a) where
463instance (FromJSON a) => FromJSON (Vector a) where
455− parseJSON = withArray "Vector a" $ V.mapM (uncurry parseIndexedJSON) . V.indexed
464+ parseJSON = withArray "Vector a" $ V.mapM (uncurry parseIndexedJSON) .
465+ V.indexed
456 {-# INLINE parseJSON #-}
466 {-# INLINE parseJSON #-}
457
467
458vectorToJSON :: (VG.Vector v a, ToJSON a) => v a -> Value
468vectorToJSON :: (VG.Vector v a, ToJSON a) => v a -> Value
@@ -516,14 +526,15 @@ instance ToJSON IntSet.IntSet where
516encodeSet :: (ToJSON a) =>
526encodeSet :: (ToJSON a) =>
517 (s -> Maybe (a, s))
527 (s -> Maybe (a, s))
518 -> ((a -> B.Builder -> B.Builder) -> B.Builder -> s -> B.Builder)
528 -> ((a -> B.Builder -> B.Builder) -> B.Builder -> s -> B.Builder)
519− -> s -> B.Builder
529+ -> s -> Encoding
520encodeSet minView foldr xs =
530encodeSet minView foldr xs =
521 case minView xs of
531 case minView xs of
522 Nothing -> E.emptyArray_
532 Nothing -> E.emptyArray_
523− Just (m,ys) -> B.char7 '[' <> toEncoding m <>
533+ Just (m,ys) -> Encoding $
534+ B.char7 '[' <> builder m <>
524 foldr go mempty ys <>
535 foldr go mempty ys <>
525 B.char7 ']'
536 B.char7 ']'
526− where go v b = B.char7 ',' <> toEncoding v <> b
537+ where go v b = B.char7 ',' <> builder v <> b
527
538
528instance FromJSON IntSet.IntSet where
539instance FromJSON IntSet.IntSet where
529 parseJSON = fmap IntSet.fromList . parseJSON
540 parseJSON = fmap IntSet.fromList . parseJSON
@@ -548,22 +559,23 @@ instance (ToJSON v) => ToJSON (M.Map Text v) where
548encodeMap :: (ToJSON k, ToJSON v) =>
559encodeMap :: (ToJSON k, ToJSON v) =>
549 (m -> Maybe ((k,v), m))
560 (m -> Maybe ((k,v), m))
550 -> ((k -> v -> B.Builder -> B.Builder) -> B.Builder -> m -> B.Builder)
561 -> ((k -> v -> B.Builder -> B.Builder) -> B.Builder -> m -> B.Builder)
551− -> m -> B.Builder
562+ -> m -> Encoding
552encodeMap minViewWithKey foldrWithKey xs =
563encodeMap minViewWithKey foldrWithKey xs =
553 case minViewWithKey xs of
564 case minViewWithKey xs of
554− Nothing -> BP.primBounded (E.ascii2 ('{','}')) ()
565+ Nothing -> E.emptyObject_
566+ Just ((k,v),ys) -> Encoding $
555− Just ((k,v),ys) -> B.char7 '{' <> encodePair k v <>
567+ B.char7 '{' <> encodePair k v <>
556 foldrWithKey go mempty ys <> B.char7 '}'
568 foldrWithKey go mempty ys <> B.char7 '}'
557 where go k v b = B.char7 ',' <> encodePair k v <> b
569 where go k v b = B.char7 ',' <> encodePair k v <> b
558
570
559encodeWithKey :: (ToJSON k, ToJSON v) =>
571encodeWithKey :: (ToJSON k, ToJSON v) =>
560 ((k -> v -> Series -> Series) -> Series -> m -> Series)
572 ((k -> v -> Series -> Series) -> Series -> m -> Series)
561− -> m -> B.Builder
573+ -> m -> Encoding
562−encodeWithKey foldrWithKey xs = E.series '{' '}' . foldrWithKey go mempty $ xs
574+encodeWithKey foldrWithKey = E.series '{' '}' . foldrWithKey go mempty
563− where go k v c = Value (encodePair k v) <> c
575+ where go k v c = Value (Encoding $ encodePair k v) <> c
564
576
565encodePair :: (ToJSON k, ToJSON v) => k -> v -> B.Builder
577encodePair :: (ToJSON k, ToJSON v) => k -> v -> B.Builder
566−encodePair k v = toEncoding k <> B.char7 ':' <> toEncoding v
578+encodePair k v = builder k <> B.char7 ':' <> builder v
567
579
568instance (FromJSON v) => FromJSON (M.Map Text v) where
580instance (FromJSON v) => FromJSON (M.Map Text v) where
569 parseJSON = withObject "Map Text a" $
581 parseJSON = withObject "Map Text a" $
@@ -622,7 +634,7 @@ instance ToJSON Value where
622 toJSON a = a
634 toJSON a = a
623 {-# INLINE toJSON #-}
635 {-# INLINE toJSON #-}
624
636
625− toEncoding = E.encodeToBuilder
637+ toEncoding = Encoding . E.encodeToBuilder
626
638
627instance FromJSON Value where
639instance FromJSON Value where
628 parseJSON a = pure a
640 parseJSON a = pure a
@@ -718,6 +730,15 @@ instance FromJSON UTCTime where
718parseJSONElemAtIndex :: FromJSON a => Int -> Vector Value -> Parser a
730parseJSONElemAtIndex :: FromJSON a => Int -> Vector Value -> Parser a
719parseJSONElemAtIndex idx ary = parseJSON (V.unsafeIndex ary idx) <?> Index idx
731parseJSONElemAtIndex idx ary = parseJSON (V.unsafeIndex ary idx) <?> Index idx
720
732
733+tuple :: B.Builder -> Encoding
734+tuple b = Encoding (B.char7 '[' <> b <> B.char7 ']')
735+{-# INLINE tuple #-}
736+
737+(>*<) :: B.Builder -> B.Builder -> B.Builder
738+a >*< b = a <> B.char7 ',' <> b
739+{-# INLINE (>*<) #-}
740+infixr 6 >*<
741+
721instance (ToJSON a, ToJSON b) => ToJSON (a,b) where
742instance (ToJSON a, ToJSON b) => ToJSON (a,b) where
722 toJSON (a,b) = Array $ V.create $ do
743 toJSON (a,b) = Array $ V.create $ do
723 mv <- VM.unsafeNew 2
744 mv <- VM.unsafeNew 2
@@ -726,9 +747,8 @@ instance (ToJSON a, ToJSON b) => ToJSON (a,b) where
726 return mv
747 return mv
727 {-# INLINE toJSON #-}
748 {-# INLINE toJSON #-}
728
749
729− toEncoding (a,b) = B.char7 '[' <>
750+ toEncoding (a,b) = tuple $
730− toEncoding a <> B.char7 ',' <>
751+ builder a >*< builder b
731− toEncoding b <> B.char7 ']'
732
752
733instance (FromJSON a, FromJSON b) => FromJSON (a,b) where
753instance (FromJSON a, FromJSON b) => FromJSON (a,b) where
734 parseJSON = withArray "(a,b)" $ \ab ->
754 parseJSON = withArray "(a,b)" $ \ab ->
@@ -749,10 +769,10 @@ instance (ToJSON a, ToJSON b, ToJSON c) => ToJSON (a,b,c) where
749 return mv
769 return mv
750 {-# INLINE toJSON #-}
770 {-# INLINE toJSON #-}
751
771
752− toEncoding (a,b,c) = B.char7 '[' <>
772+ toEncoding (a,b,c) = tuple $
753− toEncoding a <> B.char7 ',' <>
773+ builder a >*<
754− toEncoding b <> B.char7 ',' <>
774+ builder b >*<
755− toEncoding c <> B.char7 ']'
775+ builder c
756
776
757instance (FromJSON a, FromJSON b, FromJSON c) => FromJSON (a,b,c) where
777instance (FromJSON a, FromJSON b, FromJSON c) => FromJSON (a,b,c) where
758 parseJSON = withArray "(a,b,c)" $ \abc ->
778 parseJSON = withArray "(a,b,c)" $ \abc ->
@@ -775,11 +795,11 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSON (a,b,c,d) where
775 return mv
795 return mv
776 {-# INLINE toJSON #-}
796 {-# INLINE toJSON #-}
777
797
778− toEncoding (a,b,c,d) = B.char7 '[' <>
798+ toEncoding (a,b,c,d) = tuple $
779− toEncoding a <> B.char7 ',' <>
799+ builder a >*<
780− toEncoding b <> B.char7 ',' <>
800+ builder b >*<
781− toEncoding c <> B.char7 ',' <>
801+ builder c >*<
782− toEncoding d <> B.char7 ']'
802+ builder d
783
803
784instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) =>
804instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) =>
785 FromJSON (a,b,c,d) where
805 FromJSON (a,b,c,d) where
@@ -806,12 +826,12 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e) =>
806 return mv
826 return mv
807 {-# INLINE toJSON #-}
827 {-# INLINE toJSON #-}
808
828
809− toEncoding (a,b,c,d,e) = B.char7 '[' <>
829+ toEncoding (a,b,c,d,e) = tuple $
810− toEncoding a <> B.char7 ',' <>
830+ builder a >*<
811− toEncoding b <> B.char7 ',' <>
831+ builder b >*<
812− toEncoding c <> B.char7 ',' <>
832+ builder c >*<
813− toEncoding d <> B.char7 ',' <>
833+ builder d >*<
814− toEncoding e <> B.char7 ']'
834+ builder e
815
835
816instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e) =>
836instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e) =>
817 FromJSON (a,b,c,d,e) where
837 FromJSON (a,b,c,d,e) where
@@ -840,13 +860,13 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f) =>
840 return mv
860 return mv
841 {-# INLINE toJSON #-}
861 {-# INLINE toJSON #-}
842
862
843− toEncoding (a,b,c,d,e,f) = B.char7 '[' <>
863+ toEncoding (a,b,c,d,e,f) = tuple $
844− toEncoding a <> B.char7 ',' <>
864+ builder a >*<
845− toEncoding b <> B.char7 ',' <>
865+ builder b >*<
846− toEncoding c <> B.char7 ',' <>
866+ builder c >*<
847− toEncoding d <> B.char7 ',' <>
867+ builder d >*<
848− toEncoding e <> B.char7 ',' <>
868+ builder e >*<
849− toEncoding f <> B.char7 ']'
869+ builder f
850
870
851instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
871instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
852 FromJSON f) => FromJSON (a,b,c,d,e,f) where
872 FromJSON f) => FromJSON (a,b,c,d,e,f) where
@@ -877,14 +897,14 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
877 return mv
897 return mv
878 {-# INLINE toJSON #-}
898 {-# INLINE toJSON #-}
879
899
880− toEncoding (a,b,c,d,e,f,g) = B.char7 '[' <>
900+ toEncoding (a,b,c,d,e,f,g) = tuple $
881− toEncoding a <> B.char7 ',' <>
901+ builder a >*<
882− toEncoding b <> B.char7 ',' <>
902+ builder b >*<
883− toEncoding c <> B.char7 ',' <>
903+ builder c >*<
884− toEncoding d <> B.char7 ',' <>
904+ builder d >*<
885− toEncoding e <> B.char7 ',' <>
905+ builder e >*<
886− toEncoding f <> B.char7 ',' <>
906+ builder f >*<
887− toEncoding g <> B.char7 ']'
907+ builder g
888
908
889instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
909instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
890 FromJSON f, FromJSON g) => FromJSON (a,b,c,d,e,f,g) where
910 FromJSON f, FromJSON g) => FromJSON (a,b,c,d,e,f,g) where
@@ -917,15 +937,15 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
917 return mv
937 return mv
918 {-# INLINE toJSON #-}
938 {-# INLINE toJSON #-}
919
939
920− toEncoding (a,b,c,d,e,f,g,h) = B.char7 '[' <>
940+ toEncoding (a,b,c,d,e,f,g,h) = tuple $
921− toEncoding a <> B.char7 ',' <>
941+ builder a >*<
922− toEncoding b <> B.char7 ',' <>
942+ builder b >*<
923− toEncoding c <> B.char7 ',' <>
943+ builder c >*<
924− toEncoding d <> B.char7 ',' <>
944+ builder d >*<
925− toEncoding e <> B.char7 ',' <>
945+ builder e >*<
926− toEncoding f <> B.char7 ',' <>
946+ builder f >*<
927− toEncoding g <> B.char7 ',' <>
947+ builder g >*<
928− toEncoding h <> B.char7 ']'
948+ builder h
929
949
930instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
950instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
931 FromJSON f, FromJSON g, FromJSON h) =>
951 FromJSON f, FromJSON g, FromJSON h) =>
@@ -962,16 +982,16 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
962 return mv
982 return mv
963 {-# INLINE toJSON #-}
983 {-# INLINE toJSON #-}
964
984
965− toEncoding (a,b,c,d,e,f,g,h,i) = B.char7 '[' <>
985+ toEncoding (a,b,c,d,e,f,g,h,i) = tuple $
966− toEncoding a <> B.char7 ',' <>
986+ builder a >*<
967− toEncoding b <> B.char7 ',' <>
987+ builder b >*<
968− toEncoding c <> B.char7 ',' <>
988+ builder c >*<
969− toEncoding d <> B.char7 ',' <>
989+ builder d >*<
970− toEncoding e <> B.char7 ',' <>
990+ builder e >*<
971− toEncoding f <> B.char7 ',' <>
991+ builder f >*<
972− toEncoding g <> B.char7 ',' <>
992+ builder g >*<
973− toEncoding h <> B.char7 ',' <>
993+ builder h >*<
974− toEncoding i <> B.char7 ']'
994+ builder i
975
995
976instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
996instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
977 FromJSON f, FromJSON g, FromJSON h, FromJSON i) =>
997 FromJSON f, FromJSON g, FromJSON h, FromJSON i) =>
@@ -1011,17 +1031,17 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
1011 return mv
1031 return mv
1012 {-# INLINE toJSON #-}
1032 {-# INLINE toJSON #-}
1013
1033
1014− toEncoding (a,b,c,d,e,f,g,h,i,j) = B.char7 '[' <>
1034+ toEncoding (a,b,c,d,e,f,g,h,i,j) = tuple $
1015− toEncoding a <> B.char7 ',' <>
1035+ builder a >*<
1016− toEncoding b <> B.char7 ',' <>
1036+ builder b >*<
1017− toEncoding c <> B.char7 ',' <>
1037+ builder c >*<
1018− toEncoding d <> B.char7 ',' <>
1038+ builder d >*<
1019− toEncoding e <> B.char7 ',' <>
1039+ builder e >*<
1020− toEncoding f <> B.char7 ',' <>
1040+ builder f >*<
1021− toEncoding g <> B.char7 ',' <>
1041+ builder g >*<
1022− toEncoding h <> B.char7 ',' <>
1042+ builder h >*<
1023− toEncoding i <> B.char7 ',' <>
1043+ builder i >*<
1024− toEncoding j <> B.char7 ']'
1044+ builder j
1025
1045
1026instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1046instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1027 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j) =>
1047 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j) =>
@@ -1063,18 +1083,18 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
1063 return mv
1083 return mv
1064 {-# INLINE toJSON #-}
1084 {-# INLINE toJSON #-}
1065
1085
1066− toEncoding (a,b,c,d,e,f,g,h,i,j,k) = B.char7 '[' <>
1086+ toEncoding (a,b,c,d,e,f,g,h,i,j,k) = tuple $
1067− toEncoding a <> B.char7 ',' <>
1087+ builder a >*<
1068− toEncoding b <> B.char7 ',' <>
1088+ builder b >*<
1069− toEncoding c <> B.char7 ',' <>
1089+ builder c >*<
1070− toEncoding d <> B.char7 ',' <>
1090+ builder d >*<
1071− toEncoding e <> B.char7 ',' <>
1091+ builder e >*<
1072− toEncoding f <> B.char7 ',' <>
1092+ builder f >*<
1073− toEncoding g <> B.char7 ',' <>
1093+ builder g >*<
1074− toEncoding h <> B.char7 ',' <>
1094+ builder h >*<
1075− toEncoding i <> B.char7 ',' <>
1095+ builder i >*<
1076− toEncoding j <> B.char7 ',' <>
1096+ builder j >*<
1077− toEncoding k <> B.char7 ']'
1097+ builder k
1078
1098
1079instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1099instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1080 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
1100 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
@@ -1119,19 +1139,19 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
1119 return mv
1139 return mv
1120 {-# INLINE toJSON #-}
1140 {-# INLINE toJSON #-}
1121
1141
1122− toEncoding (a,b,c,d,e,f,g,h,i,j,k,l) = B.char7 '[' <>
1142+ toEncoding (a,b,c,d,e,f,g,h,i,j,k,l) = tuple $
1123− toEncoding a <> B.char7 ',' <>
1143+ builder a >*<
1124− toEncoding b <> B.char7 ',' <>
1144+ builder b >*<
1125− toEncoding c <> B.char7 ',' <>
1145+ builder c >*<
1126− toEncoding d <> B.char7 ',' <>
1146+ builder d >*<
1127− toEncoding e <> B.char7 ',' <>
1147+ builder e >*<
1128− toEncoding f <> B.char7 ',' <>
1148+ builder f >*<
1129− toEncoding g <> B.char7 ',' <>
1149+ builder g >*<
1130− toEncoding h <> B.char7 ',' <>
1150+ builder h >*<
1131− toEncoding i <> B.char7 ',' <>
1151+ builder i >*<
1132− toEncoding j <> B.char7 ',' <>
1152+ builder j >*<
1133− toEncoding k <> B.char7 ',' <>
1153+ builder k >*<
1134− toEncoding l <> B.char7 ']'
1154+ builder l
1135
1155
1136instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1156instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1137 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
1157 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
@@ -1179,20 +1199,20 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
1179 return mv
1199 return mv
1180 {-# INLINE toJSON #-}
1200 {-# INLINE toJSON #-}
1181
1201
1182− toEncoding (a,b,c,d,e,f,g,h,i,j,k,l,m) = B.char7 '[' <>
1202+ toEncoding (a,b,c,d,e,f,g,h,i,j,k,l,m) = tuple $
1183− toEncoding a <> B.char7 ',' <>
1203+ builder a >*<
1184− toEncoding b <> B.char7 ',' <>
1204+ builder b >*<
1185− toEncoding c <> B.char7 ',' <>
1205+ builder c >*<
1186− toEncoding d <> B.char7 ',' <>
1206+ builder d >*<
1187− toEncoding e <> B.char7 ',' <>
1207+ builder e >*<
1188− toEncoding f <> B.char7 ',' <>
1208+ builder f >*<
1189− toEncoding g <> B.char7 ',' <>
1209+ builder g >*<
1190− toEncoding h <> B.char7 ',' <>
1210+ builder h >*<
1191− toEncoding i <> B.char7 ',' <>
1211+ builder i >*<
1192− toEncoding j <> B.char7 ',' <>
1212+ builder j >*<
1193− toEncoding k <> B.char7 ',' <>
1213+ builder k >*<
1194− toEncoding l <> B.char7 ',' <>
1214+ builder l >*<
1195− toEncoding m <> B.char7 ']'
1215+ builder m
1196
1216
1197instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1217instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1198 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
1218 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
@@ -1242,21 +1262,21 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
1242 return mv
1262 return mv
1243 {-# INLINE toJSON #-}
1263 {-# INLINE toJSON #-}
1244
1264
1245− toEncoding (a,b,c,d,e,f,g,h,i,j,k,l,m,n) = B.char7 '[' <>
1265+ toEncoding (a,b,c,d,e,f,g,h,i,j,k,l,m,n) = tuple $
1246− toEncoding a <> B.char7 ',' <>
1266+ builder a >*<
1247− toEncoding b <> B.char7 ',' <>
1267+ builder b >*<
1248− toEncoding c <> B.char7 ',' <>
1268+ builder c >*<
1249− toEncoding d <> B.char7 ',' <>
1269+ builder d >*<
1250− toEncoding e <> B.char7 ',' <>
1270+ builder e >*<
1251− toEncoding f <> B.char7 ',' <>
1271+ builder f >*<
1252− toEncoding g <> B.char7 ',' <>
1272+ builder g >*<
1253− toEncoding h <> B.char7 ',' <>
1273+ builder h >*<
1254− toEncoding i <> B.char7 ',' <>
1274+ builder i >*<
1255− toEncoding j <> B.char7 ',' <>
1275+ builder j >*<
1256− toEncoding k <> B.char7 ',' <>
1276+ builder k >*<
1257− toEncoding l <> B.char7 ',' <>
1277+ builder l >*<
1258− toEncoding m <> B.char7 ',' <>
1278+ builder m >*<
1259− toEncoding n <> B.char7 ']'
1279+ builder n
1260
1280
1261instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1281instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1262 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
1282 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
@@ -1308,22 +1328,22 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
1308 return mv
1328 return mv
1309 {-# INLINE toJSON #-}
1329 {-# INLINE toJSON #-}
1310
1330
1311− toEncoding (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) = B.char7 '[' <>
1331+ toEncoding (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) = tuple $
1312− toEncoding a <> B.char7 ',' <>
1332+ builder a >*<
1313− toEncoding b <> B.char7 ',' <>
1333+ builder b >*<
1314− toEncoding c <> B.char7 ',' <>
1334+ builder c >*<
1315− toEncoding d <> B.char7 ',' <>
1335+ builder d >*<
1316− toEncoding e <> B.char7 ',' <>
1336+ builder e >*<
1317− toEncoding f <> B.char7 ',' <>
1337+ builder f >*<
1318− toEncoding g <> B.char7 ',' <>
1338+ builder g >*<
1319− toEncoding h <> B.char7 ',' <>
1339+ builder h >*<
1320− toEncoding i <> B.char7 ',' <>
1340+ builder i >*<
1321− toEncoding j <> B.char7 ',' <>
1341+ builder j >*<
1322− toEncoding k <> B.char7 ',' <>
1342+ builder k >*<
1323− toEncoding l <> B.char7 ',' <>
1343+ builder l >*<
1324− toEncoding m <> B.char7 ',' <>
1344+ builder m >*<
1325− toEncoding n <> B.char7 ',' <>
1345+ builder n >*<
1326− toEncoding o <> B.char7 ']'
1346+ builder o
1327
1347
1328instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1348instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
1329 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
1349 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
@@ -1429,10 +1449,11 @@ instance KeyValue Pair where
1429 {-# INLINE (.=) #-}
1449 {-# INLINE (.=) #-}
1430
1450
1431instance KeyValue Series where
1451instance KeyValue Series where
1452+ name .= value = Value . Encoding $
1432− name .= value = Value (E.text name <> B.char7 ':' <> toEncoding value)
1453+ E.text name <> B.char7 ':' <> builder value
1433 {-# INLINE (.=) #-}
1454 {-# INLINE (.=) #-}
1434
1455
1435−series :: Series -> B.Builder
1456+series :: Series -> Encoding
1436series Empty = mempty
1457series Empty = mempty
1437series (Value v) = v
1458series (Value v) = v
1438
1459
@@ -1509,7 +1530,7 @@ realFloatToJSON d
1509
1530
1510realFloatToEncoding :: RealFloat a => a -> Encoding
1531realFloatToEncoding :: RealFloat a => a -> Encoding
1511realFloatToEncoding d
1532realFloatToEncoding d
1512− | isNaN d || isInfinite d = E.null_
1533+ | isNaN d || isInfinite d = Encoding E.null_
1513 | otherwise = toEncoding (Scientific.fromFloatDigits d)
1534 | otherwise = toEncoding (Scientific.fromFloatDigits d)
1514{-# INLINE realFloatToEncoding #-}
1535{-# INLINE realFloatToEncoding #-}
1515
1536
Data/Aeson/Types/Internal.hs+6−4
@@ -15,7 +15,7 @@ module Data.Aeson.Types.Internal
15 (
15 (
16 -- * Core JSON types
16 -- * Core JSON types
17 Value(..)
17 Value(..)
18− , Encoding
18+ , Encoding(..)
19 , Series(..)
19 , Series(..)
20 , Array
20 , Array
21 , emptyArray, isEmptyArray
21 , emptyArray, isEmptyArray
@@ -205,10 +205,12 @@ data Value = Object !Object
205 deriving (Eq, Read, Show, Typeable, Data)
205 deriving (Eq, Read, Show, Typeable, Data)
206
206
207-- | An encoding of a JSON value.
207-- | An encoding of a JSON value.
208−type Encoding = Builder
208+newtype Encoding = Encoding {
209+ fromEncoding :: Builder
210+ } deriving (Monoid)
209
211
210data Series = Empty
212data Series = Empty
211− | Value Builder
213+ | Value Encoding
212 deriving (Typeable)
214 deriving (Typeable)
213
215
214instance Monoid Series where
216instance Monoid Series where
@@ -218,7 +220,7 @@ instance Monoid Series where
218 Value $
220 Value $
219 a <> case b of
221 a <> case b of
220 Empty -> mempty
222 Empty -> mempty
221− Value c -> char7 ',' <> c
223+ Value c -> Encoding (char7 ',') <> c
222
224
223-- | A newtype wrapper for 'UTCTime' that uses the same non-standard
225-- | A newtype wrapper for 'UTCTime' that uses the same non-standard
224-- serialization format as Microsoft .NET, whose @System.DateTime@
226-- serialization format as Microsoft .NET, whose @System.DateTime@
benchmarks/Typed/Manual.hs+1−1
@@ -10,7 +10,7 @@ import Data.ByteString.Lazy as L
10import Data.ByteString.Builder as B
10import Data.ByteString.Builder as B
11
11
12encodeDirect :: Result -> L.ByteString
12encodeDirect :: Result -> L.ByteString
13−encodeDirect = B.toLazyByteString . toEncoding
13+encodeDirect = B.toLazyByteString . fromEncoding . toEncoding
14
14
15encodeViaValue :: Result -> L.ByteString
15encodeViaValue :: Result -> L.ByteString
16encodeViaValue = encode
16encodeViaValue = encode