@@ -1,4 +1,5 @@
1−{-# LANGUAGE DeriveDataTypeable, FlexibleInstances #-}
1+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, IncoherentInstances,
2+ OverlappingInstances #-}
23
34-- Module: Data.Aeson.Types
45-- Copyright: (c) 2011 MailRank, Inc.
@@ -28,25 +29,30 @@ module Data.Aeson.Types
2829 , object
2930 ) where
3031
31−import Control.Arrow ((***))
3232import Control.Applicative
3333import Control.DeepSeq (NFData(..))
3434import Data.Data (Data)
35+import Data.Int (Int8, Int16, Int32, Int64)
36+import qualified Data.IntSet as IntSet
3537import Data.Map (Map)
3638import Data.Monoid (Dual(..), First(..), Last(..))
39+import Data.Ratio (Ratio)
3740import Data.Text (Text, pack, unpack)
3841import Data.Text.Encoding (decodeUtf8, encodeUtf8)
3942import Data.Time.Clock (UTCTime)
4043import Data.Time.Format (formatTime, parseTime)
4144import Data.Typeable (Typeable)
4245import Data.Vector (Vector)
46+import Data.Word (Word, Word8, Word16, Word32, Word64)
4347import System.Locale (defaultTimeLocale)
4448import qualified Data.ByteString as B
4549import qualified Data.ByteString.Lazy as LB
4650import qualified Data.Map as M
4751import qualified Data.Set as Set
52+import qualified Data.Text as T
4853import qualified Data.Text.Lazy as LT
4954import qualified Data.Vector as V
55+import Data.Aeson.Functions
5056
5157-- | A JSON \"object\" (key\/value map).
5258type Object = Map Text Value
@@ -80,15 +86,11 @@ emptyObject :: Value
8086emptyObject = Object M.empty
8187
8288-- | A key\/value pair for an 'Object'.
83−newtype Pair = Pair { unPair :: (Text, Value) }
84− deriving (Eq, Typeable)
85−
86−instance Show Pair where
87− show = show . unPair
89+type Pair = (Text, Value)
8890
8991-- | Construct a 'Pair' from a key and a value.
9092(.=) :: ToJSON a => Text -> a -> Pair
91−name .= value = Pair (name, toJSON value)
93+name .= value = (name, toJSON value)
9294{-# INLINE (.=) #-}
9395
9496-- | Retrieve the value associated with the given key of an 'Object'.
@@ -117,10 +119,10 @@ obj .:? key = case M.lookup key obj of
117119 Just v -> fromJSON v
118120{-# INLINE (.:?) #-}
119121
120−-- | Create a 'Value' from a list of 'Pair's. If duplicate
122+-- | Create a 'Value' from a list of name\/value 'Pair's. If duplicate
121123-- keys arise, earlier keys and their associated values win.
122124object :: [Pair] -> Value
123−object = Object . M.fromList . map unPair
125+object = Object . M.fromList
124126{-# INLINE object #-}
125127
126128-- | A type that can be converted to JSON.
@@ -185,6 +187,34 @@ instance FromJSON Bool where
185187 fromJSON _ = empty
186188 {-# INLINE fromJSON #-}
187189
190+instance ToJSON () where
191+ toJSON _ = emptyArray
192+ {-# INLINE toJSON #-}
193+
194+instance FromJSON () where
195+ fromJSON (Array v) | V.null v = pure ()
196+ fromJSON _ = empty
197+ {-# INLINE fromJSON #-}
198+
199+instance ToJSON [Char] where
200+ toJSON = String . T.pack
201+ {-# INLINE toJSON #-}
202+
203+instance FromJSON [Char] where
204+ fromJSON (String t) = pure (T.unpack t)
205+ fromJSON _ = empty
206+ {-# INLINE fromJSON #-}
207+
208+instance ToJSON Char where
209+ toJSON = String . T.singleton
210+ {-# INLINE toJSON #-}
211+
212+instance FromJSON Char where
213+ fromJSON (String t)
214+ | T.compareLength t 1 == EQ = pure (T.head t)
215+ fromJSON _ = empty
216+ {-# INLINE fromJSON #-}
217+
188218instance ToJSON Double where
189219 toJSON = Number
190220 {-# INLINE toJSON #-}
@@ -194,6 +224,24 @@ instance FromJSON Double where
194224 fromJSON _ = empty
195225 {-# INLINE fromJSON #-}
196226
227+instance ToJSON Float where
228+ toJSON = Number . fromRational . toRational
229+ {-# INLINE toJSON #-}
230+
231+instance FromJSON Float where
232+ fromJSON (Number n) = pure . fromRational . toRational $ n
233+ fromJSON _ = empty
234+ {-# INLINE fromJSON #-}
235+
236+instance ToJSON (Ratio Integer) where
237+ toJSON = Number . fromRational
238+ {-# INLINE toJSON #-}
239+
240+instance FromJSON (Ratio Integer) where
241+ fromJSON (Number n) = pure . toRational $ n
242+ fromJSON _ = empty
243+ {-# INLINE fromJSON #-}
244+
197245instance ToJSON Int where
198246 toJSON = Number . fromIntegral
199247 {-# INLINE toJSON #-}
@@ -212,6 +260,87 @@ instance FromJSON Integer where
212260 fromJSON _ = empty
213261 {-# INLINE fromJSON #-}
214262
263+instance ToJSON Int8 where
264+ toJSON = Number . fromIntegral
265+ {-# INLINE toJSON #-}
266+
267+instance FromJSON Int8 where
268+ fromJSON (Number n) = pure (floor n)
269+ fromJSON _ = empty
270+ {-# INLINE fromJSON #-}
271+
272+instance ToJSON Int16 where
273+ toJSON = Number . fromIntegral
274+ {-# INLINE toJSON #-}
275+
276+instance FromJSON Int16 where
277+ fromJSON (Number n) = pure (floor n)
278+ fromJSON _ = empty
279+ {-# INLINE fromJSON #-}
280+
281+instance ToJSON Int32 where
282+ toJSON = Number . fromIntegral
283+ {-# INLINE toJSON #-}
284+
285+instance FromJSON Int32 where
286+ fromJSON (Number n) = pure (floor n)
287+ fromJSON _ = empty
288+ {-# INLINE fromJSON #-}
289+
290+instance ToJSON Int64 where
291+ toJSON = Number . fromIntegral
292+ {-# INLINE toJSON #-}
293+
294+instance FromJSON Int64 where
295+ fromJSON (Number n) = pure (floor n)
296+ fromJSON _ = empty
297+ {-# INLINE fromJSON #-}
298+
299+instance ToJSON Word where
300+ toJSON = Number . fromIntegral
301+ {-# INLINE toJSON #-}
302+
303+instance FromJSON Word where
304+ fromJSON (Number n) = pure (floor n)
305+ fromJSON _ = empty
306+ {-# INLINE fromJSON #-}
307+
308+instance ToJSON Word8 where
309+ toJSON = Number . fromIntegral
310+ {-# INLINE toJSON #-}
311+
312+instance FromJSON Word8 where
313+ fromJSON (Number n) = pure (floor n)
314+ fromJSON _ = empty
315+ {-# INLINE fromJSON #-}
316+
317+instance ToJSON Word16 where
318+ toJSON = Number . fromIntegral
319+ {-# INLINE toJSON #-}
320+
321+instance FromJSON Word16 where
322+ fromJSON (Number n) = pure (floor n)
323+ fromJSON _ = empty
324+ {-# INLINE fromJSON #-}
325+
326+instance ToJSON Word32 where
327+ toJSON = Number . fromIntegral
328+ {-# INLINE toJSON #-}
329+
330+instance FromJSON Word32 where
331+ fromJSON (Number n) = pure (floor n)
332+ fromJSON _ = empty
333+ {-# INLINE fromJSON #-}
334+
335+instance ToJSON Word64 where
336+ toJSON = Number . fromIntegral
337+ {-# INLINE toJSON #-}
338+
339+instance FromJSON Word64 where
340+ fromJSON (Number n) = pure (floor n)
341+ fromJSON _ = empty
342+ {-# INLINE fromJSON #-}
343+
215344instance ToJSON Text where
216345 toJSON = String
217346 {-# INLINE toJSON #-}
@@ -274,6 +403,14 @@ instance (Ord a, FromJSON a) => FromJSON (Set.Set a) where
274403 fromJSON = fmap Set.fromList . fromJSON
275404 {-# INLINE fromJSON #-}
276405
406+instance ToJSON IntSet.IntSet where
407+ toJSON = toJSON . IntSet.toList
408+ {-# INLINE toJSON #-}
409+
410+instance FromJSON IntSet.IntSet where
411+ fromJSON = fmap IntSet.fromList . fromJSON
412+ {-# INLINE fromJSON #-}
413+
277414instance (ToJSON v) => ToJSON (M.Map Text v) where
278415 toJSON = Object . M.map toJSON
279416 {-# INLINE toJSON #-}
@@ -354,12 +491,6 @@ instance FromJSON a => FromJSON (Last a) where
354491 fromJSON = fmap Last . fromJSON
355492 {-# INLINE fromJSON #-}
356493
357−-- | Transform one map into another. The ordering of keys must be
358−-- preserved.
359−transformMap :: (Ord k1, Ord k2) => (k1 -> k2) -> (v1 -> v2)
360− -> M.Map k1 v1 -> M.Map k2 v2
361−transformMap fk fv = M.fromAscList . map (fk *** fv) . M.toAscList
362−
363494mapA :: (Alternative m) => (t -> m a) -> [t] -> m [a]
364495mapA f = go
365496 where