@@ -43,6 +43,7 @@ module Data.Aeson.Types.ToJSON (
43 -- * Classes and types for map keys
43 -- * Classes and types for map keys
44 , ToJSONKey(..)
44 , ToJSONKey(..)
45 , ToJSONKeyFunction(..)
45 , ToJSONKeyFunction(..)
46 , contramapToJSONKeyFunction
47 , contramapToJSONKeyFunction
47 -- * Object key-value pairs
48 -- * Object key-value pairs
48 , KeyValue(..)
49 , KeyValue(..)
@@ -55,9 +56,9 @@ module Data.Aeson.Types.ToJSON (
55import Prelude ()
56import Prelude ()
56import Prelude.Compat
57import Prelude.Compat
58−import Data.Aeson.Encoding.Internal (Encoding (..), Series, dict, emptyArray_,
59+import Data.Aeson.Encoding.Internal (Encoding, Encoding', Series, dict,
59− tuple, (>*<))
60+ emptyArray_, tuple, (>*<), (><))
60−import Data.Aeson.Functions (mapHashKeyVal, mapKeyVal)
61+import Data.Aeson.Internal.Functions (mapHashKeyVal, mapKeyVal)
61import Data.Aeson.Types.Generic
62import Data.Aeson.Types.Generic
62import Data.Aeson.Types.Internal
63import Data.Aeson.Types.Internal
@@ -71,6 +72,7 @@ import Data.Bits (unsafeShiftR)
71import Data.DList (DList)
72import Data.DList (DList)
72import Data.Fixed (Fixed, HasResolution)
73import Data.Fixed (Fixed, HasResolution)
73import Data.Foldable (toList)
74import Data.Foldable (toList)
75+import Data.Functor.Compose (Compose (..))
74import Data.Functor.Identity (Identity (..))
76import Data.Functor.Identity (Identity (..))
75import Data.Int (Int16, Int32, Int64, Int8)
77import Data.Int (Int16, Int32, Int64, Int8)
76import Data.List (intersperse)
78import Data.List (intersperse)
@@ -92,35 +94,30 @@ import Foreign.Storable (Storable)
92import GHC.Generics
94import GHC.Generics
93import Numeric.Natural (Natural)
95import Numeric.Natural (Natural)
95−import qualified Data.ByteString.Builder as B (toLazyByteString)
97+import qualified Data.ByteString.Lazy as L
96−import qualified Data.ByteString.Lazy as L
97−import qualified Data.DList as DList
98+import qualified Data.DList as DList
98−import qualified Data.HashMap.Strict as H
99+import qualified Data.HashMap.Strict as H
99−import qualified Data.HashSet as HashSet
100+import qualified Data.HashSet as HashSet
100−import qualified Data.IntMap as IntMap
101+import qualified Data.IntMap as IntMap
101−import qualified Data.IntSet as IntSet
102+import qualified Data.IntSet as IntSet
102−import qualified Data.List.NonEmpty as NE
103+import qualified Data.List.NonEmpty as NE
103−import qualified Data.Map as M
104+import qualified Data.Map as M
104−import qualified Data.Scientific as Scientific
105+import qualified Data.Scientific as Scientific
105−import qualified Data.Sequence as Seq
106+import qualified Data.Sequence as Seq
106−import qualified Data.Set as Set
107+import qualified Data.Set as Set
107−import qualified Data.Text as T
108+import qualified Data.Text as T
108−import qualified Data.Text.Encoding as T
109+import qualified Data.Text.Encoding as T
109−import qualified Data.Text.Lazy as LT
110+import qualified Data.Text.Lazy as LT
110−import qualified Data.Tree as Tree
111+import qualified Data.Tree as Tree
111−import qualified Data.Vector as V
112+import qualified Data.Vector as V
112−import qualified Data.Vector.Generic as VG
113+import qualified Data.Vector.Generic as VG
113−import qualified Data.Vector.Mutable as VM
114+import qualified Data.Vector.Mutable as VM
114−import qualified Data.Vector.Primitive as VP
115+import qualified Data.Vector.Primitive as VP
115−import qualified Data.Vector.Storable as VS
116+import qualified Data.Vector.Storable as VS
116−import qualified Data.Vector.Unboxed as VU
117+import qualified Data.Vector.Unboxed as VU
118toJSONPair :: (a -> Value) -> (b -> Value) -> (a, b) -> Value
119toJSONPair :: (a -> Value) -> (b -> Value) -> (a, b) -> Value
119−toJSONPair keySerialiser valSerializer (a, b) = Array $ V.create $ do
120+toJSONPair a b = liftToJSON2 a (listValue a) b (listValue b)
120− mv <- VM.unsafeNew 2
121− VM.unsafeWrite mv 0 (keySerialiser a)
122− VM.unsafeWrite mv 1 (valSerializer b)
124{-# INLINE toJSONPair #-}
121{-# INLINE toJSONPair #-}
126realFloatToJSON :: RealFloat a => a -> Value
123realFloatToJSON :: RealFloat a => a -> Value
@@ -309,7 +306,7 @@ instance KeyValue Pair where
310-- | Typeclass for types that can be used as the key of a map-like container
307-- | Typeclass for types that can be used as the key of a map-like container
311-- (like 'Map' or 'HashMap'). For example, since 'Text' has a 'ToJSONKey'
308-- (like 'Map' or 'HashMap'). For example, since 'Text' has a 'ToJSONKey'
312−-- instance and 'Char' has a 'ToJSON' instance, we can encode a value of
309+-- instance and 'Char' has a 'ToJSON' instance, we can encode a value of
313-- type 'Map' 'Text' 'Char':
310-- type 'Map' 'Text' 'Char':
315-- >>> LBC8.putStrLn $ encode $ Map.fromList [("foo" :: Text, 'a')]
312-- >>> LBC8.putStrLn $ encode $ Map.fromList [("foo" :: Text, 'a')]
@@ -355,16 +352,16 @@ instance KeyValue Pair where
355-- >>> let m = Map.fromList [(Foo 4 "bar",'a'),(Foo 6 "arg",'b')]
352-- >>> let m = Map.fromList [(Foo 4 "bar",'a'),(Foo 6 "arg",'b')]
356-- >>> LBC8.putStrLn $ encode m
353-- >>> LBC8.putStrLn $ encode m
357-- [[{"fooName":"bar","fooAge":4},"a"],[{"fooName":"arg","fooAge":6},"b"]]
354-- [[{"fooName":"bar","fooAge":4},"a"],[{"fooName":"arg","fooAge":6},"b"]]
359-- The next case to consider is if we have a type that is a
356-- The next case to consider is if we have a type that is a
360-- newtype wrapper around 'Text'. The recommended approach is to use
357-- newtype wrapper around 'Text'. The recommended approach is to use
361-- generalized newtype deriving:
358-- generalized newtype deriving:
363-- > newtype RecordId = RecordId { getRecordId :: Text}
360-- > newtype RecordId = RecordId { getRecordId :: Text}
364-- > deriving (Eq,Ord,ToJSONKey)
361-- > deriving (Eq,Ord,ToJSONKey)
366-- Then we may write:
363-- Then we may write:
368-- >>> LBC8.putStrLn $ encode $ Map.fromList [(RecordId "abc",'a')]
365-- >>> LBC8.putStrLn $ encode $ Map.fromList [(RecordId "abc",'a')]
369-- {"abc":"a"}
366-- {"abc":"a"}
@@ -382,7 +379,7 @@ instance KeyValue Pair where
382-- > instance ToJSONKey Color where
379-- > instance ToJSONKey Color where
383-- > toJSONKey = ToJSONKeyText f g
380-- > toJSONKey = ToJSONKeyText f g
384-- > where f = Text.pack . show
381-- > where f = Text.pack . show
385−-- > g = text . Text.pack . show
382+-- > g = text . Text.pack . show
386-- > -- text function is from Data.Aeson.Encoding
383-- > -- text function is from Data.Aeson.Encoding
388-- The situation of needing to turning function @a -> Text@ into
385-- The situation of needing to turning function @a -> Text@ into
@@ -391,7 +388,7 @@ instance KeyValue Pair where
392-- > instance ToJSONKey Color where
389-- > instance ToJSONKey Color where
393-- > toJSONKey = toJSONKeyText (Text.pack . show)
390-- > toJSONKey = toJSONKeyText (Text.pack . show)
395-- The performance of the above instance can be improved by
392-- The performance of the above instance can be improved by
396-- not using 'String' as an intermediate step when converting to
393-- not using 'String' as an intermediate step when converting to
397-- 'Text'. One option for improving performance would be to use
394-- 'Text'. One option for improving performance would be to use
@@ -400,7 +397,7 @@ instance KeyValue Pair where
400-- builder) is generated by encoding the 'Text' to a 'ByteString',
397-- builder) is generated by encoding the 'Text' to a 'ByteString',
401-- an intermediate step that could be avoided. The fastest possible
398-- an intermediate step that could be avoided. The fastest possible
402-- implementation would be:
399-- implementation would be:
404-- > -- Assuming that OverloadedStrings is enabled
401-- > -- Assuming that OverloadedStrings is enabled
405-- > instance ToJSONKey Color where
402-- > instance ToJSONKey Color where
406-- > toJSONKey = ToJSONKeyText f g
403-- > toJSONKey = ToJSONKeyText f g
@@ -417,23 +414,45 @@ class ToJSONKey a where
417 -- | Strategy for rendering the key for a map-like container.
414 -- | Strategy for rendering the key for a map-like container.
418 toJSONKey :: ToJSONKeyFunction a
415 toJSONKey :: ToJSONKeyFunction a
419 default toJSONKey :: ToJSON a => ToJSONKeyFunction a
416 default toJSONKey :: ToJSON a => ToJSONKeyFunction a
420− toJSONKey = ToJSONKeyValue (toJSON, toEncoding)
417+ toJSONKey = ToJSONKeyValue toJSON toEncoding
421 -- | This is similar in spirit to the 'showsList' method of 'Show'.
419 -- | This is similar in spirit to the 'showsList' method of 'Show'.
422 -- It makes it possible to give 'String' keys special treatment
420 -- It makes it possible to give 'String' keys special treatment
423 -- without using @OverlappingInstances@. End users should always
421 -- without using @OverlappingInstances@. End users should always
424 -- be able to use the default implementation of this method.
422 -- be able to use the default implementation of this method.
425 toJSONKeyList :: ToJSONKeyFunction [a]
423 toJSONKeyList :: ToJSONKeyFunction [a]
426 default toJSONKeyList :: ToJSON a => ToJSONKeyFunction [a]
424 default toJSONKeyList :: ToJSON a => ToJSONKeyFunction [a]
427− toJSONKeyList = ToJSONKeyValue (toJSON, toEncoding)
425+ toJSONKeyList = ToJSONKeyValue toJSON toEncoding
429data ToJSONKeyFunction a
427data ToJSONKeyFunction a
428+ = ToJSONKeyText !(a -> Text) !(a -> Encoding' Text)
430− = ToJSONKeyText (a -> Text, a -> Encoding) -- ^ key is encoded to string, produces object
429+ -- ^ key is encoded to string, produces object
430+ | ToJSONKeyValue !(a -> Value) !(a -> Encoding)
431− | ToJSONKeyValue (a -> Value, a -> Encoding) -- ^ key is encoded to value, produces array
431+ -- ^ key is encoded to value, produces array
433+-- | Helper for creating textual keys.
436+-- instance 'ToJSONKey' MyKey where
437+-- 'toJSONKey' = 'toJSONKeyText' myKeyToText
439+-- myKeyToText = Text.pack . show -- or showt from text-show
441+toJSONKeyText :: (a -> Text) -> ToJSONKeyFunction a
442+toJSONKeyText f = ToJSONKeyText f (E.text . f)
444+-- | TODO: should this be exported?
445+toJSONKeyTextEnc :: (a -> Encoding' Text) -> ToJSONKeyFunction a
446+toJSONKeyTextEnc e = ToJSONKeyText tot e
448+ -- TODO: dropAround is also used in stringEncoding, which is unfortunate atm
449+ tot = T.dropAround (== '"') . T.decodeLatin1 . L.toStrict . E.encodingToLazyByteString . e
451+-- | Contravariant map, as 'ToJSONKeyFunction' is a contravariant functor.
433contramapToJSONKeyFunction :: (b -> a) -> ToJSONKeyFunction a -> ToJSONKeyFunction b
452contramapToJSONKeyFunction :: (b -> a) -> ToJSONKeyFunction a -> ToJSONKeyFunction b
434contramapToJSONKeyFunction h x = case x of
453contramapToJSONKeyFunction h x = case x of
435− ToJSONKeyText (f,g) -> ToJSONKeyText (f . h, g . h)
454+ ToJSONKeyText f g -> ToJSONKeyText (f . h) (g . h)
436− ToJSONKeyValue (f,g) -> ToJSONKeyValue (f . h, g . h)
455+ ToJSONKeyValue f g -> ToJSONKeyValue (f . h) (g . h)
438-------------------------------------------------------------------------------
457-------------------------------------------------------------------------------
439-- Lifings of FromJSON and ToJSON to unary and binary type constructors
458-- Lifings of FromJSON and ToJSON to unary and binary type constructors
@@ -676,7 +695,7 @@ instance ( AllNullary (a :+: b) allNullary
676 -- 'allNullaryToStringTag' option is set they are encoded to
695 -- 'allNullaryToStringTag' option is set they are encoded to
677 -- strings. This distinction is made by 'sumToEncoding':
696 -- strings. This distinction is made by 'sumToEncoding':
678 gToEncoding opts pa te tel
697 gToEncoding opts pa te tel
679− = (unTagged :: Tagged allNullary Encoding -> Encoding)
698+ = (unTagged :: Tagged allNullary (Encoding) -> Encoding)
680 . sumToEncoding opts pa te tel
699 . sumToEncoding opts pa te tel
682instance (ToJSON1 f, GToEncoding One g) => GToEncoding One (f :.: g) where
701instance (ToJSON1 f, GToEncoding One g) => GToEncoding One (f :.: g) where
@@ -728,7 +747,7 @@ nonAllNullarySumToJSON opts pa tj tjl =
728class SumToEncoding arity f allNullary where
747class SumToEncoding arity f allNullary where
729 sumToEncoding :: Options -> Proxy arity
748 sumToEncoding :: Options -> Proxy arity
730 -> (a -> Encoding) -> ([a] -> Encoding)
749 -> (a -> Encoding) -> ([a] -> Encoding)
731− -> f a -> Tagged allNullary Encoding
750+ -> f a -> Tagged allNullary (Encoding)
733instance ( GetConName f
752instance ( GetConName f
734 , TaggedObjectEnc arity f
753 , TaggedObjectEnc arity f
@@ -822,29 +841,28 @@ instance ( IsRecord a isRecord
822 , Constructor c
841 , Constructor c
823 ) => TaggedObjectEnc arity (C1 c a) where
842 ) => TaggedObjectEnc arity (C1 c a) where
824 taggedObjectEnc opts pa tagFieldName contentsFieldName te tel v =
843 taggedObjectEnc opts pa tagFieldName contentsFieldName te tel v =
825− E.openCurly <>
844+ E.wrapObject $
826− (toEncoding tagFieldName <>
845+ (E.string tagFieldName ><
827− E.colon <>
846+ E.colon ><
828− toEncoding (constructorTagModifier opts (conName (undefined :: t c a p)))) <>
847+ toEncoding (constructorTagModifier opts (conName (undefined :: t c a p)))) ><
829− ((unTagged :: Tagged isRecord Encoding -> Encoding) .
848+ ((unTagged :: Tagged isRecord (Encoding) -> Encoding) .
830− taggedObjectEnc' opts pa contentsFieldName te tel . unM1 $ v) <>
849+ taggedObjectEnc' opts pa contentsFieldName te tel . unM1 $ v)
833class TaggedObjectEnc' arity f isRecord where
851class TaggedObjectEnc' arity f isRecord where
834 taggedObjectEnc' :: Options -> Proxy arity
852 taggedObjectEnc' :: Options -> Proxy arity
835 -> String -> (a -> Encoding) -> ([a] -> Encoding)
853 -> String -> (a -> Encoding) -> ([a] -> Encoding)
836− -> f a -> Tagged isRecord Encoding
854+ -> f a -> Tagged isRecord (Encoding)
838instance OVERLAPPING_ TaggedObjectEnc' arity U1 False where
856instance OVERLAPPING_ TaggedObjectEnc' arity U1 False where
839− taggedObjectEnc' _ _ _ _ _ _ = Tagged mempty
857+ taggedObjectEnc' _ _ _ _ _ _ = Tagged E.empty
841instance (RecordToEncoding arity f) => TaggedObjectEnc' arity f True where
859instance (RecordToEncoding arity f) => TaggedObjectEnc' arity f True where
842− taggedObjectEnc' opts pa _ te tel = Tagged . (E.comma <>) . fst
860+ taggedObjectEnc' opts pa _ te tel = Tagged . (E.comma ><) . fst
843 . recordToEncoding opts pa te tel
861 . recordToEncoding opts pa te tel
845instance (GToEncoding arity f) => TaggedObjectEnc' arity f False where
863instance (GToEncoding arity f) => TaggedObjectEnc' arity f False where
846 taggedObjectEnc' opts pa contentsFieldName te tel =
864 taggedObjectEnc' opts pa contentsFieldName te tel =
847− Tagged . (\z -> E.comma <> toEncoding contentsFieldName <> E.colon <> z) .
865+ Tagged . (\z -> E.comma >< toEncoding contentsFieldName >< E.colon >< z) .
848 gToEncoding opts pa te tel
866 gToEncoding opts pa te tel
850--------------------------------------------------------------------------------
868--------------------------------------------------------------------------------
@@ -946,13 +964,13 @@ class ConsToEncoding' arity f isRecord where
946 consToEncoding' :: Options -> Proxy arity
964 consToEncoding' :: Options -> Proxy arity
947 -> Bool -- ^ Are we a record with one field?
965 -> Bool -- ^ Are we a record with one field?
948 -> (a -> Encoding) -> ([a] -> Encoding)
966 -> (a -> Encoding) -> ([a] -> Encoding)
949− -> f a -> Tagged isRecord Encoding
967+ -> f a -> Tagged isRecord (Encoding)
951instance ( IsRecord f isRecord
969instance ( IsRecord f isRecord
952 , ConsToEncoding' arity f isRecord
970 , ConsToEncoding' arity f isRecord
953 ) => ConsToEncoding arity f where
971 ) => ConsToEncoding arity f where
954 consToEncoding opts pa te tel =
972 consToEncoding opts pa te tel =
955− (unTagged :: Tagged isRecord Encoding -> Encoding)
973+ (unTagged :: Tagged isRecord (Encoding) -> (Encoding))
956 . consToEncoding' opts pa (isUnary (undefined :: f a)) te tel
974 . consToEncoding' opts pa (isUnary (undefined :: f a)) te tel
958instance (RecordToEncoding arity f) => ConsToEncoding' arity f True where
976instance (RecordToEncoding arity f) => ConsToEncoding' arity f True where
@@ -1003,39 +1021,40 @@ class RecordToEncoding arity f where
1003 -- of the field (without the key); 'Nothing' otherwise
1021 -- of the field (without the key); 'Nothing' otherwise
1004 recordToEncoding :: Options -> Proxy arity
1022 recordToEncoding :: Options -> Proxy arity
1005 -> (a -> Encoding) -> ([a] -> Encoding)
1023 -> (a -> Encoding) -> ([a] -> Encoding)
1006− -> f a -> (Encoding, Maybe Encoding)
1024+ -> f a -> (Encoding, Maybe (Encoding))
1008instance ( RecordToEncoding arity a
1026instance ( RecordToEncoding arity a
1009 , RecordToEncoding arity b
1027 , RecordToEncoding arity b
1010 ) => RecordToEncoding arity (a :*: b) where
1028 ) => RecordToEncoding arity (a :*: b) where
1011 recordToEncoding opts pa te tel (a :*: b) | omitNothingFields opts =
1029 recordToEncoding opts pa te tel (a :*: b) | omitNothingFields opts =
1012− (mconcat $ intersperse E.comma $
1030+ (E.econcat $ intersperse E.comma $
1013 filter (not . E.nullEncoding)
1031 filter (not . E.nullEncoding)
1014 [ fst (recordToEncoding opts pa te tel a)
1032 [ fst (recordToEncoding opts pa te tel a)
1015 , fst (recordToEncoding opts pa te tel b) ]
1033 , fst (recordToEncoding opts pa te tel b) ]
1016 , Nothing)
1034 , Nothing)
1017 recordToEncoding opts pa te tel (a :*: b) =
1035 recordToEncoding opts pa te tel (a :*: b) =
1018− (fst (recordToEncoding opts pa te tel a) <> E.comma <>
1036+ (fst (recordToEncoding opts pa te tel a) >< E.comma ><
1019 fst (recordToEncoding opts pa te tel b),
1037 fst (recordToEncoding opts pa te tel b),
1020 Nothing)
1038 Nothing)
1022instance (Selector s, GToEncoding arity a) => RecordToEncoding arity (S1 s a) where
1041instance (Selector s, GToEncoding arity a) => RecordToEncoding arity (S1 s a) where
1023 recordToEncoding = fieldToEncoding
1042 recordToEncoding = fieldToEncoding
1025instance OVERLAPPING_ (Selector s, ToJSON a) =>
1044instance OVERLAPPING_ (Selector s, ToJSON a) =>
1026 RecordToEncoding arity (S1 s (K1 i (Maybe a))) where
1045 RecordToEncoding arity (S1 s (K1 i (Maybe a))) where
1027 recordToEncoding opts _ _ _ (M1 k1) | omitNothingFields opts
1046 recordToEncoding opts _ _ _ (M1 k1) | omitNothingFields opts
1028− , K1 Nothing <- k1 = (mempty, Nothing)
1047+ , K1 Nothing <- k1 = (E.empty, Nothing)
1029 recordToEncoding opts pa te tel m1 = fieldToEncoding opts pa te tel m1
1048 recordToEncoding opts pa te tel m1 = fieldToEncoding opts pa te tel m1
1031fieldToEncoding :: (Selector s, GToEncoding arity a)
1050fieldToEncoding :: (Selector s, GToEncoding arity a)
1032 => Options -> Proxy arity
1051 => Options -> Proxy arity
1033 -> (p -> Encoding) -> ([p] -> Encoding)
1052 -> (p -> Encoding) -> ([p] -> Encoding)
1034− -> S1 s a p -> (Encoding, Maybe Encoding)
1053+ -> S1 s a p -> (Encoding, Maybe (Encoding))
1035fieldToEncoding opts pa te tel m1 =
1054fieldToEncoding opts pa te tel m1 =
1036 let keyBuilder = toEncoding (fieldLabelModifier opts $ selName m1)
1055 let keyBuilder = toEncoding (fieldLabelModifier opts $ selName m1)
1037 valueBuilder = gToEncoding opts pa te tel (unM1 m1)
1056 valueBuilder = gToEncoding opts pa te tel (unM1 m1)
1038− in (keyBuilder <> E.colon <> valueBuilder, Just valueBuilder)
1057+ in (keyBuilder >< E.colon >< valueBuilder, Just valueBuilder)
1040--------------------------------------------------------------------------------
1059--------------------------------------------------------------------------------
@@ -1070,21 +1089,20 @@ instance OVERLAPPABLE_ (GToJSON arity a) => WriteProduct arity a where
1070class EncodeProduct arity f where
1089class EncodeProduct arity f where
1071 encodeProduct :: Options -> Proxy arity
1090 encodeProduct :: Options -> Proxy arity
1072 -> (a -> Encoding) -> ([a] -> Encoding)
1091 -> (a -> Encoding) -> ([a] -> Encoding)
1073− -> f a -> Encoding
1092+ -> f a -> Encoding' E.InArray
1075instance ( EncodeProduct arity a
1094instance ( EncodeProduct arity a
1076 , EncodeProduct arity b
1095 , EncodeProduct arity b
1077 ) => EncodeProduct arity (a :*: b) where
1096 ) => EncodeProduct arity (a :*: b) where
1078 encodeProduct opts pa te tel (a :*: b) | omitNothingFields opts =
1097 encodeProduct opts pa te tel (a :*: b) | omitNothingFields opts =
1079− mconcat $ intersperse E.comma $
1098+ E.econcat $ intersperse E.comma $
1080 filter (not . E.nullEncoding)
1099 filter (not . E.nullEncoding)
1081 [encodeProduct opts pa te tel a, encodeProduct opts pa te tel b]
1100 [encodeProduct opts pa te tel a, encodeProduct opts pa te tel b]
1082− encodeProduct opts pa te tel (a :*: b) = encodeProduct opts pa te tel a <>
1101+ encodeProduct opts pa te tel (a :*: b) = encodeProduct opts pa te tel a >*<
1084 encodeProduct opts pa te tel b
1102 encodeProduct opts pa te tel b
1086instance OVERLAPPABLE_ (GToEncoding arity a) => EncodeProduct arity a where
1104instance OVERLAPPABLE_ (GToEncoding arity a) => EncodeProduct arity a where
1087− encodeProduct opts = gToEncoding opts
1105+ encodeProduct opts pa te tel a = E.retagEncoding $ gToEncoding opts pa te tel a
1089--------------------------------------------------------------------------------
1107--------------------------------------------------------------------------------
@@ -1130,12 +1148,12 @@ instance ( GToEncoding arity a
1130 , Constructor c
1148 , Constructor c
1131 ) => ObjectWithSingleFieldEnc arity (C1 c a) where
1149 ) => ObjectWithSingleFieldEnc arity (C1 c a) where
1132 objectWithSingleFieldEnc opts pa te tel v =
1150 objectWithSingleFieldEnc opts pa te tel v =
1133− E.openCurly <>
1151+ E.openCurly ><
1134 toEncoding
1152 toEncoding
1135 (constructorTagModifier opts
1153 (constructorTagModifier opts
1136− (conName (undefined :: t c a p))) <>
1154+ (conName (undefined :: t c a p))) ><
1137− E.colon <>
1155+ E.colon ><
1138− gToEncoding opts pa te tel v <>
1156+ gToEncoding opts pa te tel v ><
1139 E.closeCurly
1157 E.closeCurly
1141-------------------------------------------------------------------------------
1159-------------------------------------------------------------------------------
@@ -1146,21 +1164,6 @@ instance ( GToEncoding arity a
1147-------------------------------------------------------------------------------
1165-------------------------------------------------------------------------------
1149−instance ToJSON1 Identity where
1150− liftToJSON t _ (Identity a) = t a
1151− {-# INLINE liftToJSON #-}
1153− liftToEncoding t _ (Identity a) = t a
1154− {-# INLINE liftToEncoding #-}
1156−instance (ToJSON a) => ToJSON (Identity a) where
1158− {-# INLINE toJSON #-}
1160− toEncoding = toEncoding1
1161− {-# INLINE toEncoding #-}
1164instance ToJSON2 Const where
1167instance ToJSON2 Const where
1165 liftToJSON2 t _ _ _ (Const x) = t x
1168 liftToJSON2 t _ _ _ (Const x) = t x
1166 {-# INLINE liftToJSON2 #-}
1169 {-# INLINE liftToJSON2 #-}
@@ -1237,10 +1240,7 @@ instance ToJSON Bool where
1237 {-# INLINE toEncoding #-}
1240 {-# INLINE toEncoding #-}
1239instance ToJSONKey Bool where
1242instance ToJSONKey Bool where
1240− toJSONKey = ToJSONKeyText
1241− ( (\x -> if x then "true" else "false")
1242− , (\x -> toEncoding $ if x then ("true" :: Text) else "false")
1243+ toJSONKey = toJSONKeyText $ \x -> if x then "true" else "false"
1246instance ToJSON Ordering where
1246instance ToJSON Ordering where
@@ -1485,9 +1485,10 @@ instance ToJSON Text where
1485 {-# INLINE toEncoding #-}
1485 {-# INLINE toEncoding #-}
1487instance ToJSONKey Text where
1487instance ToJSONKey Text where
1488− toJSONKey = ToJSONKeyText (id, toEncoding)
1488+ toJSONKey = toJSONKeyText id
1489 {-# INLINE toJSONKey #-}
1489 {-# INLINE toJSONKey #-}
1491instance ToJSON LT.Text where
1492instance ToJSON LT.Text where
1492 toJSON = String . LT.toStrict
1493 toJSON = String . LT.toStrict
1493 {-# INLINE toJSON #-}
1494 {-# INLINE toJSON #-}
@@ -1495,6 +1496,10 @@ instance ToJSON LT.Text where
1495 toEncoding = E.lazyText
1496 toEncoding = E.lazyText
1496 {-# INLINE toEncoding #-}
1497 {-# INLINE toEncoding #-}
1499+instance ToJSONKey LT.Text where
1500+ toJSONKey = toJSONKeyText LT.toStrict
1498instance ToJSON Version where
1503instance ToJSON Version where
1499 toJSON = toJSON . showVersion
1504 toJSON = toJSON . showVersion
1500 {-# INLINE toJSON #-}
1505 {-# INLINE toJSON #-}
@@ -1502,6 +1507,9 @@ instance ToJSON Version where
1502 toEncoding = toEncoding . showVersion
1507 toEncoding = toEncoding . showVersion
1503 {-# INLINE toEncoding #-}
1508 {-# INLINE toEncoding #-}
1510+instance ToJSONKey Version where
1511+ toJSONKey = toJSONKeyText (T.pack . showVersion)
1505-------------------------------------------------------------------------------
1513-------------------------------------------------------------------------------
1506-- semigroups NonEmpty
1514-- semigroups NonEmpty
1507-------------------------------------------------------------------------------
1515-------------------------------------------------------------------------------
@@ -1552,6 +1560,79 @@ instance (ToJSON a) => ToJSON (DList.DList a) where
1552 toEncoding = toEncoding1
1560 toEncoding = toEncoding1
1553 {-# INLINE toEncoding #-}
1561 {-# INLINE toEncoding #-}
1563+-------------------------------------------------------------------------------
1564+-- transformers - Functors
1565+-------------------------------------------------------------------------------
1567+instance ToJSON1 Identity where
1568+ liftToJSON t _ (Identity a) = t a
1569+ {-# INLINE liftToJSON #-}
1571+ liftToJSONList _ tl xs = tl (map runIdentity xs)
1572+ {-# INLINE liftToJSONList #-}
1574+ liftToEncoding t _ (Identity a) = t a
1575+ {-# INLINE liftToEncoding #-}
1577+ liftToEncodingList _ tl xs = tl (map runIdentity xs)
1578+ {-# INLINE liftToEncodingList #-}
1580+instance (ToJSON a) => ToJSON (Identity a) where
1582+ {-# INLINE toJSON #-}
1584+ toJSONList = liftToJSONList toJSON toJSONList
1585+ {-# INLINE toJSONList #-}
1587+ toEncoding = toEncoding1
1588+ {-# INLINE toEncoding #-}
1590+ toEncodingList = liftToEncodingList toEncoding toEncodingList
1591+ {-# INLINE toEncodingList #-}
1593+instance (ToJSONKey a, ToJSON a) => ToJSONKey (Identity a) where
1594+ toJSONKey = contramapToJSONKeyFunction runIdentity toJSONKey
1595+ toJSONKeyList = contramapToJSONKeyFunction (map runIdentity) toJSONKeyList
1598+instance (ToJSON1 f, ToJSON1 g) => ToJSON1 (Compose f g) where
1599+ liftToJSON tv tvl (Compose x) = liftToJSON g gl x
1601+ g = liftToJSON tv tvl
1602+ gl = liftToJSONList tv tvl
1603+ {-# INLINE liftToJSON #-}
1605+ liftToJSONList te tel xs = liftToJSONList g gl (map getCompose xs)
1607+ g = liftToJSON te tel
1608+ gl = liftToJSONList te tel
1609+ {-# INLINE liftToJSONList #-}
1611+ liftToEncoding te tel (Compose x) = liftToEncoding g gl x
1613+ g = liftToEncoding te tel
1614+ gl = liftToEncodingList te tel
1615+ {-# INLINE liftToEncoding #-}
1617+ liftToEncodingList te tel xs = liftToEncodingList g gl (map getCompose xs)
1619+ g = liftToEncoding te tel
1620+ gl = liftToEncodingList te tel
1621+ {-# INLINE liftToEncodingList #-}
1623+instance (ToJSON1 f, ToJSON1 g, ToJSON a) => ToJSON (Compose f g a) where
1625+ {-# INLINE toJSON #-}
1627+ toJSONList = liftToJSONList toJSON toJSONList
1628+ {-# INLINE toJSONList #-}
1630+ toEncoding = toEncoding1
1631+ {-# INLINE toEncoding #-}
1633+ toEncodingList = liftToEncodingList toEncoding toEncodingList
1634+ {-# INLINE toEncodingList #-}
1555-------------------------------------------------------------------------------
1636-------------------------------------------------------------------------------
1556-- containers
1637-- containers
1557-------------------------------------------------------------------------------
1638-------------------------------------------------------------------------------
@@ -1617,14 +1698,14 @@ instance ToJSON a => ToJSON (IntMap.IntMap a) where
1618instance ToJSONKey k => ToJSON1 (M.Map k) where
1699instance ToJSONKey k => ToJSON1 (M.Map k) where
1619 liftToJSON g _ = case toJSONKey of
1700 liftToJSON g _ = case toJSONKey of
1620− ToJSONKeyText (f,_) -> Object . mapHashKeyVal f g
1701+ ToJSONKeyText f _ -> Object . mapHashKeyVal f g
1621− ToJSONKeyValue (f,_) -> Array . V.fromList . map (toJSONPair f g) . M.toList
1702+ ToJSONKeyValue f _ -> Array . V.fromList . map (toJSONPair f g) . M.toList
1622 {-# INLINE liftToJSON #-}
1703 {-# INLINE liftToJSON #-}
1624 -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> M.Map k a -> Encoding
1705 -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> M.Map k a -> Encoding
1625 liftToEncoding g _ = case toJSONKey of
1706 liftToEncoding g _ = case toJSONKey of
1626− ToJSONKeyText (_,f) -> dict f g M.foldrWithKey
1707+ ToJSONKeyText _ f -> dict f g M.foldrWithKey
1627− ToJSONKeyValue (_,f) -> listEncoding (pairEncoding f) . M.toList
1708+ ToJSONKeyValue _ f -> listEncoding (pairEncoding f) . M.toList
1629 -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
1710 -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
1630 pairEncoding f (a, b) = tuple $ f a >*< g b
1711 pairEncoding f (a, b) = tuple $ f a >*< g b
@@ -1736,14 +1817,14 @@ instance (ToJSON a) => ToJSON (HashSet.HashSet a) where
1737instance ToJSONKey k => ToJSON1 (H.HashMap k) where
1818instance ToJSONKey k => ToJSON1 (H.HashMap k) where
1738 liftToJSON g _ = case toJSONKey of
1819 liftToJSON g _ = case toJSONKey of
1739− ToJSONKeyText (f,_) -> Object . mapKeyVal f g
1820+ ToJSONKeyText f _ -> Object . mapKeyVal f g
1740− ToJSONKeyValue (f,_) -> Array . V.fromList . map (toJSONPair f g) . H.toList
1821+ ToJSONKeyValue f _ -> Array . V.fromList . map (toJSONPair f g) . H.toList
1741 {-# INLINE liftToJSON #-}
1822 {-# INLINE liftToJSON #-}
1743 -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> H.HashMap k a -> Encoding
1824 -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> H.HashMap k a -> Encoding
1744 liftToEncoding g _ = case toJSONKey of
1825 liftToEncoding g _ = case toJSONKey of
1745− ToJSONKeyText (_,f) -> dict f g H.foldrWithKey
1826+ ToJSONKeyText _ f -> dict f g H.foldrWithKey
1746− ToJSONKeyValue (_,f) -> listEncoding (pairEncoding f) . H.toList
1827+ ToJSONKeyValue _ f -> listEncoding (pairEncoding f) . H.toList
1748 -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
1829 -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
1749 pairEncoding f (a, b) = tuple $ f a >*< g b
1830 pairEncoding f (a, b) = tuple $ f a >*< g b
@@ -1823,13 +1904,12 @@ instance ToJSONKey UTCTime where
1823 toJSONKey = toJSONKeyTextEnc E.utcTime
1904 toJSONKey = toJSONKeyTextEnc E.utcTime
1825-- | Encode something t a JSON string.
1906-- | Encode something t a JSON string.
1826−stringEncoding :: Encoding -> Value
1907+stringEncoding :: Encoding' Text -> Value
1827stringEncoding = String
1908stringEncoding = String
1828 . T.dropAround (== '"')
1909 . T.dropAround (== '"')
1829 . T.decodeLatin1
1910 . T.decodeLatin1
1830 . L.toStrict
1911 . L.toStrict
1831− . B.toLazyByteString
1912+ . E.encodingToLazyByteString
1833{-# INLINE stringEncoding #-}
1913{-# INLINE stringEncoding #-}
1835instance ToJSON NominalDiffTime where
1915instance ToJSON NominalDiffTime where
@@ -1922,29 +2002,17 @@ instance ToJSONKey b => ToJSONKey (Tagged a b) where
1922-- Instances for converting t map keys
2002-- Instances for converting t map keys
1923-------------------------------------------------------------------------------
2003-------------------------------------------------------------------------------
1925−-- | TODO: Move ToJSONKEyFunction to .Types(.Internal),
1926−-- export and document this function from there
1927−toJSONKeyTextEnc :: (a -> Encoding) -> ToJSONKeyFunction a
1928−toJSONKeyTextEnc e = ToJSONKeyText
1929− -- TODO: dropAround is also used in stringEncoding, which is unfortunate atm
1930− ( T.dropAround (== '"') . T.decodeLatin1 . L.toStrict . B.toLazyByteString . fromEncoding . e
1934instance (ToJSON a, ToJSON b) => ToJSONKey (a,b)
2005instance (ToJSON a, ToJSON b) => ToJSONKey (a,b)
1935instance (ToJSON a, ToJSON b, ToJSON c) => ToJSONKey (a,b,c)
2006instance (ToJSON a, ToJSON b, ToJSON c) => ToJSONKey (a,b,c)
1936instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSONKey (a,b,c,d)
2007instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSONKey (a,b,c,d)
1938instance ToJSONKey Char where
2009instance ToJSONKey Char where
1939− toJSONKey = ToJSONKeyText (T.singleton, toEncoding)
2010+ toJSONKey = ToJSONKeyText T.singleton (E.string . (:[]))
1940− toJSONKeyList = ToJSONKeyText (T.pack, toEncoding . T.pack)
2011+ toJSONKeyList = toJSONKeyText T.pack
1942instance (ToJSONKey a, ToJSON a) => ToJSONKey [a] where
2013instance (ToJSONKey a, ToJSON a) => ToJSONKey [a] where
1943 toJSONKey = toJSONKeyList
2014 toJSONKey = toJSONKeyList
1945−instance (ToJSONKey a, ToJSON a) => ToJSONKey (Identity a) where
1946− toJSONKey = contramapToJSONKeyFunction runIdentity toJSONKey
1948-------------------------------------------------------------------------------
2016-------------------------------------------------------------------------------
1949-- Tuple instances, see tuple-instances-to.hs
2017-- Tuple instances, see tuple-instances-to.hs
1950-------------------------------------------------------------------------------
2018-------------------------------------------------------------------------------