@@ -38,7 +38,7 @@ module Data.Aeson.Types
38import Control.Applicative
38import Control.Applicative
39import Control.DeepSeq (NFData(..))
39import Control.DeepSeq (NFData(..))
40import Control.Monad (MonadPlus(..))
40import Control.Monad (MonadPlus(..))
41−import Data.Aeson.Functions (hashMap, mapHash, transformMap)
41+import Data.Aeson.Functions
42import Data.Attoparsec.Char8 (Number(..))
42import Data.Attoparsec.Char8 (Number(..))
43import Data.Data (Data)
43import Data.Data (Data)
44import Data.Int (Int8, Int16, Int32, Int64)
44import Data.Int (Int8, Int16, Int32, Int64)
@@ -48,7 +48,7 @@ import Data.Monoid (Monoid(..))
48import Data.Ratio (Ratio)
48import Data.Ratio (Ratio)
49import Data.String (IsString(..))
49import Data.String (IsString(..))
50import Data.Text (Text, pack, unpack)
50import Data.Text (Text, pack, unpack)
51−import Data.Text.Encoding (decodeUtf8, encodeUtf8)
51+import Data.Text.Encoding (encodeUtf8)
52import Data.Time.Clock (UTCTime)
52import Data.Time.Clock (UTCTime)
53import Data.Time.Format (FormatTime, formatTime, parseTime)
53import Data.Time.Format (FormatTime, formatTime, parseTime)
54import Data.Typeable (Typeable)
54import Data.Typeable (Typeable)
@@ -458,7 +458,7 @@ instance FromJSON LT.Text where
458 {-# INLINE parseJSON #-}
458 {-# INLINE parseJSON #-}
460instance ToJSON B.ByteString where
460instance ToJSON B.ByteString where
461− toJSON = String . decodeUtf8
461+ toJSON = String . decode
462 {-# INLINE toJSON #-}
462 {-# INLINE toJSON #-}
464instance FromJSON B.ByteString where
464instance FromJSON B.ByteString where
@@ -467,11 +467,11 @@ instance FromJSON B.ByteString where
467 {-# INLINE parseJSON #-}
467 {-# INLINE parseJSON #-}
469instance ToJSON LB.ByteString where
469instance ToJSON LB.ByteString where
470− toJSON = toJSON . B.concat . LB.toChunks
470+ toJSON = toJSON . strict
471 {-# INLINE toJSON #-}
471 {-# INLINE toJSON #-}
473instance FromJSON LB.ByteString where
473instance FromJSON LB.ByteString where
474− parseJSON (String t) = pure . LB.fromChunks . (:[]) . encodeUtf8 $ t
474+ parseJSON (String t) = pure . lazy $ t
475 parseJSON _ = empty
475 parseJSON _ = empty
476 {-# INLINE parseJSON #-}
476 {-# INLINE parseJSON #-}
@@ -480,7 +480,7 @@ instance (ToJSON a) => ToJSON [a] where
480 {-# INLINE toJSON #-}
480 {-# INLINE toJSON #-}
482instance (FromJSON a) => FromJSON [a] where
482instance (FromJSON a) => FromJSON [a] where
483− parseJSON (Array a) = mapA parseJSON (V.toList a)
483+ parseJSON (Array a) = mapM parseJSON (V.toList a)
484 parseJSON _ = empty
484 parseJSON _ = empty
485 {-# INLINE parseJSON #-}
485 {-# INLINE parseJSON #-}
@@ -489,7 +489,7 @@ instance (ToJSON a) => ToJSON (Vector a) where
489 {-# INLINE toJSON #-}
489 {-# INLINE toJSON #-}
491instance (FromJSON a) => FromJSON (Vector a) where
491instance (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
493 parseJSON _ = empty
493 parseJSON _ = empty
494 {-# INLINE parseJSON #-}
494 {-# INLINE parseJSON #-}
@@ -514,10 +514,8 @@ instance (ToJSON v) => ToJSON (M.Map Text v) where
514 {-# INLINE toJSON #-}
514 {-# INLINE toJSON #-}
516instance (FromJSON v) => FromJSON (M.Map Text v) where
516instance (FromJSON v) => FromJSON (M.Map Text v) where
517− parseJSON (Object o) = M.fromAscList <$> go (M.toAscList o)
517+ parseJSON (Object o) = M.fromAscList <$> mapM go (M.toAscList o)
519− go ((k,v):kvs) = ((:) . (,) k) <$> parseJSON v <*> go kvs
518+ where go (k,v) = ((,) k) <$> parseJSON v
521 parseJSON _ = empty
519 parseJSON _ = empty
523instance (ToJSON v) => ToJSON (M.Map LT.Text v) where
521instance (ToJSON v) => ToJSON (M.Map LT.Text v) where
@@ -532,15 +530,25 @@ instance (ToJSON v) => ToJSON (M.Map String v) where
532instance (FromJSON v) => FromJSON (M.Map String v) where
530instance (FromJSON v) => FromJSON (M.Map String v) where
533 parseJSON = fmap (M.mapKeysMonotonic unpack) . parseJSON
531 parseJSON = fmap (M.mapKeysMonotonic unpack) . parseJSON
533+instance (ToJSON v) => ToJSON (M.Map B.ByteString v) where
534+ toJSON = Object . transformMap decode toJSON
536+instance (FromJSON v) => FromJSON (M.Map B.ByteString v) where
537+ parseJSON = fmap (M.mapKeysMonotonic encodeUtf8) . parseJSON
539+instance (ToJSON v) => ToJSON (M.Map LB.ByteString v) where
540+ toJSON = Object . transformMap strict toJSON
542+instance (FromJSON v) => FromJSON (M.Map LB.ByteString v) where
543+ parseJSON = fmap (M.mapKeysMonotonic lazy) . parseJSON
535instance (ToJSON v) => ToJSON (H.HashMap Text v) where
545instance (ToJSON v) => ToJSON (H.HashMap Text v) where
536 toJSON = Object . hashMap id toJSON
546 toJSON = Object . hashMap id toJSON
537 {-# INLINE toJSON #-}
547 {-# INLINE toJSON #-}
539instance (FromJSON v) => FromJSON (H.HashMap Text v) where
549instance (FromJSON v) => FromJSON (H.HashMap Text v) where
540− parseJSON (Object o) = H.fromList <$> go (M.toList o)
550+ parseJSON (Object o) = H.fromList <$> mapM go (M.toList o)
542− go ((k,v):kvs) = ((:) . (,) k) <$> parseJSON v <*> go kvs
551+ where go (k,v) = ((,) k) <$> parseJSON v
544 parseJSON _ = empty
552 parseJSON _ = empty
546instance (ToJSON v) => ToJSON (H.HashMap LT.Text v) where
554instance (ToJSON v) => ToJSON (H.HashMap LT.Text v) where
@@ -555,6 +563,18 @@ instance (ToJSON v) => ToJSON (H.HashMap String v) where
555instance (FromJSON v) => FromJSON (H.HashMap String v) where
563instance (FromJSON v) => FromJSON (H.HashMap String v) where
556 parseJSON = fmap (mapHash unpack) . parseJSON
564 parseJSON = fmap (mapHash unpack) . parseJSON
566+instance (ToJSON v) => ToJSON (H.HashMap B.ByteString v) where
567+ toJSON = Object . hashMap decode toJSON
569+instance (FromJSON v) => FromJSON (H.HashMap B.ByteString v) where
570+ parseJSON = fmap (mapHash encodeUtf8) . parseJSON
572+instance (ToJSON v) => ToJSON (H.HashMap LB.ByteString v) where
573+ toJSON = Object . hashMap strict toJSON
575+instance (FromJSON v) => FromJSON (H.HashMap LB.ByteString v) where
576+ parseJSON = fmap (mapHash lazy) . parseJSON
558instance ToJSON Value where
578instance ToJSON Value where
559 toJSON a = a
579 toJSON a = a
560 {-# INLINE toJSON #-}
580 {-# INLINE toJSON #-}
@@ -565,8 +585,9 @@ instance FromJSON Value where
566-- | A newtype wrapper for 'UTCTime' that uses the same non-standard
586-- | A newtype wrapper for 'UTCTime' that uses the same non-standard
567-- serialization format as Microsoft .NET.
587-- serialization format as Microsoft .NET.
568−newtype DotNetTime = DotNetTime UTCTime
588+newtype DotNetTime = DotNetTime {
589+ fromDotNetTime :: UTCTime
569− deriving (Eq, Ord, Read, Show, Typeable, FormatTime)
590+ } deriving (Eq, Ord, Read, Show, Typeable, FormatTime)
571instance ToJSON DotNetTime where
592instance ToJSON DotNetTime where
572 toJSON (DotNetTime t) =
593 toJSON (DotNetTime t) =
@@ -582,7 +603,8 @@ instance FromJSON DotNetTime where
582 {-# INLINE parseJSON #-}
603 {-# INLINE parseJSON #-}
584instance ToJSON UTCTime where
605instance ToJSON UTCTime where
606+ toJSON t = String (pack (take 23 str ++ "Z"))
585− toJSON t = String (pack (formatTime defaultTimeLocale "%FT%X%QZ" t))
607+ where str = formatTime defaultTimeLocale "%FT%T%Q" t
586 {-# INLINE toJSON #-}
608 {-# INLINE toJSON #-}
588instance FromJSON UTCTime where
610instance FromJSON UTCTime where
@@ -627,9 +649,3 @@ instance ToJSON a => ToJSON (Last a) where
627instance FromJSON a => FromJSON (Last a) where
649instance FromJSON a => FromJSON (Last a) where
628 parseJSON = fmap Last . parseJSON
650 parseJSON = fmap Last . parseJSON
629 {-# INLINE parseJSON #-}
651 {-# INLINE parseJSON #-}
631−mapA :: (Alternative m) => (t -> m a) -> [t] -> m [a]
634− go (a:as) = (:) <$> f a <*> go as