@@ -38,7 +38,7 @@ module Data.Aeson.Types
3838import Control.Applicative
3939import Control.DeepSeq (NFData(..))
4040import Control.Monad (MonadPlus(..))
41−import Data.Aeson.Functions (hashMap, mapHash, transformMap)
41+import Data.Aeson.Functions
4242import Data.Attoparsec.Char8 (Number(..))
4343import Data.Data (Data)
4444import Data.Int (Int8, Int16, Int32, Int64)
@@ -48,7 +48,7 @@ import Data.Monoid (Monoid(..))
4848import Data.Ratio (Ratio)
4949import Data.String (IsString(..))
5050import Data.Text (Text, pack, unpack)
51−import Data.Text.Encoding (decodeUtf8, encodeUtf8)
51+import Data.Text.Encoding (encodeUtf8)
5252import Data.Time.Clock (UTCTime)
5353import Data.Time.Format (FormatTime, formatTime, parseTime)
5454import Data.Typeable (Typeable)
@@ -458,7 +458,7 @@ instance FromJSON LT.Text where
458458 {-# INLINE parseJSON #-}
459459
460460instance ToJSON B.ByteString where
461− toJSON = String . decodeUtf8
461+ toJSON = String . decode
462462 {-# INLINE toJSON #-}
463463
464464instance FromJSON B.ByteString where
@@ -467,11 +467,11 @@ instance FromJSON B.ByteString where
467467 {-# INLINE parseJSON #-}
468468
469469instance ToJSON LB.ByteString where
470− toJSON = toJSON . B.concat . LB.toChunks
470+ toJSON = toJSON . strict
471471 {-# INLINE toJSON #-}
472472
473473instance FromJSON LB.ByteString where
474− parseJSON (String t) = pure . LB.fromChunks . (:[]) . encodeUtf8 $ t
474+ parseJSON (String t) = pure . lazy $ t
475475 parseJSON _ = empty
476476 {-# INLINE parseJSON #-}
477477
@@ -480,7 +480,7 @@ instance (ToJSON a) => ToJSON [a] where
480480 {-# INLINE toJSON #-}
481481
482482instance (FromJSON a) => FromJSON [a] where
483− parseJSON (Array a) = mapA parseJSON (V.toList a)
483+ parseJSON (Array a) = mapM parseJSON (V.toList a)
484484 parseJSON _ = empty
485485 {-# INLINE parseJSON #-}
486486
@@ -489,7 +489,7 @@ instance (ToJSON a) => ToJSON (Vector a) where
489489 {-# INLINE toJSON #-}
490490
491491instance (FromJSON a) => FromJSON (Vector a) where
492− parseJSON (Array a) = V.fromList <$> mapA parseJSON (V.toList a)
492+ parseJSON (Array a) = V.mapM parseJSON a
493493 parseJSON _ = empty
494494 {-# INLINE parseJSON #-}
495495
@@ -514,10 +514,8 @@ instance (ToJSON v) => ToJSON (M.Map Text v) where
514514 {-# INLINE toJSON #-}
515515
516516instance (FromJSON v) => FromJSON (M.Map Text v) where
517− parseJSON (Object o) = M.fromAscList <$> go (M.toAscList o)
518− where
519− go ((k,v):kvs) = ((:) . (,) k) <$> parseJSON v <*> go kvs
520− go _ = pure []
517+ parseJSON (Object o) = M.fromAscList <$> mapM go (M.toAscList o)
518+ where go (k,v) = ((,) k) <$> parseJSON v
521519 parseJSON _ = empty
522520
523521instance (ToJSON v) => ToJSON (M.Map LT.Text v) where
@@ -532,15 +530,25 @@ instance (ToJSON v) => ToJSON (M.Map String v) where
532530instance (FromJSON v) => FromJSON (M.Map String v) where
533531 parseJSON = fmap (M.mapKeysMonotonic unpack) . parseJSON
534532
533+instance (ToJSON v) => ToJSON (M.Map B.ByteString v) where
534+ toJSON = Object . transformMap decode toJSON
535+
536+instance (FromJSON v) => FromJSON (M.Map B.ByteString v) where
537+ parseJSON = fmap (M.mapKeysMonotonic encodeUtf8) . parseJSON
538+
539+instance (ToJSON v) => ToJSON (M.Map LB.ByteString v) where
540+ toJSON = Object . transformMap strict toJSON
541+
542+instance (FromJSON v) => FromJSON (M.Map LB.ByteString v) where
543+ parseJSON = fmap (M.mapKeysMonotonic lazy) . parseJSON
544+
535545instance (ToJSON v) => ToJSON (H.HashMap Text v) where
536546 toJSON = Object . hashMap id toJSON
537547 {-# INLINE toJSON #-}
538548
539549instance (FromJSON v) => FromJSON (H.HashMap Text v) where
540− parseJSON (Object o) = H.fromList <$> go (M.toList o)
541− where
542− go ((k,v):kvs) = ((:) . (,) k) <$> parseJSON v <*> go kvs
543− go _ = pure []
550+ parseJSON (Object o) = H.fromList <$> mapM go (M.toList o)
551+ where go (k,v) = ((,) k) <$> parseJSON v
544552 parseJSON _ = empty
545553
546554instance (ToJSON v) => ToJSON (H.HashMap LT.Text v) where
@@ -555,6 +563,18 @@ instance (ToJSON v) => ToJSON (H.HashMap String v) where
555563instance (FromJSON v) => FromJSON (H.HashMap String v) where
556564 parseJSON = fmap (mapHash unpack) . parseJSON
557565
566+instance (ToJSON v) => ToJSON (H.HashMap B.ByteString v) where
567+ toJSON = Object . hashMap decode toJSON
568+
569+instance (FromJSON v) => FromJSON (H.HashMap B.ByteString v) where
570+ parseJSON = fmap (mapHash encodeUtf8) . parseJSON
571+
572+instance (ToJSON v) => ToJSON (H.HashMap LB.ByteString v) where
573+ toJSON = Object . hashMap strict toJSON
574+
575+instance (FromJSON v) => FromJSON (H.HashMap LB.ByteString v) where
576+ parseJSON = fmap (mapHash lazy) . parseJSON
577+
558578instance ToJSON Value where
559579 toJSON a = a
560580 {-# INLINE toJSON #-}
@@ -565,8 +585,9 @@ instance FromJSON Value where
565585
566586-- | A newtype wrapper for 'UTCTime' that uses the same non-standard
567587-- serialization format as Microsoft .NET.
568−newtype DotNetTime = DotNetTime UTCTime
569− deriving (Eq, Ord, Read, Show, Typeable, FormatTime)
588+newtype DotNetTime = DotNetTime {
589+ fromDotNetTime :: UTCTime
590+ } deriving (Eq, Ord, Read, Show, Typeable, FormatTime)
570591
571592instance ToJSON DotNetTime where
572593 toJSON (DotNetTime t) =
@@ -582,7 +603,8 @@ instance FromJSON DotNetTime where
582603 {-# INLINE parseJSON #-}
583604
584605instance ToJSON UTCTime where
585− toJSON t = String (pack (formatTime defaultTimeLocale "%FT%X%QZ" t))
606+ toJSON t = String (pack (take 23 str ++ "Z"))
607+ where str = formatTime defaultTimeLocale "%FT%T%Q" t
586608 {-# INLINE toJSON #-}
587609
588610instance FromJSON UTCTime where
@@ -627,9 +649,3 @@ instance ToJSON a => ToJSON (Last a) where
627649instance FromJSON a => FromJSON (Last a) where
628650 parseJSON = fmap Last . parseJSON
629651 {-# INLINE parseJSON #-}
630−
631−mapA :: (Alternative m) => (t -> m a) -> [t] -> m [a]
632−mapA f = go
633− where
634− go (a:as) = (:) <$> f a <*> go as
635− go _ = pure []