@@ -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(..)
@@ -413,22 +414,44 @@ class ToJSONKey a where
413 -- container.
414 -- container.
414 toJSONKey :: ToJSONKeyFunction a
415 toJSONKey :: ToJSONKeyFunction a
415 default toJSONKey :: ToJSON a => ToJSONKeyFunction a
416 default toJSONKey :: ToJSON a => ToJSONKeyFunction a
416− toJSONKey = ToJSONKeyValue (toJSON, toEncoding)
417+ toJSONKey = ToJSONKeyValue toJSON toEncoding
417 -- | This is similar in spirit to the 'showsList' method of 'Show'.
419 -- | This is similar in spirit to the 'showsList' method of 'Show'.
418 -- It makes it possible to give 'String' keys special treatment
420 -- It makes it possible to give 'String' keys special treatment
419 -- without using @OverlappingInstances@.
421 -- without using @OverlappingInstances@.
420 toJSONKeyList :: ToJSONKeyFunction [a]
422 toJSONKeyList :: ToJSONKeyFunction [a]
421 default toJSONKeyList :: ToJSON a => ToJSONKeyFunction [a]
423 default toJSONKeyList :: ToJSON a => ToJSONKeyFunction [a]
422− toJSONKeyList = ToJSONKeyValue (toJSON, toEncoding)
424+ toJSONKeyList = ToJSONKeyValue toJSON toEncoding
424data ToJSONKeyFunction a
426data ToJSONKeyFunction a
427+ = ToJSONKeyText !(a -> Text) !(a -> Encoding' Text)
425− = ToJSONKeyText (a -> Text, a -> Encoding' Text) -- ^ key is encoded to string, produces object
428+ -- ^ key is encoded to string, produces object
429+ | ToJSONKeyValue !(a -> Value) !(a -> Encoding)
426− | ToJSONKeyValue (a -> Value, a -> Encoding) -- ^ key is encoded to value, produces array
430+ -- ^ key is encoded to value, produces array
432+-- | Helper for creating textual keys.
435+-- instance 'ToJSONKey' MyKey where
436+-- 'toJSONKey' = 'toJSONKeyText' myKeyToText
438+-- myKeyToText = Text.pack . show -- or showt from text-show
440+toJSONKeyText :: (a -> Text) -> ToJSONKeyFunction a
441+toJSONKeyText f = ToJSONKeyText f (E.text . f)
443+-- | TODO: should this be exported?
444+toJSONKeyTextEnc :: (a -> Encoding' Text) -> ToJSONKeyFunction a
445+toJSONKeyTextEnc e = ToJSONKeyText tot e
447+ -- TODO: dropAround is also used in stringEncoding, which is unfortunate atm
448+ tot = T.dropAround (== '"') . T.decodeLatin1 . L.toStrict . E.encodingToLazyByteString . e
450+-- | Contravariant map, as 'ToJSONKeyFunction' is a contravariant functor.
428contramapToJSONKeyFunction :: (b -> a) -> ToJSONKeyFunction a -> ToJSONKeyFunction b
451contramapToJSONKeyFunction :: (b -> a) -> ToJSONKeyFunction a -> ToJSONKeyFunction b
429contramapToJSONKeyFunction h x = case x of
452contramapToJSONKeyFunction h x = case x of
430− ToJSONKeyText (f,g) -> ToJSONKeyText (f . h, g . h)
453+ ToJSONKeyText f g -> ToJSONKeyText (f . h) (g . h)
431− ToJSONKeyValue (f,g) -> ToJSONKeyValue (f . h, g . h)
454+ ToJSONKeyValue f g -> ToJSONKeyValue (f . h) (g . h)
433-------------------------------------------------------------------------------
456-------------------------------------------------------------------------------
434-- Lifings of FromJSON and ToJSON to unary and binary type constructors
457-- Lifings of FromJSON and ToJSON to unary and binary type constructors
@@ -1231,10 +1254,7 @@ instance ToJSON Bool where
1231 {-# INLINE toEncoding #-}
1254 {-# INLINE toEncoding #-}
1233instance ToJSONKey Bool where
1256instance ToJSONKey Bool where
1234− toJSONKey = ToJSONKeyText
1235− ( (\x -> if x then "true" else "false")
1236− , (\x -> E.text $ if x then "true"else "false")
1257+ toJSONKey = toJSONKeyText $ \x -> if x then "true" else "false"
1240instance ToJSON Ordering where
1260instance ToJSON Ordering where
@@ -1479,7 +1499,7 @@ instance ToJSON Text where
1479 {-# INLINE toEncoding #-}
1499 {-# INLINE toEncoding #-}
1481instance ToJSONKey Text where
1501instance ToJSONKey Text where
1482− toJSONKey = ToJSONKeyText (id, E.text)
1502+ toJSONKey = toJSONKeyText id
1483 {-# INLINE toJSONKey #-}
1503 {-# INLINE toJSONKey #-}
1485instance ToJSON LT.Text where
1505instance ToJSON LT.Text where
@@ -1611,14 +1631,14 @@ instance ToJSON a => ToJSON (IntMap.IntMap a) where
1612instance ToJSONKey k => ToJSON1 (M.Map k) where
1632instance ToJSONKey k => ToJSON1 (M.Map k) where
1613 liftToJSON g _ = case toJSONKey of
1633 liftToJSON g _ = case toJSONKey of
1614− ToJSONKeyText (f,_) -> Object . mapHashKeyVal f g
1634+ ToJSONKeyText f _ -> Object . mapHashKeyVal f g
1615− ToJSONKeyValue (f,_) -> Array . V.fromList . map (toJSONPair f g) . M.toList
1635+ ToJSONKeyValue f _ -> Array . V.fromList . map (toJSONPair f g) . M.toList
1616 {-# INLINE liftToJSON #-}
1636 {-# INLINE liftToJSON #-}
1618 -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> M.Map k a -> Encoding
1638 -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> M.Map k a -> Encoding
1619 liftToEncoding g _ = case toJSONKey of
1639 liftToEncoding g _ = case toJSONKey of
1620− ToJSONKeyText (_,f) -> dict f g M.foldrWithKey
1640+ ToJSONKeyText _ f -> dict f g M.foldrWithKey
1621− ToJSONKeyValue (_,f) -> listEncoding (pairEncoding f) . M.toList
1641+ ToJSONKeyValue _ f -> listEncoding (pairEncoding f) . M.toList
1623 -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
1643 -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
1624 pairEncoding f (a, b) = tuple $ f a >*< g b
1644 pairEncoding f (a, b) = tuple $ f a >*< g b
@@ -1730,14 +1750,14 @@ instance (ToJSON a) => ToJSON (HashSet.HashSet a) where
1731instance ToJSONKey k => ToJSON1 (H.HashMap k) where
1751instance ToJSONKey k => ToJSON1 (H.HashMap k) where
1732 liftToJSON g _ = case toJSONKey of
1752 liftToJSON g _ = case toJSONKey of
1733− ToJSONKeyText (f,_) -> Object . mapKeyVal f g
1753+ ToJSONKeyText f _ -> Object . mapKeyVal f g
1734− ToJSONKeyValue (f,_) -> Array . V.fromList . map (toJSONPair f g) . H.toList
1754+ ToJSONKeyValue f _ -> Array . V.fromList . map (toJSONPair f g) . H.toList
1735 {-# INLINE liftToJSON #-}
1755 {-# INLINE liftToJSON #-}
1737 -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> H.HashMap k a -> Encoding
1757 -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> H.HashMap k a -> Encoding
1738 liftToEncoding g _ = case toJSONKey of
1758 liftToEncoding g _ = case toJSONKey of
1739− ToJSONKeyText (_,f) -> dict f g H.foldrWithKey
1759+ ToJSONKeyText _ f -> dict f g H.foldrWithKey
1740− ToJSONKeyValue (_,f) -> listEncoding (pairEncoding f) . H.toList
1760+ ToJSONKeyValue _ f -> listEncoding (pairEncoding f) . H.toList
1742 -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
1762 -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
1743 pairEncoding f (a, b) = tuple $ f a >*< g b
1763 pairEncoding f (a, b) = tuple $ f a >*< g b
@@ -1915,22 +1935,13 @@ instance ToJSONKey b => ToJSONKey (Tagged a b) where
1915-- Instances for converting t map keys
1935-- Instances for converting t map keys
1916-------------------------------------------------------------------------------
1936-------------------------------------------------------------------------------
1918−-- | TODO: Move ToJSONKEyFunction to .Types(.Internal),
1919−-- export and document this function from there
1920−toJSONKeyTextEnc :: (a -> Encoding' Text) -> ToJSONKeyFunction a
1921−toJSONKeyTextEnc e = ToJSONKeyText
1922− -- TODO: dropAround is also used in stringEncoding, which is unfortunate atm
1923− ( T.dropAround (== '"') . T.decodeLatin1 . L.toStrict . E.encodingToLazyByteString . e
1927instance (ToJSON a, ToJSON b) => ToJSONKey (a,b)
1938instance (ToJSON a, ToJSON b) => ToJSONKey (a,b)
1928instance (ToJSON a, ToJSON b, ToJSON c) => ToJSONKey (a,b,c)
1939instance (ToJSON a, ToJSON b, ToJSON c) => ToJSONKey (a,b,c)
1929instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSONKey (a,b,c,d)
1940instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSONKey (a,b,c,d)
1931instance ToJSONKey Char where
1942instance ToJSONKey Char where
1932− toJSONKey = ToJSONKeyText (T.singleton, E.string . (:[]))
1943+ toJSONKey = ToJSONKeyText T.singleton (E.string . (:[]))
1933− toJSONKeyList = ToJSONKeyText (T.pack, E.text . T.pack)
1944+ toJSONKeyList = toJSONKeyText T.pack
1935instance (ToJSONKey a, ToJSON a) => ToJSONKey [a] where
1946instance (ToJSONKey a, ToJSON a) => ToJSONKey [a] where
1936 toJSONKey = toJSONKeyList
1947 toJSONKey = toJSONKeyList