on master help sign in
Simplify and extend map support.
76bab1cBryan O'Sullivan
Data/Aeson/Functions.hs+20
@@ -3,10 +3,18 @@ module Data.Aeson.Functions
3 hashMap
3 hashMap
4 , mapHash
4 , mapHash
5 , transformMap
5 , transformMap
6+ -- * String conversions
7+ , decode
8+ , strict
9+ , lazy
6 ) where
10 ) where
7
11
8import Control.Arrow ((***), first)
12import Control.Arrow ((***), first)
9import Data.Hashable (Hashable)
13import Data.Hashable (Hashable)
14+import Data.Text (Text)
15+import Data.Text.Encoding (decodeUtf8, encodeUtf8)
16+import qualified Data.ByteString as B
17+import qualified Data.ByteString.Lazy as L
10import qualified Data.HashMap.Strict as H
18import qualified Data.HashMap.Strict as H
11import qualified Data.Map as M
19import qualified Data.Map as M
12
20
@@ -27,3 +35,15 @@ hashMap fk kv = M.fromList . map (fk *** kv) . H.toList
27mapHash :: (Eq k2, Hashable k2) => (k1 -> k2) -> M.Map k1 v -> H.HashMap k2 v
35mapHash :: (Eq k2, Hashable k2) => (k1 -> k2) -> M.Map k1 v -> H.HashMap k2 v
28mapHash fk = H.fromList . map (first fk) . M.toList
36mapHash fk = H.fromList . map (first fk) . M.toList
29{-# INLINE mapHash #-}
37{-# INLINE mapHash #-}
38+
39+strict :: L.ByteString -> Text
40+strict = decode . B.concat . L.toChunks
41+{-# INLINE strict #-}
42+
43+lazy :: Text -> L.ByteString
44+lazy = L.fromChunks . (:[]) . encodeUtf8
45+{-# INLINE lazy #-}
46+
47+decode :: B.ByteString -> Text
48+decode = decodeUtf8
49+{-# INLINE decode #-}
Data/Aeson/Types.hs+28−36
@@ -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)
@@ -480,7 +480,7 @@ instance (ToJSON a) => ToJSON [a] where
480 {-# INLINE toJSON #-}
480 {-# INLINE toJSON #-}
481
481
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 #-}
486
486
@@ -489,7 +489,7 @@ instance (ToJSON a) => ToJSON (Vector a) where
489 {-# INLINE toJSON #-}
489 {-# INLINE toJSON #-}
490
490
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 #-}
495
495
@@ -514,10 +514,8 @@ instance (ToJSON v) => ToJSON (M.Map Text v) where
514 {-# INLINE toJSON #-}
514 {-# INLINE toJSON #-}
515
515
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)
518− where
519− go ((k,v):kvs) = ((:) . (,) k) <$> parseJSON v <*> go kvs
518+ where go (k,v) = ((,) k) <$> parseJSON v
520− go _ = pure []
521 parseJSON _ = empty
519 parseJSON _ = empty
522
520
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
534
532
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+
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 #-}
538
548
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)
541− where
542− go ((k,v):kvs) = ((:) . (,) k) <$> parseJSON v <*> go kvs
551+ where go (k,v) = ((,) k) <$> parseJSON v
543− go _ = pure []
544 parseJSON _ = empty
552 parseJSON _ = empty
545
553
546instance (ToJSON v) => ToJSON (H.HashMap LT.Text v) where
554instance (ToJSON v) => ToJSON (H.HashMap LT.Text v) where
@@ -555,17 +563,17 @@ 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
557
565
558−instance (ToJSON v) => ToJSON (M.Map B.ByteString v) where
566+instance (ToJSON v) => ToJSON (H.HashMap B.ByteString v) where
559− toJSON = Object . transformMap decode toJSON
567+ toJSON = Object . hashMap decode toJSON
560
568
561−instance (FromJSON v) => FromJSON (M.Map B.ByteString v) where
569+instance (FromJSON v) => FromJSON (H.HashMap B.ByteString v) where
562− parseJSON = fmap (M.mapKeysMonotonic encodeUtf8) . parseJSON
570+ parseJSON = fmap (mapHash encodeUtf8) . parseJSON
563
571
564−instance (ToJSON v) => ToJSON (M.Map LB.ByteString v) where
572+instance (ToJSON v) => ToJSON (H.HashMap LB.ByteString v) where
565− toJSON = Object . transformMap strict toJSON
573+ toJSON = Object . hashMap strict toJSON
566
574
567−instance (FromJSON v) => FromJSON (M.Map LB.ByteString v) where
575+instance (FromJSON v) => FromJSON (H.HashMap LB.ByteString v) where
568− parseJSON = fmap (M.mapKeysMonotonic lazy) . parseJSON
576+ parseJSON = fmap (mapHash lazy) . parseJSON
569
577
570instance ToJSON Value where
578instance ToJSON Value where
571 toJSON a = a
579 toJSON a = a
@@ -639,19 +647,3 @@ instance ToJSON a => ToJSON (Last a) where
639instance FromJSON a => FromJSON (Last a) where
647instance FromJSON a => FromJSON (Last a) where
640 parseJSON = fmap Last . parseJSON
648 parseJSON = fmap Last . parseJSON
641 {-# INLINE parseJSON #-}
649 {-# INLINE parseJSON #-}
642−
643−mapA :: (Alternative m) => (t -> m a) -> [t] -> m [a]
644−mapA f = go
645− where
646− go (a:as) = (:) <$> f a <*> go as
647− go _ = pure []
648−
649−strict :: LB.ByteString -> Text
650−strict = decode . B.concat . LB.toChunks
651−
652−lazy :: Text -> LB.ByteString
653−lazy = LB.fromChunks . (:[]) . encodeUtf8
654−
655−decode :: B.ByteString -> Text
656−decode = decodeUtf8
657−{-# INLINE decode #-}