@@ -51,14 +51,18 @@ module Data.Aeson.Types.Instances
5151 ) where
5252
5353import Control.Applicative ((<$>), (<*>), (<|>), pure, empty)
54+import qualified Data.Aeson.Encode.ByteString as E
55+import qualified Data.ByteString.Builder as B
56+import qualified Data.ByteString.Builder.Prim as BP
5457import Data.Aeson.Functions
58+import Data.Monoid ((<>), mempty)
5559import Data.Aeson.Types.Class
5660import Data.Aeson.Types.Internal
5761import Data.Scientific (Scientific)
5862import qualified Data.Scientific as Scientific (coefficient, base10Exponent, fromFloatDigits, toRealFloat)
5963import Data.Attoparsec.Number (Number(..))
6064import Data.Fixed
61−import Data.Foldable (toList)
65+import Data.Foldable (Foldable, toList)
6266import Data.Functor.Identity (Identity(..))
6367import Data.Hashable (Hashable(..))
6468import Data.Int (Int8, Int16, Int32, Int64)
@@ -72,6 +76,7 @@ import Data.Traversable (traverse)
7276import Data.Vector (Vector)
7377import Data.Word (Word, Word8, Word16, Word32, Word64)
7478import Foreign.Storable (Storable)
79+import Prelude hiding (foldr)
7580import qualified Data.HashMap.Strict as H
7681import qualified Data.HashSet as HashSet
7782import qualified Data.IntMap as IntMap
@@ -88,6 +93,7 @@ import qualified Data.Vector.Primitive as VP
8893import qualified Data.Vector.Storable as VS
8994import qualified Data.Vector.Unboxed as VU
9095import qualified Data.Vector.Mutable as VM ( unsafeNew, unsafeWrite )
96+import qualified Prelude as P
9197
9298#if MIN_VERSION_time(1,5,0)
9399import Data.Time.Format (defaultTimeLocale, dateTimeFmt)
@@ -99,6 +105,9 @@ instance (ToJSON a) => ToJSON (Identity a) where
99105 toJSON (Identity a) = toJSON a
100106 {-# INLINE toJSON #-}
101107
108+ toEncoding (Identity a) = toEncoding a
109+ {-# INLINE toEncoding #-}
110+
102111instance (FromJSON a) => FromJSON (Identity a) where
103112 parseJSON a = Identity <$> parseJSON a
104113 {-# INLINE parseJSON #-}
@@ -108,6 +117,9 @@ instance (ToJSON a) => ToJSON (Maybe a) where
108117 toJSON Nothing = Null
109118 {-# INLINE toJSON #-}
110119
120+ toEncoding (Just a) = toEncoding a
121+ toEncoding Nothing = E.null_
122+
111123instance (FromJSON a) => FromJSON (Maybe a) where
112124 parseJSON Null = pure Nothing
113125 parseJSON a = Just <$> parseJSON a
@@ -118,6 +130,11 @@ instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
118130 toJSON (Right b) = object [right .= b]
119131 {-# INLINE toJSON #-}
120132
133+ toEncoding (Left a) =
134+ B.shortByteString "{\"left\":" <> toEncoding a <> B.char7 '}'
135+ toEncoding (Right a) =
136+ B.shortByteString "{\"right\":" <> toEncoding a <> B.char7 '}'
137+
121138instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
122139 parseJSON (Object (H.toList -> [(key, value)]))
123140 | key == left = Left <$> parseJSON value
@@ -136,6 +153,8 @@ instance ToJSON Bool where
136153 toJSON = Bool
137154 {-# INLINE toJSON #-}
138155
156+ toEncoding v = E.bool v
157+
139158instance FromJSON Bool where
140159 parseJSON = withBool "Bool" pure
141160 {-# INLINE parseJSON #-}
@@ -144,6 +163,8 @@ instance ToJSON () where
144163 toJSON _ = emptyArray
145164 {-# INLINE toJSON #-}
146165
166+ toEncoding _ = E.emptyArray_
167+
147168instance FromJSON () where
148169 parseJSON = withArray "()" $ \v ->
149170 if V.null v
@@ -155,6 +176,8 @@ instance ToJSON [Char] where
155176 toJSON = String . T.pack
156177 {-# INLINE toJSON #-}
157178
179+ toEncoding = E.text . T.pack
180+
158181instance FromJSON [Char] where
159182 parseJSON = withText "String" $ pure . T.unpack
160183 {-# INLINE parseJSON #-}
@@ -163,6 +186,8 @@ instance ToJSON Char where
163186 toJSON = String . T.singleton
164187 {-# INLINE toJSON #-}
165188
189+ toEncoding = E.text . T.singleton
190+
166191instance FromJSON Char where
167192 parseJSON = withText "Char" $ \t ->
168193 if T.compareLength t 1 == EQ
@@ -174,6 +199,9 @@ instance ToJSON Scientific where
174199 toJSON = Number
175200 {-# INLINE toJSON #-}
176201
202+ toEncoding v = E.number v
203+ {-# INLINE toEncoding #-}
204+
177205instance FromJSON Scientific where
178206 parseJSON = withScientific "Scientific" pure
179207 {-# INLINE parseJSON #-}
@@ -182,6 +210,9 @@ instance ToJSON Double where
182210 toJSON = realFloatToJSON
183211 {-# INLINE toJSON #-}
184212
213+ toEncoding = realFloatToEncoding
214+ {-# INLINE toEncoding #-}
215+
185216instance FromJSON Double where
186217 parseJSON = parseRealFloat "Double"
187218 {-# INLINE parseJSON #-}
@@ -191,6 +222,10 @@ instance ToJSON Number where
191222 toJSON (I i) = toJSON i
192223 {-# INLINE toJSON #-}
193224
225+ toEncoding (D d) = toEncoding d
226+ toEncoding (I i) = toEncoding i
227+ {-# INLINE toEncoding #-}
228+
194229instance FromJSON Number where
195230 parseJSON (Number s) = pure $ scientificToNumber s
196231 parseJSON Null = pure (D (0/0))
@@ -201,6 +236,9 @@ instance ToJSON Float where
201236 toJSON = realFloatToJSON
202237 {-# INLINE toJSON #-}
203238
239+ toEncoding = realFloatToEncoding
240+ {-# INLINE toEncoding #-}
241+
204242instance FromJSON Float where
205243 parseJSON = parseRealFloat "Float"
206244 {-# INLINE parseJSON #-}
@@ -209,7 +247,11 @@ instance ToJSON (Ratio Integer) where
209247 toJSON r = object [ "numerator" .= numerator r
210248 , "denominator" .= denominator r
211249 ]
212− {-# INLINE toJSON #-}
250+
251+ toEncoding r =
252+ B.shortByteString "{\"numerator\":" <> toEncoding (numerator r) <>
253+ B.shortByteString ",\"denominator\":" <> toEncoding (denominator r) <>
254+ B.char7 '}'
213255
214256instance FromJSON (Ratio Integer) where
215257 parseJSON = withObject "Rational" $ \obj ->
@@ -221,6 +263,8 @@ instance HasResolution a => ToJSON (Fixed a) where
221263 toJSON = Number . realToFrac
222264 {-# INLINE toJSON #-}
223265
266+ toEncoding = E.number . realToFrac
267+
224268-- | /WARNING:/ Only parse fixed-precision numbers from trusted input
225269-- since an attacker could easily fill up the memory of the target
226270-- system by specifying a scientific number with a big exponent like
@@ -233,6 +277,9 @@ instance ToJSON Int where
233277 toJSON = Number . fromIntegral
234278 {-# INLINE toJSON #-}
235279
280+ toEncoding = B.intDec
281+ {-# INLINE toEncoding #-}
282+
236283instance FromJSON Int where
237284 parseJSON = parseIntegral "Int"
238285 {-# INLINE parseJSON #-}
@@ -241,6 +288,8 @@ instance ToJSON Integer where
241288 toJSON = Number . fromInteger
242289 {-# INLINE toJSON #-}
243290
291+ toEncoding = B.integerDec
292+
244293-- | /WARNING:/ Only parse Integers from trusted input since an
245294-- attacker could easily fill up the memory of the target system by
246295-- specifying a scientific number with a big exponent like
@@ -253,6 +302,8 @@ instance ToJSON Int8 where
253302 toJSON = Number . fromIntegral
254303 {-# INLINE toJSON #-}
255304
305+ toEncoding = B.int8Dec
306+
256307instance FromJSON Int8 where
257308 parseJSON = parseIntegral "Int8"
258309 {-# INLINE parseJSON #-}
@@ -261,6 +312,8 @@ instance ToJSON Int16 where
261312 toJSON = Number . fromIntegral
262313 {-# INLINE toJSON #-}
263314
315+ toEncoding = B.int16Dec
316+
264317instance FromJSON Int16 where
265318 parseJSON = parseIntegral "Int16"
266319 {-# INLINE parseJSON #-}
@@ -269,6 +322,8 @@ instance ToJSON Int32 where
269322 toJSON = Number . fromIntegral
270323 {-# INLINE toJSON #-}
271324
325+ toEncoding = B.int32Dec
326+
272327instance FromJSON Int32 where
273328 parseJSON = parseIntegral "Int32"
274329 {-# INLINE parseJSON #-}
@@ -277,6 +332,8 @@ instance ToJSON Int64 where
277332 toJSON = Number . fromIntegral
278333 {-# INLINE toJSON #-}
279334
335+ toEncoding = B.int64Dec
336+
280337instance FromJSON Int64 where
281338 parseJSON = parseIntegral "Int64"
282339 {-# INLINE parseJSON #-}
@@ -285,6 +342,8 @@ instance ToJSON Word where
285342 toJSON = Number . fromIntegral
286343 {-# INLINE toJSON #-}
287344
345+ toEncoding = B.wordDec
346+
288347instance FromJSON Word where
289348 parseJSON = parseIntegral "Word"
290349 {-# INLINE parseJSON #-}
@@ -293,6 +352,8 @@ instance ToJSON Word8 where
293352 toJSON = Number . fromIntegral
294353 {-# INLINE toJSON #-}
295354
355+ toEncoding = B.word8Dec
356+
296357instance FromJSON Word8 where
297358 parseJSON = parseIntegral "Word8"
298359 {-# INLINE parseJSON #-}
@@ -301,6 +362,8 @@ instance ToJSON Word16 where
301362 toJSON = Number . fromIntegral
302363 {-# INLINE toJSON #-}
303364
365+ toEncoding = B.word16Dec
366+
304367instance FromJSON Word16 where
305368 parseJSON = parseIntegral "Word16"
306369 {-# INLINE parseJSON #-}
@@ -309,6 +372,8 @@ instance ToJSON Word32 where
309372 toJSON = Number . fromIntegral
310373 {-# INLINE toJSON #-}
311374
375+ toEncoding = B.word32Dec
376+
312377instance FromJSON Word32 where
313378 parseJSON = parseIntegral "Word32"
314379 {-# INLINE parseJSON #-}
@@ -317,6 +382,8 @@ instance ToJSON Word64 where
317382 toJSON = Number . fromIntegral
318383 {-# INLINE toJSON #-}
319384
385+ toEncoding = B.word64Dec
386+
320387instance FromJSON Word64 where
321388 parseJSON = parseIntegral "Word64"
322389 {-# INLINE parseJSON #-}
@@ -325,6 +392,8 @@ instance ToJSON Text where
325392 toJSON = String
326393 {-# INLINE toJSON #-}
327394
395+ toEncoding = E.text
396+
328397instance FromJSON Text where
329398 parseJSON = withText "Text" pure
330399 {-# INLINE parseJSON #-}
@@ -333,6 +402,11 @@ instance ToJSON LT.Text where
333402 toJSON = String . LT.toStrict
334403 {-# INLINE toJSON #-}
335404
405+ toEncoding t =
406+ B.char7 '"' <>
407+ LT.foldrChunks (\x xs -> E.unquoted x <> xs) mempty t <>
408+ B.char7 '"'
409+
336410instance FromJSON LT.Text where
337411 parseJSON = withText "Lazy Text" $ pure . LT.fromStrict
338412 {-# INLINE parseJSON #-}
@@ -341,14 +415,20 @@ instance (ToJSON a) => ToJSON [a] where
341415 toJSON = Array . V.fromList . map toJSON
342416 {-# INLINE toJSON #-}
343417
418+ toEncoding [] = E.emptyArray_
419+ toEncoding (x:xs) = B.char7 '[' <> toEncoding x <> commas xs <> B.char7 ']'
420+ where commas = P.foldr (\v vs -> B.char7 ',' <> toEncoding v <> vs) mempty
421+
344422instance (FromJSON a) => FromJSON [a] where
345423 parseJSON = withArray "[a]" $ mapM parseJSON . V.toList
346424 {-# INLINE parseJSON #-}
347425
348−instance (ToJSON a) => ToJSON (Seq.Seq a) where
426+instance (Foldable t, ToJSON a) => ToJSON (t a) where
349427 toJSON = toJSON . toList
350428 {-# INLINE toJSON #-}
351429
430+ toEncoding = E.foldable
431+
352432instance (FromJSON a) => FromJSON (Seq.Seq a) where
353433 parseJSON = withArray "Seq a" $ traverse parseJSON . Seq.fromList . V.toList
354434 {-# INLINE parseJSON #-}
@@ -357,6 +437,16 @@ instance (ToJSON a) => ToJSON (Vector a) where
357437 toJSON = Array . V.map toJSON
358438 {-# INLINE toJSON #-}
359439
440+ toEncoding = encodeVector
441+
442+encodeVector :: (ToJSON a, VG.Vector v a) => v a -> B.Builder
443+encodeVector xs
444+ | VG.null xs = E.emptyArray_
445+ | otherwise = B.char7 '[' <> toEncoding (VG.unsafeHead xs) <>
446+ VG.foldr go mempty (VG.unsafeTail xs) <>
447+ B.char7 ']'
448+ where go v b = B.char7 ',' <> toEncoding v <> b
449+
360450instance (FromJSON a) => FromJSON (Vector a) where
361451 parseJSON = withArray "Vector a" $ V.mapM parseJSON
362452 {-# INLINE parseJSON #-}
@@ -372,18 +462,24 @@ vectorParseJSON s = withArray s $ fmap V.convert . V.mapM parseJSON
372462instance (Storable a, ToJSON a) => ToJSON (VS.Vector a) where
373463 toJSON = vectorToJSON
374464
465+ toEncoding = encodeVector
466+
375467instance (Storable a, FromJSON a) => FromJSON (VS.Vector a) where
376468 parseJSON = vectorParseJSON "Data.Vector.Storable.Vector a"
377469
378470instance (VP.Prim a, ToJSON a) => ToJSON (VP.Vector a) where
379471 toJSON = vectorToJSON
380472
473+ toEncoding = encodeVector
474+
381475instance (VP.Prim a, FromJSON a) => FromJSON (VP.Vector a) where
382476 parseJSON = vectorParseJSON "Data.Vector.Primitive.Vector a"
383477
384478instance (VG.Vector VU.Vector a, ToJSON a) => ToJSON (VU.Vector a) where
385479 toJSON = vectorToJSON
386480
481+ toEncoding = encodeVector
482+
387483instance (VG.Vector VU.Vector a, FromJSON a) => FromJSON (VU.Vector a) where
388484 parseJSON = vectorParseJSON "Data.Vector.Unboxed.Vector a"
389485
@@ -391,6 +487,8 @@ instance (ToJSON a) => ToJSON (Set.Set a) where
391487 toJSON = toJSON . Set.toList
392488 {-# INLINE toJSON #-}
393489
490+ toEncoding = encodeSet Set.minView Set.foldr
491+
394492instance (Ord a, FromJSON a) => FromJSON (Set.Set a) where
395493 parseJSON = fmap Set.fromList . parseJSON
396494 {-# INLINE parseJSON #-}
@@ -399,6 +497,8 @@ instance (ToJSON a) => ToJSON (HashSet.HashSet a) where
399497 toJSON = toJSON . HashSet.toList
400498 {-# INLINE toJSON #-}
401499
500+ toEncoding = E.foldable
501+
402502instance (Eq a, Hashable a, FromJSON a) => FromJSON (HashSet.HashSet a) where
403503 parseJSON = fmap HashSet.fromList . parseJSON
404504 {-# INLINE parseJSON #-}
@@ -407,6 +507,20 @@ instance ToJSON IntSet.IntSet where
407507 toJSON = toJSON . IntSet.toList
408508 {-# INLINE toJSON #-}
409509
510+ toEncoding = encodeSet IntSet.minView IntSet.foldr
511+
512+encodeSet :: (ToJSON a) =>
513+ (s -> Maybe (a, s))
514+ -> ((a -> B.Builder -> B.Builder) -> B.Builder -> s -> B.Builder)
515+ -> s -> B.Builder
516+encodeSet minView foldr xs =
517+ case minView xs of
518+ Nothing -> E.emptyArray_
519+ Just (m,ys) -> B.char7 '[' <> toEncoding m <>
520+ foldr go mempty ys <>
521+ B.char7 ']'
522+ where go v b = B.char7 ',' <> toEncoding v <> b
523+
410524instance FromJSON IntSet.IntSet where
411525 parseJSON = fmap IntSet.fromList . parseJSON
412526 {-# INLINE parseJSON #-}
@@ -415,6 +529,8 @@ instance ToJSON a => ToJSON (IntMap.IntMap a) where
415529 toJSON = toJSON . IntMap.toList
416530 {-# INLINE toJSON #-}
417531
532+ toEncoding = toEncoding . IntMap.toList
533+
418534instance FromJSON a => FromJSON (IntMap.IntMap a) where
419535 parseJSON = fmap IntMap.fromList . parseJSON
420536 {-# INLINE parseJSON #-}
@@ -423,6 +539,28 @@ instance (ToJSON v) => ToJSON (M.Map Text v) where
423539 toJSON = Object . M.foldrWithKey (\k -> H.insert k . toJSON) H.empty
424540 {-# INLINE toJSON #-}
425541
542+ toEncoding = encodeMap M.minViewWithKey M.foldrWithKey
543+
544+encodeMap :: (ToJSON k, ToJSON v) =>
545+ (m -> Maybe ((k,v), m))
546+ -> ((k -> v -> B.Builder -> B.Builder) -> B.Builder -> m -> B.Builder)
547+ -> m -> B.Builder
548+encodeMap minViewWithKey foldrWithKey xs =
549+ case minViewWithKey xs of
550+ Nothing -> BP.primBounded (E.ascii2 ('{','}')) ()
551+ Just ((k,v),ys) -> B.char7 '{' <> encodePair k v <>
552+ foldrWithKey go mempty ys <> B.char7 '}'
553+ where go k v b = B.char7 ',' <> encodePair k v <> b
554+
555+encodeWithKey :: (ToJSON k, ToJSON v) =>
556+ ((k -> v -> Series -> Series) -> Series -> m -> Series)
557+ -> m -> B.Builder
558+encodeWithKey foldrWithKey xs = E.series '{' '}' . foldrWithKey go mempty $ xs
559+ where go k v c = Value (encodePair k v) <> c
560+
561+encodePair :: (ToJSON k, ToJSON v) => k -> v -> B.Builder
562+encodePair k v = toEncoding k <> B.char7 ':' <> toEncoding v
563+
426564instance (FromJSON v) => FromJSON (M.Map Text v) where
427565 parseJSON = withObject "Map Text a" $
428566 fmap (H.foldrWithKey M.insert M.empty) . traverse parseJSON
@@ -430,12 +568,16 @@ instance (FromJSON v) => FromJSON (M.Map Text v) where
430568instance (ToJSON v) => ToJSON (M.Map LT.Text v) where
431569 toJSON = Object . mapHashKeyVal LT.toStrict toJSON
432570
571+ toEncoding = encodeMap M.minViewWithKey M.foldrWithKey
572+
433573instance (FromJSON v) => FromJSON (M.Map LT.Text v) where
434574 parseJSON = fmap (hashMapKey LT.fromStrict) . parseJSON
435575
436576instance (ToJSON v) => ToJSON (M.Map String v) where
437577 toJSON = Object . mapHashKeyVal pack toJSON
438578
579+ toEncoding = encodeMap M.minViewWithKey M.foldrWithKey
580+
439581instance (FromJSON v) => FromJSON (M.Map String v) where
440582 parseJSON = fmap (hashMapKey unpack) . parseJSON
441583
@@ -443,24 +585,32 @@ instance (ToJSON v) => ToJSON (H.HashMap Text v) where
443585 toJSON = Object . H.map toJSON
444586 {-# INLINE toJSON #-}
445587
588+ toEncoding = encodeWithKey H.foldrWithKey
589+
446590instance (FromJSON v) => FromJSON (H.HashMap Text v) where
447591 parseJSON = withObject "HashMap Text a" $ traverse parseJSON
448592
449593instance (ToJSON v) => ToJSON (H.HashMap LT.Text v) where
450594 toJSON = Object . mapKeyVal LT.toStrict toJSON
451595
596+ toEncoding = encodeWithKey H.foldrWithKey
597+
452598instance (FromJSON v) => FromJSON (H.HashMap LT.Text v) where
453599 parseJSON = fmap (mapKey LT.fromStrict) . parseJSON
454600
455601instance (ToJSON v) => ToJSON (H.HashMap String v) where
456602 toJSON = Object . mapKeyVal pack toJSON
457603
604+ toEncoding = encodeWithKey H.foldrWithKey
605+
458606instance (FromJSON v) => FromJSON (H.HashMap String v) where
459607 parseJSON = fmap (mapKey unpack) . parseJSON
460608
461609instance (ToJSON v) => ToJSON (Tree.Tree v) where
462610 toJSON (Tree.Node root branches) = toJSON (root,branches)
463611
612+ toEncoding (Tree.Node root branches) = toEncoding (root,branches)
613+
464614instance (FromJSON v) => FromJSON (Tree.Tree v) where
465615 parseJSON j = uncurry Tree.Node <$> parseJSON j
466616
@@ -468,16 +618,22 @@ instance ToJSON Value where
468618 toJSON a = a
469619 {-# INLINE toJSON #-}
470620
621+ toEncoding = E.encodeToBuilder
622+
471623instance FromJSON Value where
472624 parseJSON a = pure a
473625 {-# INLINE parseJSON #-}
474626
475627instance ToJSON DotNetTime where
476− toJSON (DotNetTime t) =
477− String (pack (secs ++ formatMillis t ++ ")/"))
478− where secs = formatTime defaultTimeLocale "/Date(%s" t
628+ toJSON = toJSON . dotNetTime
479629 {-# INLINE toJSON #-}
480630
631+ toEncoding = toEncoding . dotNetTime
632+
633+dotNetTime :: DotNetTime -> String
634+dotNetTime (DotNetTime t) = secs ++ formatMillis t ++ ")/"
635+ where secs = formatTime defaultTimeLocale "/Date(%s" t
636+
481637instance FromJSON DotNetTime where
482638 parseJSON = withText "DotNetTime" $ \t ->
483639 let (s,m) = T.splitAt (T.length t - 5) t
@@ -488,12 +644,16 @@ instance FromJSON DotNetTime where
488644 {-# INLINE parseJSON #-}
489645
490646instance ToJSON ZonedTime where
491− toJSON t = String $ pack $ formatTime defaultTimeLocale format t
492− where
493− format = "%FT%T." ++ formatMillis t ++ tzFormat
494− tzFormat
495− | 0 == timeZoneMinutes (zonedTimeZone t) = "Z"
496− | otherwise = "%z"
647+ toJSON = toJSON . zonedTime
648+
649+ toEncoding = toEncoding . zonedTime
650+
651+zonedTime :: ZonedTime -> String
652+zonedTime t = formatTime defaultTimeLocale format t
653+ where
654+ format = "%FT%T." ++ formatMillis t ++ tzFormat
655+ tzFormat | timeZoneMinutes (zonedTimeZone t) == 0 = "Z"
656+ | otherwise = "%z"
497657
498658formatMillis :: (FormatTime t) => t -> String
499659formatMillis = take 3 . formatSubseconds
@@ -535,11 +695,15 @@ instance FromJSON ZonedTime where
535695 parseJSON v = typeMismatch "ZonedTime" v
536696
537697instance ToJSON UTCTime where
538− toJSON t = String $ pack $ formatTime defaultTimeLocale format t
539− where
540− format = "%FT%T." ++ formatSubseconds t ++ "Z"
698+ toJSON = toJSON . utcTime
541699 {-# INLINE toJSON #-}
542700
701+ toEncoding = toEncoding . utcTime
702+
703+utcTime :: UTCTime -> String
704+utcTime t = formatTime defaultTimeLocale format t
705+ where format = "%FT%T." ++ formatSubseconds t ++ "Z"
706+
543707instance FromJSON UTCTime where
544708 parseJSON = withText "UTCTime" $ \t ->
545709 case parseTime defaultTimeLocale "%FT%T%QZ" (unpack t) of
@@ -555,6 +719,10 @@ instance (ToJSON a, ToJSON b) => ToJSON (a,b) where
555719 return mv
556720 {-# INLINE toJSON #-}
557721
722+ toEncoding (a,b) = B.char7 '[' <>
723+ toEncoding a <> B.char7 ',' <>
724+ toEncoding b <> B.char7 ']'
725+
558726instance (FromJSON a, FromJSON b) => FromJSON (a,b) where
559727 parseJSON = withArray "(a,b)" $ \ab ->
560728 let n = V.length ab
@@ -574,6 +742,11 @@ instance (ToJSON a, ToJSON b, ToJSON c) => ToJSON (a,b,c) where
574742 return mv
575743 {-# INLINE toJSON #-}
576744
745+ toEncoding (a,b,c) = B.char7 '[' <>
746+ toEncoding a <> B.char7 ',' <>
747+ toEncoding b <> B.char7 ',' <>
748+ toEncoding c <> B.char7 ']'
749+
577750instance (FromJSON a, FromJSON b, FromJSON c) => FromJSON (a,b,c) where
578751 parseJSON = withArray "(a,b,c)" $ \abc ->
579752 let n = V.length abc
@@ -595,6 +768,12 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSON (a,b,c,d) where
595768 return mv
596769 {-# INLINE toJSON #-}
597770
771+ toEncoding (a,b,c,d) = B.char7 '[' <>
772+ toEncoding a <> B.char7 ',' <>
773+ toEncoding b <> B.char7 ',' <>
774+ toEncoding c <> B.char7 ',' <>
775+ toEncoding d <> B.char7 ']'
776+
598777instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) =>
599778 FromJSON (a,b,c,d) where
600779 parseJSON = withArray "(a,b,c,d)" $ \abcd ->
@@ -620,6 +799,13 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e) =>
620799 return mv
621800 {-# INLINE toJSON #-}
622801
802+ toEncoding (a,b,c,d,e) = B.char7 '[' <>
803+ toEncoding a <> B.char7 ',' <>
804+ toEncoding b <> B.char7 ',' <>
805+ toEncoding c <> B.char7 ',' <>
806+ toEncoding d <> B.char7 ',' <>
807+ toEncoding e <> B.char7 ']'
808+
623809instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e) =>
624810 FromJSON (a,b,c,d,e) where
625811 parseJSON = withArray "(a,b,c,d,e)" $ \abcde ->
@@ -647,6 +833,14 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f) =>
647833 return mv
648834 {-# INLINE toJSON #-}
649835
836+ toEncoding (a,b,c,d,e,f) = B.char7 '[' <>
837+ toEncoding a <> B.char7 ',' <>
838+ toEncoding b <> B.char7 ',' <>
839+ toEncoding c <> B.char7 ',' <>
840+ toEncoding d <> B.char7 ',' <>
841+ toEncoding e <> B.char7 ',' <>
842+ toEncoding f <> B.char7 ']'
843+
650844instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
651845 FromJSON f) => FromJSON (a,b,c,d,e,f) where
652846 parseJSON = withArray "(a,b,c,d,e,f)" $ \abcdef ->
@@ -676,6 +870,15 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
676870 return mv
677871 {-# INLINE toJSON #-}
678872
873+ toEncoding (a,b,c,d,e,f,g) = B.char7 '[' <>
874+ toEncoding a <> B.char7 ',' <>
875+ toEncoding b <> B.char7 ',' <>
876+ toEncoding c <> B.char7 ',' <>
877+ toEncoding d <> B.char7 ',' <>
878+ toEncoding e <> B.char7 ',' <>
879+ toEncoding f <> B.char7 ',' <>
880+ toEncoding g <> B.char7 ']'
881+
679882instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
680883 FromJSON f, FromJSON g) => FromJSON (a,b,c,d,e,f,g) where
681884 parseJSON = withArray "(a,b,c,d,e,f,g)" $ \abcdefg ->
@@ -707,6 +910,16 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
707910 return mv
708911 {-# INLINE toJSON #-}
709912
913+ toEncoding (a,b,c,d,e,f,g,h) = B.char7 '[' <>
914+ toEncoding a <> B.char7 ',' <>
915+ toEncoding b <> B.char7 ',' <>
916+ toEncoding c <> B.char7 ',' <>
917+ toEncoding d <> B.char7 ',' <>
918+ toEncoding e <> B.char7 ',' <>
919+ toEncoding f <> B.char7 ',' <>
920+ toEncoding g <> B.char7 ',' <>
921+ toEncoding h <> B.char7 ']'
922+
710923instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
711924 FromJSON f, FromJSON g, FromJSON h) =>
712925 FromJSON (a,b,c,d,e,f,g,h) where
@@ -742,6 +955,17 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
742955 return mv
743956 {-# INLINE toJSON #-}
744957
958+ toEncoding (a,b,c,d,e,f,g,h,i) = B.char7 '[' <>
959+ toEncoding a <> B.char7 ',' <>
960+ toEncoding b <> B.char7 ',' <>
961+ toEncoding c <> B.char7 ',' <>
962+ toEncoding d <> B.char7 ',' <>
963+ toEncoding e <> B.char7 ',' <>
964+ toEncoding f <> B.char7 ',' <>
965+ toEncoding g <> B.char7 ',' <>
966+ toEncoding h <> B.char7 ',' <>
967+ toEncoding i <> B.char7 ']'
968+
745969instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
746970 FromJSON f, FromJSON g, FromJSON h, FromJSON i) =>
747971 FromJSON (a,b,c,d,e,f,g,h,i) where
@@ -780,6 +1004,18 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
7801004 return mv
7811005 {-# INLINE toJSON #-}
7821006
1007+ toEncoding (a,b,c,d,e,f,g,h,i,j) = B.char7 '[' <>
1008+ toEncoding a <> B.char7 ',' <>
1009+ toEncoding b <> B.char7 ',' <>
1010+ toEncoding c <> B.char7 ',' <>
1011+ toEncoding d <> B.char7 ',' <>
1012+ toEncoding e <> B.char7 ',' <>
1013+ toEncoding f <> B.char7 ',' <>
1014+ toEncoding g <> B.char7 ',' <>
1015+ toEncoding h <> B.char7 ',' <>
1016+ toEncoding i <> B.char7 ',' <>
1017+ toEncoding j <> B.char7 ']'
1018+
7831019instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
7841020 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j) =>
7851021 FromJSON (a,b,c,d,e,f,g,h,i,j) where
@@ -820,6 +1056,19 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
8201056 return mv
8211057 {-# INLINE toJSON #-}
8221058
1059+ toEncoding (a,b,c,d,e,f,g,h,i,j,k) = B.char7 '[' <>
1060+ toEncoding a <> B.char7 ',' <>
1061+ toEncoding b <> B.char7 ',' <>
1062+ toEncoding c <> B.char7 ',' <>
1063+ toEncoding d <> B.char7 ',' <>
1064+ toEncoding e <> B.char7 ',' <>
1065+ toEncoding f <> B.char7 ',' <>
1066+ toEncoding g <> B.char7 ',' <>
1067+ toEncoding h <> B.char7 ',' <>
1068+ toEncoding i <> B.char7 ',' <>
1069+ toEncoding j <> B.char7 ',' <>
1070+ toEncoding k <> B.char7 ']'
1071+
8231072instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
8241073 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
8251074 FromJSON k) =>
@@ -863,6 +1112,20 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
8631112 return mv
8641113 {-# INLINE toJSON #-}
8651114
1115+ toEncoding (a,b,c,d,e,f,g,h,i,j,k,l) = B.char7 '[' <>
1116+ toEncoding a <> B.char7 ',' <>
1117+ toEncoding b <> B.char7 ',' <>
1118+ toEncoding c <> B.char7 ',' <>
1119+ toEncoding d <> B.char7 ',' <>
1120+ toEncoding e <> B.char7 ',' <>
1121+ toEncoding f <> B.char7 ',' <>
1122+ toEncoding g <> B.char7 ',' <>
1123+ toEncoding h <> B.char7 ',' <>
1124+ toEncoding i <> B.char7 ',' <>
1125+ toEncoding j <> B.char7 ',' <>
1126+ toEncoding k <> B.char7 ',' <>
1127+ toEncoding l <> B.char7 ']'
1128+
8661129instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
8671130 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
8681131 FromJSON k, FromJSON l) =>
@@ -909,6 +1172,21 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
9091172 return mv
9101173 {-# INLINE toJSON #-}
9111174
1175+ toEncoding (a,b,c,d,e,f,g,h,i,j,k,l,m) = B.char7 '[' <>
1176+ toEncoding a <> B.char7 ',' <>
1177+ toEncoding b <> B.char7 ',' <>
1178+ toEncoding c <> B.char7 ',' <>
1179+ toEncoding d <> B.char7 ',' <>
1180+ toEncoding e <> B.char7 ',' <>
1181+ toEncoding f <> B.char7 ',' <>
1182+ toEncoding g <> B.char7 ',' <>
1183+ toEncoding h <> B.char7 ',' <>
1184+ toEncoding i <> B.char7 ',' <>
1185+ toEncoding j <> B.char7 ',' <>
1186+ toEncoding k <> B.char7 ',' <>
1187+ toEncoding l <> B.char7 ',' <>
1188+ toEncoding m <> B.char7 ']'
1189+
9121190instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
9131191 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
9141192 FromJSON k, FromJSON l, FromJSON m) =>
@@ -957,6 +1235,22 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
9571235 return mv
9581236 {-# INLINE toJSON #-}
9591237
1238+ toEncoding (a,b,c,d,e,f,g,h,i,j,k,l,m,n) = B.char7 '[' <>
1239+ toEncoding a <> B.char7 ',' <>
1240+ toEncoding b <> B.char7 ',' <>
1241+ toEncoding c <> B.char7 ',' <>
1242+ toEncoding d <> B.char7 ',' <>
1243+ toEncoding e <> B.char7 ',' <>
1244+ toEncoding f <> B.char7 ',' <>
1245+ toEncoding g <> B.char7 ',' <>
1246+ toEncoding h <> B.char7 ',' <>
1247+ toEncoding i <> B.char7 ',' <>
1248+ toEncoding j <> B.char7 ',' <>
1249+ toEncoding k <> B.char7 ',' <>
1250+ toEncoding l <> B.char7 ',' <>
1251+ toEncoding m <> B.char7 ',' <>
1252+ toEncoding n <> B.char7 ']'
1253+
9601254instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
9611255 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
9621256 FromJSON k, FromJSON l, FromJSON m, FromJSON n) =>
@@ -1007,6 +1301,23 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f,
10071301 return mv
10081302 {-# INLINE toJSON #-}
10091303
1304+ toEncoding (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) = B.char7 '[' <>
1305+ toEncoding a <> B.char7 ',' <>
1306+ toEncoding b <> B.char7 ',' <>
1307+ toEncoding c <> B.char7 ',' <>
1308+ toEncoding d <> B.char7 ',' <>
1309+ toEncoding e <> B.char7 ',' <>
1310+ toEncoding f <> B.char7 ',' <>
1311+ toEncoding g <> B.char7 ',' <>
1312+ toEncoding h <> B.char7 ',' <>
1313+ toEncoding i <> B.char7 ',' <>
1314+ toEncoding j <> B.char7 ',' <>
1315+ toEncoding k <> B.char7 ',' <>
1316+ toEncoding l <> B.char7 ',' <>
1317+ toEncoding m <> B.char7 ',' <>
1318+ toEncoding n <> B.char7 ',' <>
1319+ toEncoding o <> B.char7 ']'
1320+
10101321instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e,
10111322 FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j,
10121323 FromJSON k, FromJSON l, FromJSON m, FromJSON n, FromJSON o) =>
@@ -1038,6 +1349,8 @@ instance ToJSON a => ToJSON (Dual a) where
10381349 toJSON = toJSON . getDual
10391350 {-# INLINE toJSON #-}
10401351
1352+ toEncoding = toEncoding . getDual
1353+
10411354instance FromJSON a => FromJSON (Dual a) where
10421355 parseJSON = fmap Dual . parseJSON
10431356 {-# INLINE parseJSON #-}
@@ -1046,6 +1359,8 @@ instance ToJSON a => ToJSON (First a) where
10461359 toJSON = toJSON . getFirst
10471360 {-# INLINE toJSON #-}
10481361
1362+ toEncoding = toEncoding . getFirst
1363+
10491364instance FromJSON a => FromJSON (First a) where
10501365 parseJSON = fmap First . parseJSON
10511366 {-# INLINE parseJSON #-}
@@ -1054,6 +1369,8 @@ instance ToJSON a => ToJSON (Last a) where
10541369 toJSON = toJSON . getLast
10551370 {-# INLINE toJSON #-}
10561371
1372+ toEncoding = toEncoding . getLast
1373+
10571374instance FromJSON a => FromJSON (Last a) where
10581375 parseJSON = fmap Last . parseJSON
10591376 {-# INLINE parseJSON #-}
@@ -1176,6 +1493,12 @@ realFloatToJSON d
11761493 | otherwise = Number $ Scientific.fromFloatDigits d
11771494{-# INLINE realFloatToJSON #-}
11781495
1496+realFloatToEncoding :: RealFloat a => a -> Encoding
1497+realFloatToEncoding d
1498+ | isNaN d || isInfinite d = E.null_
1499+ | otherwise = toEncoding (Scientific.fromFloatDigits d)
1500+{-# INLINE realFloatToEncoding #-}
1501+
11791502scientificToNumber :: Scientific -> Number
11801503scientificToNumber s
11811504 | e < 0 = D $ Scientific.toRealFloat s