on master help sign in
Split the JSON class in two
commitc5c0e46e28d72b9b63b297a66beaa6ee478bdac5 authorBryan O'Sullivan <bos@mailrank.com> dateFri 21 Jan 2011, 15:11 (16 years ago) parent9783a48
3 files changed+36−20
Data/Aeson.hs+2−1 Data/Aeson/Encode.hs+5−4 Data/Aeson/Types.hs+29−15
Data/Aeson.hs+2−1
@@ -3,7 +3,8 @@ module Data.Aeson
33 Array
44 , Object
55 , Value(..)
6− , JSON(..)
6+ , FromJSON(..)
7+ , ToJSON(..)
78 , (.=)
89 , (.:)
910 , object
Data/Aeson/Encode.hs+5−4
@@ -8,7 +8,7 @@ module Data.Aeson.Encode
88
99import Blaze.ByteString.Builder
1010import Blaze.ByteString.Builder.Char.Utf8
11−import Data.Aeson.Types (JSON(..), Value(..))
11+import Data.Aeson.Types (ToJSON(..), Value(..))
1212import Data.Monoid (mappend, mconcat)
1313import qualified Data.ByteString.Char8 as B
1414import qualified Data.ByteString.Lazy.Char8 as L
@@ -39,17 +39,18 @@ build (Object m) =
3939string :: T.Text -> Builder
4040string s = fromChar '"' `mappend` quote s `mappend` fromChar '"'
4141 where
42− quote s = case T.uncons t of
42+ quote q = case T.uncons t of
4343 Just (c,t') -> mconcat [fromText h, fromText (escape c),
4444 quote t']
4545 Nothing -> fromText h
46− where (h,t) = T.break isEscape s
46+ where (h,t) = T.break isEscape q
4747 isEscape c = c == '\"' || c == '\n' || c == '\r' || c == '\t'
4848 escape '\"' = "\\\""
4949 escape '\n' = "\\n"
5050 escape '\r' = "\\r"
5151 escape '\t' = "\\t"
52+ escape _ = error "Data.Aeson.Encode.build: internal error"
5253
53−encode :: JSON a => a -> L.ByteString
54+encode :: ToJSON a => a -> L.ByteString
5455encode = toLazyByteString . build . toJSON
5556{-# INLINE encode #-}
Data/Aeson/Types.hs+29−15
@@ -6,7 +6,8 @@ module Data.Aeson.Types
66 , (.:)
77 , object
88 , Value(..)
9− , JSON(..)
9+ , FromJSON(..)
10+ , ToJSON(..)
1011 ) where
1112
1213import Control.Applicative
@@ -32,11 +33,11 @@ data Value = Object Object
3233 | Null
3334 deriving (Eq, Show)
3435
35−(.=) :: JSON a => Text -> a -> Object
36+(.=) :: ToJSON a => Text -> a -> Object
3637name .= value = M.singleton name (toJSON value)
3738{-# INLINE (.=) #-}
3839
39−(.:) :: (Alternative f, JSON a) => Object -> Text -> f a
40+(.:) :: (Alternative f, FromJSON a) => Object -> Text -> f a
4041obj .: key = case M.lookup key obj of
4142 Nothing -> empty
4243 Just v -> fromJSON v
@@ -46,54 +47,62 @@ object :: [Object] -> Value
4647object = Object . M.unions
4748{-# INLINE object #-}
4849
49−class JSON a where
50+class ToJSON a where
5051 toJSON :: a -> Value
52+
53+class FromJSON a where
5154 fromJSON :: Alternative f => Value -> f a
5255
53−instance (JSON a) => JSON (Maybe a) where
56+instance (ToJSON a) => ToJSON (Maybe a) where
5457 toJSON (Just a) = toJSON a
5558 toJSON Nothing = Null
5659 {-# INLINE toJSON #-}
5760
61+instance (FromJSON a) => FromJSON (Maybe a) where
5862 fromJSON Null = pure Nothing
5963 fromJSON a = Just <$> fromJSON a
6064 {-# INLINE fromJSON #-}
6165
62−instance JSON Bool where
66+instance ToJSON Bool where
6367 toJSON = Bool
6468 {-# INLINE toJSON #-}
6569
70+instance FromJSON Bool where
6671 fromJSON (Bool b) = pure b
6772 fromJSON _ = empty
6873 {-# INLINE fromJSON #-}
6974
70−instance JSON Double where
75+instance ToJSON Double where
7176 toJSON = Number
7277 {-# INLINE toJSON #-}
7378
79+instance FromJSON Double where
7480 fromJSON (Number n) = pure n
7581 fromJSON _ = empty
7682 {-# INLINE fromJSON #-}
7783
78−instance JSON Int where
84+instance ToJSON Int where
7985 toJSON = Number . fromIntegral
8086 {-# INLINE toJSON #-}
8187
88+instance FromJSON Int where
8289 fromJSON (Number n) = pure (floor n)
8390 fromJSON _ = empty
8491 {-# INLINE fromJSON #-}
8592
86−instance JSON Text where
93+instance ToJSON Text where
8794 toJSON = String
8895 {-# INLINE toJSON #-}
8996
97+instance FromJSON Text where
9098 fromJSON (String t) = pure t
9199 fromJSON _ = empty
92100 {-# INLINE fromJSON #-}
93101
94−instance JSON ByteString where
102+instance ToJSON ByteString where
95103 toJSON = String . decodeUtf8
96104
105+instance FromJSON ByteString where
97106 fromJSON (String t) = pure (encodeUtf8 t)
98107 fromJSON _ = empty
99108
@@ -103,35 +112,39 @@ mapA f = go
103112 go (a:as) = (:) <$> f a <*> go as
104113 go [] = pure []
105114
106−instance (JSON a) => JSON [a] where
115+instance (ToJSON a) => ToJSON [a] where
107116 toJSON = Array . V.fromList . map toJSON
108117 {-# INLINE toJSON #-}
109118
119+instance (FromJSON a) => FromJSON [a] where
110120 fromJSON (Array a) = mapA fromJSON (V.toList a)
111121 fromJSON _ = empty
112122 {-# INLINE fromJSON #-}
113123
114−instance (JSON a) => JSON (Vector a) where
124+instance (ToJSON a) => ToJSON (Vector a) where
115125 toJSON = Array . V.map toJSON
116126 {-# INLINE toJSON #-}
117127
128+instance (FromJSON a) => FromJSON (Vector a) where
118129 fromJSON (Array a) = V.fromList <$> mapA fromJSON (V.toList a)
119130 fromJSON _ = empty
120131 {-# INLINE fromJSON #-}
121132
122−instance JSON Value where
133+instance ToJSON Value where
123134 toJSON a = a
124135 {-# INLINE toJSON #-}
125136
137+instance FromJSON Value where
126138 fromJSON a = pure a
127139 {-# INLINE fromJSON #-}
128140
129141-- We happen to use the same JSON formatting for a UTCTime as .NET
130142-- does for a DateTime. How handy!
131−instance JSON UTCTime where
143+instance ToJSON UTCTime where
132144 toJSON t = String (pack (formatTime defaultTimeLocale "/Date(%s)/" t))
133145 {-# INLINE toJSON #-}
134146
147+instance FromJSON UTCTime where
135148 fromJSON (String t) =
136149 case parseTime defaultTimeLocale "/Date(%s)/" (unpack t) of
137150 Just d -> pure d
@@ -139,10 +152,11 @@ instance JSON UTCTime where
139152 fromJSON _ = empty
140153 {-# INLINE fromJSON #-}
141154
142−instance (JSON a, JSON b) => JSON (a,b) where
155+instance (ToJSON a, ToJSON b) => ToJSON (a,b) where
143156 toJSON (a,b) = toJSON [toJSON a, toJSON b]
144157 {-# INLINE toJSON #-}
145158
159+instance (FromJSON a, FromJSON b) => FromJSON (a,b) where
146160 fromJSON (Array ab) = case V.toList ab of
147161 [a,b] -> (,) <$> fromJSON a <*> fromJSON b
148162 _ -> empty