on master help sign in
Conversion to/from generic types via SYB, and new Parser/Result types
cf2365cBryan O'Sullivan
Data/Aeson.hs+2
@@ -17,6 +17,8 @@ module Data.Aeson
17 , Object
17 , Object
18 -- * Type conversion
18 -- * Type conversion
19 , FromJSON(..)
19 , FromJSON(..)
20+ , Result(..)
21+ , fromJSON
20 , ToJSON(..)
22 , ToJSON(..)
21 -- * Constructors and accessors
23 -- * Constructors and accessors
22 , (.=)
24 , (.=)
Data/Aeson/Generic.hs+144−8
@@ -1,22 +1,40 @@
1+{-# LANGUAGE PatternGuards #-}
2+
3+-- Module: Data.Aeson.Generic
4+-- Copyright: (c) 2011 MailRank, Inc.
5+-- (c) 2008, 2009 Lennart Augustsson
6+-- License: BSD3
7+-- Maintainer: Bryan O'Sullivan <bos@mailrank.com>
8+-- Stability: experimental
9+-- Portability: portable
10+--
11+-- JSON handling using 'Data.Generics'.
12+--
13+-- This is based on the 'Text.JSON.Generic' package originally written
14+-- by Lennart Augustsson.
15+
1module Data.Aeson.Generic
16module Data.Aeson.Generic
2 (
17 (
3 fromJSON
18 fromJSON
4 , toJSON
19 , toJSON
5 ) where
20 ) where
6
21
7−import Control.Applicative (Alternative)
22+import Control.Applicative ((<$>))
23+import Control.Arrow (first)
24+import Control.Monad.State.Strict
8−import Data.Aeson.Functions
25+import Data.Aeson.Functions (transformMap)
9−import Data.Aeson.Types hiding (FromJSON(..), ToJSON(..))
26+import Data.Aeson.Types hiding (FromJSON(..), ToJSON(..), fromJSON)
10import Data.Generics
27import Data.Generics
11−import Data.Int
28+import Data.Int (Int8, Int16, Int32, Int64)
12import Data.IntSet (IntSet)
29import Data.IntSet (IntSet)
13−import Data.Text (Text, pack)
30+import Data.Text (Text, pack, unpack)
14import Data.Time.Clock (UTCTime)
31import Data.Time.Clock (UTCTime)
15−import Data.Word
32+import Data.Word (Word, Word8, Word16, Word32, Word64)
16import qualified Data.Aeson.Types as T
33import qualified Data.Aeson.Types as T
17import qualified Data.ByteString as B
34import qualified Data.ByteString as B
18import qualified Data.ByteString.Lazy as L
35import qualified Data.ByteString.Lazy as L
19import qualified Data.Map as Map
36import qualified Data.Map as Map
37+import qualified Data.Traversable as T
20import qualified Data.Set as Set
38import qualified Data.Set as Set
21import qualified Data.Text.Lazy as L
39import qualified Data.Text.Lazy as L
22import qualified Data.Vector as V
40import qualified Data.Vector as V
@@ -105,5 +123,123 @@ toJSON_generic = generic
105 mungeField ('_':cs) = pack cs
123 mungeField ('_':cs) = pack cs
106 mungeField cs = pack cs
124 mungeField cs = pack cs
107
125
108−fromJSON :: (Alternative f, Data a) => Value -> f a
126+fromJSON :: (Data a) => Value -> Result a
109−fromJSON = undefined
127+fromJSON = parse parseJSON
128+
129+type F a = Parser a
130+
131+parseJSON :: (Data a) => Value -> Parser a
132+parseJSON j = parseJSON_generic j
133+ `ext1R` list
134+ `ext1R` vector
135+ `ext1R` mapText
136+ `ext1R` mapLazyText
137+ `ext1R` mapString
138+ -- Use the standard encoding for all base types.
139+ `extR` (value :: F Integer)
140+ `extR` (value :: F Int)
141+ `extR` (value :: F Int8)
142+ `extR` (value :: F Int16)
143+ `extR` (value :: F Int32)
144+ `extR` (value :: F Int64)
145+ `extR` (value :: F Word)
146+ `extR` (value :: F Word8)
147+ `extR` (value :: F Word16)
148+ `extR` (value :: F Word32)
149+ `extR` (value :: F Word64)
150+ `extR` (value :: F Double)
151+ `extR` (value :: F Float)
152+ `extR` (value :: F Rational)
153+ `extR` (value :: F Char)
154+ `extR` (value :: F Text)
155+ `extR` (value :: F L.Text)
156+ `extR` (value :: F String)
157+ `extR` (value :: F B.ByteString)
158+ `extR` (value :: F L.ByteString)
159+ `extR` (value :: F T.Value)
160+ `extR` (value :: F UTCTime)
161+ `extR` (value :: F IntSet)
162+ `extR` (value :: F Bool)
163+ `extR` (value :: F ())
164+ where
165+ value :: (T.FromJSON a) => Parser a
166+ value = T.parseJSON j
167+ list :: (Data a) => Parser [a]
168+ list = V.toList <$> parseJSON j
169+ vector :: (Data a) => Parser (V.Vector a)
170+ vector = case j of
171+ Array js -> V.mapM parseJSON js
172+ _ -> modFail "parseJSON" $ "bad data: " ++ show j
173+ mapText :: (Data a) => Parser (Map.Map Text a)
174+ mapText = case j of
175+ Object js -> T.mapM parseJSON js
176+ _ -> modFail "parseJSON" $ "bad data: " ++ show j
177+ mapLazyText :: (Data a) => Parser (Map.Map L.Text a)
178+ mapLazyText = Map.mapKeysMonotonic L.fromStrict <$> parseJSON j
179+ mapString :: (Data a) => Parser (Map.Map String a)
180+ mapString = Map.mapKeysMonotonic unpack <$> parseJSON j
181+
182+parseJSON_generic :: (Data a) => Value -> Parser a
183+parseJSON_generic j = generic
184+ where
185+ typ = dataTypeOf $ resType generic
186+ generic = case dataTypeRep typ of
187+ AlgRep [] -> case j of
188+ Null -> return (error "Empty type")
189+ _ -> modFail "parseJSON" "no-constr bad data"
190+ AlgRep [_] -> decodeArgs (indexConstr typ 1) j
191+ AlgRep _ -> do (c, j') <- getConstr typ j; decodeArgs c j'
192+ rep -> modFail "parseJSON" $
193+ show rep ++ "(" ++ show typ ++ ")"
194+ getConstr t (Object o) | [(s, j')] <- fromJSObject o = do
195+ c <- readConstr' t s
196+ return (c, j')
197+ getConstr t (String js) = do c <- readConstr' t (unpack js)
198+ return (c, Null) -- handle nullary ctor
199+ getConstr _ _ = modFail "parseJSON" "bad constructor encoding"
200+ readConstr' t s =
201+ maybe (modFail "parseJSON" $ "unknown constructor: " ++ s ++ " " ++
202+ show t)
203+ return $ readConstr t s
204+
205+ decodeArgs c0 = go (numConstrArgs (resType generic) c0) c0
206+ (constrFields c0)
207+ where
208+ go 0 c _ Null = construct c [] -- nullary constructor
209+ go 1 c [] jd = construct c [jd] -- unary constructor
210+ go n c [] (Array js)
211+ | n > 1 = construct c (V.toList js) -- no field names
212+ -- FIXME? We could allow reading an array into a constructor
213+ -- with field names.
214+ go _ c fs@(_:_) (Object o) = selectFields (fromJSObject o) fs >>=
215+ construct c -- field names
216+ go _ c _ jd = modFail "parseJSON" $
217+ "bad decodeArgs data " ++ show (c, jd)
218+
219+ fromJSObject = map (first unpack) . Map.toList
220+
221+ -- Build the value by stepping through the list of subparts.
222+ construct c = evalStateT $ fromConstrM f c
223+ where f :: (Data a) => StateT [Value] Parser a
224+ f = do js <- get
225+ case js of
226+ [] -> lift $ modFail "construct" "empty list"
227+ (j':js') -> do put js'; lift $ parseJSON j'
228+
229+ -- Select the named fields from a JSON object. FIXME? Should
230+ -- this use a map?
231+ selectFields fjs = mapM sel
232+ where sel f = maybe (modFail "parseJSON" $ "field does not exist " ++
233+ f) return $ lookup f fjs
234+
235+ -- Count how many arguments a constructor has. The value x is
236+ -- used to determine what type the constructor returns.
237+ numConstrArgs :: (Data a) => a -> Constr -> Int
238+ numConstrArgs x c = execState (fromConstrM f c `asTypeOf` return x) 0
239+ where f = do modify (+1); return undefined
240+
241+ resType :: MonadPlus m => m a -> a
242+ resType _ = error "resType"
243+
244+modFail :: (Monad m) => String -> String -> m a
245+modFail func err = fail $ "Data.Aeson.Generic." ++ func ++ ": " ++ err
Data/Aeson/Types.hs+192−112
@@ -1,5 +1,5 @@
1{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, IncoherentInstances,
1{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, IncoherentInstances,
2− OverlappingInstances #-}
2+ OverlappingInstances, Rank2Types #-}
3
3
4-- Module: Data.Aeson.Types
4-- Module: Data.Aeson.Types
5-- Copyright: (c) 2011 MailRank, Inc.
5-- Copyright: (c) 2011 MailRank, Inc.
@@ -20,7 +20,11 @@ module Data.Aeson.Types
20 , Object
20 , Object
21 , emptyObject
21 , emptyObject
22 -- * Type conversion
22 -- * Type conversion
23+ , Parser
24+ , Result(..)
23 , FromJSON(..)
25 , FromJSON(..)
26+ , fromJSON
27+ , parse
24 , ToJSON(..)
28 , ToJSON(..)
25 -- * Constructors and accessors
29 -- * Constructors and accessors
26 , (.=)
30 , (.=)
@@ -30,6 +34,8 @@ module Data.Aeson.Types
30 ) where
34 ) where
31
35
32import Control.Applicative
36import Control.Applicative
37+import Control.Monad (MonadPlus(..))
38+import Data.Monoid (Monoid(..))
33import Control.DeepSeq (NFData(..))
39import Control.DeepSeq (NFData(..))
34import Data.Data (Data)
40import Data.Data (Data)
35import Data.Int (Int8, Int16, Int32, Int64)
41import Data.Int (Int8, Int16, Int32, Int64)
@@ -54,6 +60,70 @@ import qualified Data.Text.Lazy as LT
54import qualified Data.Vector as V
60import qualified Data.Vector as V
55import Data.Aeson.Functions
61import Data.Aeson.Functions
56
62
63+-- | The result of running a 'Parser'.
64+data Result a = Error String
65+ | Success a
66+ deriving (Eq, Show, Typeable)
67+
68+-- | Failure continuation. Constructs an 'Error'.
69+type Failure r = String -> Result r
70+-- | Success continuation. Constructs a 'Success'.
71+type Success a r = a -> Result r
72+
73+-- | A continuation-based parser type.
74+newtype Parser a = Parser {
75+ runParser :: forall r.
76+ Failure r
77+ -> Success a r
78+ -> Result r
79+ }
80+
81+instance Monad Parser where
82+ m >>= g = Parser $ \kf ks -> let ks' a = runParser (g a) kf ks
83+ in runParser m kf ks'
84+ {-# INLINE (>>=) #-}
85+ return a = Parser $ \_kf ks -> ks a
86+ {-# INLINE return #-}
87+ fail msg = Parser $ \kf _ks -> kf msg
88+ {-# INLINE fail #-}
89+
90+instance Functor Parser where
91+ fmap f m = Parser $ \kf ks -> let ks' a = ks (f a)
92+ in runParser m kf ks'
93+ {-# INLINE fmap #-}
94+
95+instance Applicative Parser where
96+ pure = return
97+ {-# INLINE pure #-}
98+ (<*>) = apP
99+ {-# INLINE (<*>) #-}
100+
101+instance Alternative Parser where
102+ empty = fail "empty"
103+ {-# INLINE empty #-}
104+ (<|>) = mplus
105+ {-# INLINE (<|>) #-}
106+
107+instance MonadPlus Parser where
108+ mzero = fail "mzero"
109+ {-# INLINE mzero #-}
110+ mplus a b = Parser $ \kf ks -> let kf' _ = runParser b kf ks
111+ in runParser a kf' ks
112+ {-# INLINE mplus #-}
113+
114+instance Monoid (Parser a) where
115+ mempty = fail "mempty"
116+ {-# INLINE mempty #-}
117+ mappend = mplus
118+ {-# INLINE mappend #-}
119+
120+apP :: Parser (a -> b) -> Parser a -> Parser b
121+apP d e = do
122+ b <- d
123+ a <- e
124+ return (b a)
125+{-# INLINE apP #-}
126+
57-- | A JSON \"object\" (key\/value map).
127-- | A JSON \"object\" (key\/value map).
58type Object = Map Text Value
128type Object = Map Text Value
59
129
@@ -93,6 +163,16 @@ type Pair = (Text, Value)
93name .= value = (name, toJSON value)
163name .= value = (name, toJSON value)
94{-# INLINE (.=) #-}
164{-# INLINE (.=) #-}
95
165
166+-- | Convert a value from JSON, failing if the types do not match.
167+fromJSON :: (FromJSON a) => Value -> Result a
168+fromJSON = parse parseJSON
169+{-# INLINE fromJSON #-}
170+
171+-- | Run a 'Parser'.
172+parse :: (a -> Parser b) -> a -> Result b
173+parse m v = runParser (m v) Error Success
174+{-# INLINE parse #-}
175+
96-- | Retrieve the value associated with the given key of an 'Object'.
176-- | Retrieve the value associated with the given key of an 'Object'.
97-- The result is 'empty' if the key is not present or the value cannot
177-- The result is 'empty' if the key is not present or the value cannot
98-- be converted to the desired type.
178-- be converted to the desired type.
@@ -100,10 +180,10 @@ name .= value = (name, toJSON value)
100-- This accessor is appropriate if the key and value /must/ be present
180-- This accessor is appropriate if the key and value /must/ be present
101-- in an object for it to be valid. If the key and value are
181-- in an object for it to be valid. If the key and value are
102-- optional, use '(.:?)' instead.
182-- optional, use '(.:?)' instead.
103−(.:) :: (Alternative m, FromJSON a) => Object -> Text -> m a
183+(.:) :: (FromJSON a) => Object -> Text -> Parser a
104obj .: key = case M.lookup key obj of
184obj .: key = case M.lookup key obj of
105 Nothing -> empty
185 Nothing -> empty
106− Just v -> fromJSON v
186+ Just v -> parseJSON v
107{-# INLINE (.:) #-}
187{-# INLINE (.:) #-}
108
188
109-- | Retrieve the value associated with the given key of an 'Object'.
189-- | Retrieve the value associated with the given key of an 'Object'.
@@ -113,10 +193,10 @@ obj .: key = case M.lookup key obj of
113-- This accessor is most useful if the key and value can be absent
193-- This accessor is most useful if the key and value can be absent
114-- from an object without affecting its validity. If the key and
194-- from an object without affecting its validity. If the key and
115-- value are mandatory, use '(.:?)' instead.
195-- value are mandatory, use '(.:?)' instead.
116−(.:?) :: (Alternative m, FromJSON a) => Object -> Text -> m (Maybe a)
196+(.:?) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
117obj .:? key = case M.lookup key obj of
197obj .:? key = case M.lookup key obj of
118 Nothing -> pure Nothing
198 Nothing -> pure Nothing
119− Just v -> fromJSON v
199+ Just v -> parseJSON v
120{-# INLINE (.:?) #-}
200{-# INLINE (.:?) #-}
121
201
122-- | Create a 'Value' from a list of name\/value 'Pair's. If duplicate
202-- | Create a 'Value' from a list of name\/value 'Pair's. If duplicate
@@ -140,24 +220,24 @@ class ToJSON a where
140-- | A type that can be converted from JSON, with the possibility of
220-- | A type that can be converted from JSON, with the possibility of
141-- failure.
221-- failure.
142--
222--
143−-- When writing an instance, use 'mzero' to make a conversion fail,
223+-- When writing an instance, use 'mzero' or 'fail' to make a
144−-- e.g. if an 'Object' is missing a required key, or the value is of
224+-- conversion fail, e.g. if an 'Object' is missing a required key, or
145−-- the wrong type.
225+-- the value is of the wrong type.
146--
226--
147-- An example type and instance:
227-- An example type and instance:
148--
228--
149-- @data Coord { x :: Double, y :: Double }
229-- @data Coord { x :: Double, y :: Double }
150--
230--
151-- instance FromJSON Coord where
231-- instance FromJSON Coord where
152−-- fromJSON ('Object' v) = Coord '<$>'
232+-- parseJSON ('Object' v) = Coord '<$>'
153-- v '.:' \"x\" '<*>'
233-- v '.:' \"x\" '<*>'
154-- v '.:' \"y\"
234-- v '.:' \"y\"
155--
235--
156-- \-- A non-'Object' value is of the wrong type, so use 'mzero' to fail.
236-- \-- A non-'Object' value is of the wrong type, so use 'mzero' to fail.
157−-- fromJSON _ = 'mzero'
237+-- parseJSON _ = 'mzero'
158-- @
238-- @
159class FromJSON a where
239class FromJSON a where
160− fromJSON :: Alternative m => Value -> m a
240+ parseJSON :: Value -> Parser a
161
241
162instance (ToJSON a) => ToJSON (Maybe a) where
242instance (ToJSON a) => ToJSON (Maybe a) where
163 toJSON (Just a) = toJSON a
243 toJSON (Just a) = toJSON a
@@ -165,9 +245,9 @@ instance (ToJSON a) => ToJSON (Maybe a) where
165 {-# INLINE toJSON #-}
245 {-# INLINE toJSON #-}
166
246
167instance (FromJSON a) => FromJSON (Maybe a) where
247instance (FromJSON a) => FromJSON (Maybe a) where
168− fromJSON Null = pure Nothing
248+ parseJSON Null = pure Nothing
169− fromJSON a = Just <$> fromJSON a
249+ parseJSON a = Just <$> parseJSON a
170− {-# INLINE fromJSON #-}
250+ {-# INLINE parseJSON #-}
171
251
172instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
252instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
173 toJSON (Left a) = toJSON a
253 toJSON (Left a) = toJSON a
@@ -175,272 +255,272 @@ instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
175 {-# INLINE toJSON #-}
255 {-# INLINE toJSON #-}
176
256
177instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
257instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
178− fromJSON a = Left <$> fromJSON a <|> Right <$> fromJSON a
258+ parseJSON a = Left <$> parseJSON a <|> Right <$> parseJSON a
179− {-# INLINE fromJSON #-}
259+ {-# INLINE parseJSON #-}
180
260
181instance ToJSON Bool where
261instance ToJSON Bool where
182 toJSON = Bool
262 toJSON = Bool
183 {-# INLINE toJSON #-}
263 {-# INLINE toJSON #-}
184
264
185instance FromJSON Bool where
265instance FromJSON Bool where
186− fromJSON (Bool b) = pure b
266+ parseJSON (Bool b) = pure b
187− fromJSON _ = empty
267+ parseJSON _ = empty
188− {-# INLINE fromJSON #-}
268+ {-# INLINE parseJSON #-}
189
269
190instance ToJSON () where
270instance ToJSON () where
191 toJSON _ = emptyArray
271 toJSON _ = emptyArray
192 {-# INLINE toJSON #-}
272 {-# INLINE toJSON #-}
193
273
194instance FromJSON () where
274instance FromJSON () where
195− fromJSON (Array v) | V.null v = pure ()
275+ parseJSON (Array v) | V.null v = pure ()
196− fromJSON _ = empty
276+ parseJSON _ = empty
197− {-# INLINE fromJSON #-}
277+ {-# INLINE parseJSON #-}
198
278
199instance ToJSON [Char] where
279instance ToJSON [Char] where
200 toJSON = String . T.pack
280 toJSON = String . T.pack
201 {-# INLINE toJSON #-}
281 {-# INLINE toJSON #-}
202
282
203instance FromJSON [Char] where
283instance FromJSON [Char] where
204− fromJSON (String t) = pure (T.unpack t)
284+ parseJSON (String t) = pure (T.unpack t)
205− fromJSON _ = empty
285+ parseJSON _ = empty
206− {-# INLINE fromJSON #-}
286+ {-# INLINE parseJSON #-}
207
287
208instance ToJSON Char where
288instance ToJSON Char where
209 toJSON = String . T.singleton
289 toJSON = String . T.singleton
210 {-# INLINE toJSON #-}
290 {-# INLINE toJSON #-}
211
291
212instance FromJSON Char where
292instance FromJSON Char where
213− fromJSON (String t)
293+ parseJSON (String t)
214 | T.compareLength t 1 == EQ = pure (T.head t)
294 | T.compareLength t 1 == EQ = pure (T.head t)
215− fromJSON _ = empty
295+ parseJSON _ = empty
216− {-# INLINE fromJSON #-}
296+ {-# INLINE parseJSON #-}
217
297
218instance ToJSON Double where
298instance ToJSON Double where
219 toJSON = Number
299 toJSON = Number
220 {-# INLINE toJSON #-}
300 {-# INLINE toJSON #-}
221
301
222instance FromJSON Double where
302instance FromJSON Double where
223− fromJSON (Number n) = pure n
303+ parseJSON (Number n) = pure n
224− fromJSON _ = empty
304+ parseJSON _ = empty
225− {-# INLINE fromJSON #-}
305+ {-# INLINE parseJSON #-}
226
306
227instance ToJSON Float where
307instance ToJSON Float where
228 toJSON = Number . fromRational . toRational
308 toJSON = Number . fromRational . toRational
229 {-# INLINE toJSON #-}
309 {-# INLINE toJSON #-}
230
310
231instance FromJSON Float where
311instance FromJSON Float where
232− fromJSON (Number n) = pure . fromRational . toRational $ n
312+ parseJSON (Number n) = pure . fromRational . toRational $ n
233− fromJSON _ = empty
313+ parseJSON _ = empty
234− {-# INLINE fromJSON #-}
314+ {-# INLINE parseJSON #-}
235
315
236instance ToJSON (Ratio Integer) where
316instance ToJSON (Ratio Integer) where
237 toJSON = Number . fromRational
317 toJSON = Number . fromRational
238 {-# INLINE toJSON #-}
318 {-# INLINE toJSON #-}
239
319
240instance FromJSON (Ratio Integer) where
320instance FromJSON (Ratio Integer) where
241− fromJSON (Number n) = pure . toRational $ n
321+ parseJSON (Number n) = pure . toRational $ n
242− fromJSON _ = empty
322+ parseJSON _ = empty
243− {-# INLINE fromJSON #-}
323+ {-# INLINE parseJSON #-}
244
324
245instance ToJSON Int where
325instance ToJSON Int where
246 toJSON = Number . fromIntegral
326 toJSON = Number . fromIntegral
247 {-# INLINE toJSON #-}
327 {-# INLINE toJSON #-}
248
328
249instance FromJSON Int where
329instance FromJSON Int where
250− fromJSON (Number n) = pure (floor n)
330+ parseJSON (Number n) = pure (floor n)
251− fromJSON _ = empty
331+ parseJSON _ = empty
252− {-# INLINE fromJSON #-}
332+ {-# INLINE parseJSON #-}
253
333
254instance ToJSON Integer where
334instance ToJSON Integer where
255 toJSON = Number . fromIntegral
335 toJSON = Number . fromIntegral
256 {-# INLINE toJSON #-}
336 {-# INLINE toJSON #-}
257
337
258instance FromJSON Integer where
338instance FromJSON Integer where
259− fromJSON (Number n) = pure (floor n)
339+ parseJSON (Number n) = pure (floor n)
260− fromJSON _ = empty
340+ parseJSON _ = empty
261− {-# INLINE fromJSON #-}
341+ {-# INLINE parseJSON #-}
262
342
263instance ToJSON Int8 where
343instance ToJSON Int8 where
264 toJSON = Number . fromIntegral
344 toJSON = Number . fromIntegral
265 {-# INLINE toJSON #-}
345 {-# INLINE toJSON #-}
266
346
267instance FromJSON Int8 where
347instance FromJSON Int8 where
268− fromJSON (Number n) = pure (floor n)
348+ parseJSON (Number n) = pure (floor n)
269− fromJSON _ = empty
349+ parseJSON _ = empty
270− {-# INLINE fromJSON #-}
350+ {-# INLINE parseJSON #-}
271
351
272instance ToJSON Int16 where
352instance ToJSON Int16 where
273 toJSON = Number . fromIntegral
353 toJSON = Number . fromIntegral
274 {-# INLINE toJSON #-}
354 {-# INLINE toJSON #-}
275
355
276instance FromJSON Int16 where
356instance FromJSON Int16 where
277− fromJSON (Number n) = pure (floor n)
357+ parseJSON (Number n) = pure (floor n)
278− fromJSON _ = empty
358+ parseJSON _ = empty
279− {-# INLINE fromJSON #-}
359+ {-# INLINE parseJSON #-}
280
360
281instance ToJSON Int32 where
361instance ToJSON Int32 where
282 toJSON = Number . fromIntegral
362 toJSON = Number . fromIntegral
283 {-# INLINE toJSON #-}
363 {-# INLINE toJSON #-}
284
364
285instance FromJSON Int32 where
365instance FromJSON Int32 where
286− fromJSON (Number n) = pure (floor n)
366+ parseJSON (Number n) = pure (floor n)
287− fromJSON _ = empty
367+ parseJSON _ = empty
288− {-# INLINE fromJSON #-}
368+ {-# INLINE parseJSON #-}
289
369
290instance ToJSON Int64 where
370instance ToJSON Int64 where
291 toJSON = Number . fromIntegral
371 toJSON = Number . fromIntegral
292 {-# INLINE toJSON #-}
372 {-# INLINE toJSON #-}
293
373
294instance FromJSON Int64 where
374instance FromJSON Int64 where
295− fromJSON (Number n) = pure (floor n)
375+ parseJSON (Number n) = pure (floor n)
296− fromJSON _ = empty
376+ parseJSON _ = empty
297− {-# INLINE fromJSON #-}
377+ {-# INLINE parseJSON #-}
298
378
299instance ToJSON Word where
379instance ToJSON Word where
300 toJSON = Number . fromIntegral
380 toJSON = Number . fromIntegral
301 {-# INLINE toJSON #-}
381 {-# INLINE toJSON #-}
302
382
303instance FromJSON Word where
383instance FromJSON Word where
304− fromJSON (Number n) = pure (floor n)
384+ parseJSON (Number n) = pure (floor n)
305− fromJSON _ = empty
385+ parseJSON _ = empty
306− {-# INLINE fromJSON #-}
386+ {-# INLINE parseJSON #-}
307
387
308instance ToJSON Word8 where
388instance ToJSON Word8 where
309 toJSON = Number . fromIntegral
389 toJSON = Number . fromIntegral
310 {-# INLINE toJSON #-}
390 {-# INLINE toJSON #-}
311
391
312instance FromJSON Word8 where
392instance FromJSON Word8 where
313− fromJSON (Number n) = pure (floor n)
393+ parseJSON (Number n) = pure (floor n)
314− fromJSON _ = empty
394+ parseJSON _ = empty
315− {-# INLINE fromJSON #-}
395+ {-# INLINE parseJSON #-}
316
396
317instance ToJSON Word16 where
397instance ToJSON Word16 where
318 toJSON = Number . fromIntegral
398 toJSON = Number . fromIntegral
319 {-# INLINE toJSON #-}
399 {-# INLINE toJSON #-}
320
400
321instance FromJSON Word16 where
401instance FromJSON Word16 where
322− fromJSON (Number n) = pure (floor n)
402+ parseJSON (Number n) = pure (floor n)
323− fromJSON _ = empty
403+ parseJSON _ = empty
324− {-# INLINE fromJSON #-}
404+ {-# INLINE parseJSON #-}
325
405
326instance ToJSON Word32 where
406instance ToJSON Word32 where
327 toJSON = Number . fromIntegral
407 toJSON = Number . fromIntegral
328 {-# INLINE toJSON #-}
408 {-# INLINE toJSON #-}
329
409
330instance FromJSON Word32 where
410instance FromJSON Word32 where
331− fromJSON (Number n) = pure (floor n)
411+ parseJSON (Number n) = pure (floor n)
332− fromJSON _ = empty
412+ parseJSON _ = empty
333− {-# INLINE fromJSON #-}
413+ {-# INLINE parseJSON #-}
334
414
335instance ToJSON Word64 where
415instance ToJSON Word64 where
336 toJSON = Number . fromIntegral
416 toJSON = Number . fromIntegral
337 {-# INLINE toJSON #-}
417 {-# INLINE toJSON #-}
338
418
339instance FromJSON Word64 where
419instance FromJSON Word64 where
340− fromJSON (Number n) = pure (floor n)
420+ parseJSON (Number n) = pure (floor n)
341− fromJSON _ = empty
421+ parseJSON _ = empty
342− {-# INLINE fromJSON #-}
422+ {-# INLINE parseJSON #-}
343
423
344instance ToJSON Text where
424instance ToJSON Text where
345 toJSON = String
425 toJSON = String
346 {-# INLINE toJSON #-}
426 {-# INLINE toJSON #-}
347
427
348instance FromJSON Text where
428instance FromJSON Text where
349− fromJSON (String t) = pure t
429+ parseJSON (String t) = pure t
350− fromJSON _ = empty
430+ parseJSON _ = empty
351− {-# INLINE fromJSON #-}
431+ {-# INLINE parseJSON #-}
352
432
353instance ToJSON LT.Text where
433instance ToJSON LT.Text where
354 toJSON = String . LT.toStrict
434 toJSON = String . LT.toStrict
355 {-# INLINE toJSON #-}
435 {-# INLINE toJSON #-}
356
436
357instance FromJSON LT.Text where
437instance FromJSON LT.Text where
358− fromJSON (String t) = pure (LT.fromStrict t)
438+ parseJSON (String t) = pure (LT.fromStrict t)
359− fromJSON _ = empty
439+ parseJSON _ = empty
360− {-# INLINE fromJSON #-}
440+ {-# INLINE parseJSON #-}
361
441
362instance ToJSON B.ByteString where
442instance ToJSON B.ByteString where
363 toJSON = String . decodeUtf8
443 toJSON = String . decodeUtf8
364 {-# INLINE toJSON #-}
444 {-# INLINE toJSON #-}
365
445
366instance FromJSON B.ByteString where
446instance FromJSON B.ByteString where
367− fromJSON (String t) = pure . encodeUtf8 $ t
447+ parseJSON (String t) = pure . encodeUtf8 $ t
368− fromJSON _ = empty
448+ parseJSON _ = empty
369− {-# INLINE fromJSON #-}
449+ {-# INLINE parseJSON #-}
370
450
371instance ToJSON LB.ByteString where
451instance ToJSON LB.ByteString where
372 toJSON = toJSON . B.concat . LB.toChunks
452 toJSON = toJSON . B.concat . LB.toChunks
373 {-# INLINE toJSON #-}
453 {-# INLINE toJSON #-}
374
454
375instance FromJSON LB.ByteString where
455instance FromJSON LB.ByteString where
376− fromJSON (String t) = pure . LB.fromChunks . (:[]) . encodeUtf8 $ t
456+ parseJSON (String t) = pure . LB.fromChunks . (:[]) . encodeUtf8 $ t
377− fromJSON _ = empty
457+ parseJSON _ = empty
378− {-# INLINE fromJSON #-}
458+ {-# INLINE parseJSON #-}
379
459
380instance (ToJSON a) => ToJSON [a] where
460instance (ToJSON a) => ToJSON [a] where
381 toJSON = Array . V.fromList . map toJSON
461 toJSON = Array . V.fromList . map toJSON
382 {-# INLINE toJSON #-}
462 {-# INLINE toJSON #-}
383
463
384instance (FromJSON a) => FromJSON [a] where
464instance (FromJSON a) => FromJSON [a] where
385− fromJSON (Array a) = mapA fromJSON (V.toList a)
465+ parseJSON (Array a) = mapA parseJSON (V.toList a)
386− fromJSON _ = empty
466+ parseJSON _ = empty
387− {-# INLINE fromJSON #-}
467+ {-# INLINE parseJSON #-}
388
468
389instance (ToJSON a) => ToJSON (Vector a) where
469instance (ToJSON a) => ToJSON (Vector a) where
390 toJSON = Array . V.map toJSON
470 toJSON = Array . V.map toJSON
391 {-# INLINE toJSON #-}
471 {-# INLINE toJSON #-}
392
472
393instance (FromJSON a) => FromJSON (Vector a) where
473instance (FromJSON a) => FromJSON (Vector a) where
394− fromJSON (Array a) = V.fromList <$> mapA fromJSON (V.toList a)
474+ parseJSON (Array a) = V.fromList <$> mapA parseJSON (V.toList a)
395− fromJSON _ = empty
475+ parseJSON _ = empty
396− {-# INLINE fromJSON #-}
476+ {-# INLINE parseJSON #-}
397
477
398instance (ToJSON a) => ToJSON (Set.Set a) where
478instance (ToJSON a) => ToJSON (Set.Set a) where
399 toJSON = toJSON . Set.toList
479 toJSON = toJSON . Set.toList
400 {-# INLINE toJSON #-}
480 {-# INLINE toJSON #-}
401
481
402instance (Ord a, FromJSON a) => FromJSON (Set.Set a) where
482instance (Ord a, FromJSON a) => FromJSON (Set.Set a) where
403− fromJSON = fmap Set.fromList . fromJSON
483+ parseJSON = fmap Set.fromList . parseJSON
404− {-# INLINE fromJSON #-}
484+ {-# INLINE parseJSON #-}
405
485
406instance ToJSON IntSet.IntSet where
486instance ToJSON IntSet.IntSet where
407 toJSON = toJSON . IntSet.toList
487 toJSON = toJSON . IntSet.toList
408 {-# INLINE toJSON #-}
488 {-# INLINE toJSON #-}
409
489
410instance FromJSON IntSet.IntSet where
490instance FromJSON IntSet.IntSet where
411− fromJSON = fmap IntSet.fromList . fromJSON
491+ parseJSON = fmap IntSet.fromList . parseJSON
412− {-# INLINE fromJSON #-}
492+ {-# INLINE parseJSON #-}
413
493
414instance (ToJSON v) => ToJSON (M.Map Text v) where
494instance (ToJSON v) => ToJSON (M.Map Text v) where
415 toJSON = Object . M.map toJSON
495 toJSON = Object . M.map toJSON
416 {-# INLINE toJSON #-}
496 {-# INLINE toJSON #-}
417
497
418instance (FromJSON v) => FromJSON (M.Map Text v) where
498instance (FromJSON v) => FromJSON (M.Map Text v) where
419− fromJSON (Object o) = M.fromAscList <$> go (M.toAscList o)
499+ parseJSON (Object o) = M.fromAscList <$> go (M.toAscList o)
420 where
500 where
421− go ((k,v):kvs) = ((:) . (,) k) <$> fromJSON v <*> go kvs
501+ go ((k,v):kvs) = ((:) . (,) k) <$> parseJSON v <*> go kvs
422 go _ = pure []
502 go _ = pure []
423− fromJSON _ = empty
503+ parseJSON _ = empty
424
504
425instance (ToJSON v) => ToJSON (M.Map LT.Text v) where
505instance (ToJSON v) => ToJSON (M.Map LT.Text v) where
426 toJSON = Object . transformMap LT.toStrict toJSON
506 toJSON = Object . transformMap LT.toStrict toJSON
427
507
428instance (FromJSON v) => FromJSON (M.Map LT.Text v) where
508instance (FromJSON v) => FromJSON (M.Map LT.Text v) where
429− fromJSON = fmap (M.mapKeysMonotonic LT.fromStrict) . fromJSON
509+ parseJSON = fmap (M.mapKeysMonotonic LT.fromStrict) . parseJSON
430
510
431instance (ToJSON v) => ToJSON (M.Map String v) where
511instance (ToJSON v) => ToJSON (M.Map String v) where
432 toJSON = Object . transformMap pack toJSON
512 toJSON = Object . transformMap pack toJSON
433
513
434instance (FromJSON v) => FromJSON (M.Map String v) where
514instance (FromJSON v) => FromJSON (M.Map String v) where
435− fromJSON = fmap (M.mapKeysMonotonic unpack) . fromJSON
515+ parseJSON = fmap (M.mapKeysMonotonic unpack) . parseJSON
436
516
437instance ToJSON Value where
517instance ToJSON Value where
438 toJSON a = a
518 toJSON a = a
439 {-# INLINE toJSON #-}
519 {-# INLINE toJSON #-}
440
520
441instance FromJSON Value where
521instance FromJSON Value where
442− fromJSON a = pure a
522+ parseJSON a = pure a
443− {-# INLINE fromJSON #-}
523+ {-# INLINE parseJSON #-}
444
524
445-- We happen to use the same JSON formatting for a UTCTime as .NET
525-- We happen to use the same JSON formatting for a UTCTime as .NET
446-- does for a DateTime. How handy!
526-- does for a DateTime. How handy!
@@ -449,47 +529,47 @@ instance ToJSON UTCTime where
449 {-# INLINE toJSON #-}
529 {-# INLINE toJSON #-}
450
530
451instance FromJSON UTCTime where
531instance FromJSON UTCTime where
452− fromJSON (String t) =
532+ parseJSON (String t) =
453 case parseTime defaultTimeLocale "/Date(%s)/" (unpack t) of
533 case parseTime defaultTimeLocale "/Date(%s)/" (unpack t) of
454 Just d -> pure d
534 Just d -> pure d
455 _ -> empty
535 _ -> empty
456− fromJSON _ = empty
536+ parseJSON _ = empty
457− {-# INLINE fromJSON #-}
537+ {-# INLINE parseJSON #-}
458
538
459instance (ToJSON a, ToJSON b) => ToJSON (a,b) where
539instance (ToJSON a, ToJSON b) => ToJSON (a,b) where
460 toJSON (a,b) = toJSON [toJSON a, toJSON b]
540 toJSON (a,b) = toJSON [toJSON a, toJSON b]
461 {-# INLINE toJSON #-}
541 {-# INLINE toJSON #-}
462
542
463instance (FromJSON a, FromJSON b) => FromJSON (a,b) where
543instance (FromJSON a, FromJSON b) => FromJSON (a,b) where
464− fromJSON (Array ab) = case V.toList ab of
544+ parseJSON (Array ab) = case V.toList ab of
465− [a,b] -> (,) <$> fromJSON a <*> fromJSON b
545+ [a,b] -> (,) <$> parseJSON a <*> parseJSON b
466 _ -> empty
546 _ -> empty
467− fromJSON _ = empty
547+ parseJSON _ = empty
468− {-# INLINE fromJSON #-}
548+ {-# INLINE parseJSON #-}
469
549
470instance ToJSON a => ToJSON (Dual a) where
550instance ToJSON a => ToJSON (Dual a) where
471 toJSON = toJSON . getDual
551 toJSON = toJSON . getDual
472 {-# INLINE toJSON #-}
552 {-# INLINE toJSON #-}
473
553
474instance FromJSON a => FromJSON (Dual a) where
554instance FromJSON a => FromJSON (Dual a) where
475− fromJSON = fmap Dual . fromJSON
555+ parseJSON = fmap Dual . parseJSON
476− {-# INLINE fromJSON #-}
556+ {-# INLINE parseJSON #-}
477
557
478instance ToJSON a => ToJSON (First a) where
558instance ToJSON a => ToJSON (First a) where
479 toJSON = toJSON . getFirst
559 toJSON = toJSON . getFirst
480 {-# INLINE toJSON #-}
560 {-# INLINE toJSON #-}
481
561
482instance FromJSON a => FromJSON (First a) where
562instance FromJSON a => FromJSON (First a) where
483− fromJSON = fmap First . fromJSON
563+ parseJSON = fmap First . parseJSON
484− {-# INLINE fromJSON #-}
564+ {-# INLINE parseJSON #-}
485
565
486instance ToJSON a => ToJSON (Last a) where
566instance ToJSON a => ToJSON (Last a) where
487 toJSON = toJSON . getLast
567 toJSON = toJSON . getLast
488 {-# INLINE toJSON #-}
568 {-# INLINE toJSON #-}
489
569
490instance FromJSON a => FromJSON (Last a) where
570instance FromJSON a => FromJSON (Last a) where
491− fromJSON = fmap Last . fromJSON
571+ parseJSON = fmap Last . parseJSON
492− {-# INLINE fromJSON #-}
572+ {-# INLINE parseJSON #-}
493
573
494mapA :: (Alternative m) => (t -> m a) -> [t] -> m [a]
574mapA :: (Alternative m) => (t -> m a) -> [t] -> m [a]
495mapA f = go
575mapA f = go
aeson.cabal+2−1
@@ -1,5 +1,5 @@
1name: aeson
1name: aeson
2−version: 0.1.0.2
2+version: 0.2.0.0
3license: BSD3
3license: BSD3
4license-file: LICENSE
4license-file: LICENSE
5category: Text, Web, JSON
5category: Text, Web, JSON
@@ -78,6 +78,7 @@ library
78 bytestring,
78 bytestring,
79 containers,
79 containers,
80 deepseq,
80 deepseq,
81+ monads-fd,
81 old-locale,
82 old-locale,
82 syb,
83 syb,
83 text >= 0.11.0.2,
84 text >= 0.11.0.2,