on 0.11.x help sign in
427 lines 14 kB history raw
1-- |
2-- Module: Data.Aeson
3-- Copyright: (c) 2011-2016 Bryan O'Sullivan
4-- (c) 2011 MailRank, Inc.
5-- License: BSD3
6-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>
7-- Stability: experimental
8-- Portability: portable
9--
10-- Types and functions for working efficiently with JSON data.
11--
12-- (A note on naming: in Greek mythology, Aeson was the father of Jason.)
14module Data.Aeson
15 (
16 -- * How to use this library
17 -- $use
19 -- ** Writing instances by hand
20 -- $manual
22 -- ** Working with the AST
23 -- $ast
25 -- ** Decoding to a Haskell value
26 -- $haskell
28 -- ** Decoding a mixed-type object
29 -- $mixed
31 -- * Encoding and decoding
32 -- $encoding_and_decoding
34 -- ** Direct encoding
35 -- $encoding
36 decode
37 , decode'
38 , eitherDecode
39 , eitherDecode'
40 , encode
41 -- ** Variants for strict bytestrings
42 , decodeStrict
43 , decodeStrict'
44 , eitherDecodeStrict
45 , eitherDecodeStrict'
46 -- * Core JSON types
47 , Value(..)
48 , Encoding
49 , fromEncoding
50 , Array
51 , Object
52 -- * Convenience types
53 , DotNetTime(..)
54 -- * Type conversion
55 , FromJSON(..)
56 , Result(..)
57 , fromJSON
58 , ToJSON(..)
59 , KeyValue(..)
60 -- ** Generic JSON classes and options
61 , GFromJSON(..)
62 , GToJSON(..)
63 , GToEncoding(..)
64 , genericToJSON
65 , genericToEncoding
66 , genericParseJSON
67 , defaultOptions
69 -- * Inspecting @'Value's@
70 , withObject
71 , withText
72 , withArray
73 , withNumber
74 , withScientific
75 , withBool
76 -- * Constructors and accessors
77 , Series
78 , pairs
79 , foldable
80 , (.:)
81 , (.:?)
82 , (.:!)
83 , (.!=)
84 , object
85 -- * Parsing
86 , json
87 , json'
88 ) where
90import Data.Aeson.Encode (encode)
91import Data.Aeson.Parser.Internal (decodeWith, decodeStrictWith,
92 eitherDecodeWith, eitherDecodeStrictWith,
93 jsonEOF, json, jsonEOF', json')
94import Data.Aeson.Types
95import Data.Aeson.Types.Instances (ifromJSON)
96import Data.Aeson.Types.Internal (JSONPath, formatError)
97import qualified Data.ByteString as B
98import qualified Data.ByteString.Lazy as L
100-- | Efficiently deserialize a JSON value from a lazy 'L.ByteString'.
101-- If this fails due to incomplete or invalid input, 'Nothing' is
102-- returned.
103--
104-- The input must consist solely of a JSON document, with no trailing
105-- data except for whitespace.
106--
107-- This function parses immediately, but defers conversion. See
108-- 'json' for details.
109decode :: (FromJSON a) => L.ByteString -> Maybe a
110decode = decodeWith jsonEOF fromJSON
111{-# INLINE decode #-}
113-- | Efficiently deserialize a JSON value from a strict 'B.ByteString'.
114-- If this fails due to incomplete or invalid input, 'Nothing' is
115-- returned.
116--
117-- The input must consist solely of a JSON document, with no trailing
118-- data except for whitespace.
119--
120-- This function parses immediately, but defers conversion. See
121-- 'json' for details.
122decodeStrict :: (FromJSON a) => B.ByteString -> Maybe a
123decodeStrict = decodeStrictWith jsonEOF fromJSON
124{-# INLINE decodeStrict #-}
126-- | Efficiently deserialize a JSON value from a lazy 'L.ByteString'.
127-- If this fails due to incomplete or invalid input, 'Nothing' is
128-- returned.
129--
130-- The input must consist solely of a JSON document, with no trailing
131-- data except for whitespace.
132--
133-- This function parses and performs conversion immediately. See
134-- 'json'' for details.
135decode' :: (FromJSON a) => L.ByteString -> Maybe a
136decode' = decodeWith jsonEOF' fromJSON
137{-# INLINE decode' #-}
139-- | Efficiently deserialize a JSON value from a lazy 'L.ByteString'.
140-- If this fails due to incomplete or invalid input, 'Nothing' is
141-- returned.
142--
143-- The input must consist solely of a JSON document, with no trailing
144-- data except for whitespace.
145--
146-- This function parses and performs conversion immediately. See
147-- 'json'' for details.
148decodeStrict' :: (FromJSON a) => B.ByteString -> Maybe a
149decodeStrict' = decodeStrictWith jsonEOF' fromJSON
150{-# INLINE decodeStrict' #-}
152eitherFormatError :: Either (JSONPath, String) a -> Either String a
153eitherFormatError = either (Left . uncurry formatError) Right
154{-# INLINE eitherFormatError #-}
156-- | Like 'decode' but returns an error message when decoding fails.
157eitherDecode :: (FromJSON a) => L.ByteString -> Either String a
158eitherDecode = eitherFormatError . eitherDecodeWith jsonEOF ifromJSON
159{-# INLINE eitherDecode #-}
161-- | Like 'decodeStrict' but returns an error message when decoding fails.
162eitherDecodeStrict :: (FromJSON a) => B.ByteString -> Either String a
163eitherDecodeStrict =
164 eitherFormatError . eitherDecodeStrictWith jsonEOF ifromJSON
165{-# INLINE eitherDecodeStrict #-}
167-- | Like 'decode'' but returns an error message when decoding fails.
168eitherDecode' :: (FromJSON a) => L.ByteString -> Either String a
169eitherDecode' = eitherFormatError . eitherDecodeWith jsonEOF' ifromJSON
170{-# INLINE eitherDecode' #-}
172-- | Like 'decodeStrict'' but returns an error message when decoding fails.
173eitherDecodeStrict' :: (FromJSON a) => B.ByteString -> Either String a
174eitherDecodeStrict' =
175 eitherFormatError . eitherDecodeStrictWith jsonEOF' ifromJSON
176{-# INLINE eitherDecodeStrict' #-}
178-- $use
179--
180-- This section contains basic information on the different ways to
181-- work with data using this library. These range from simple but
182-- inflexible, to complex but flexible.
183--
184-- The most common way to use the library is to define a data type,
185-- corresponding to some JSON data you want to work with, and then
186-- write either a 'FromJSON' instance, a to 'ToJSON' instance, or both
187-- for that type.
188--
189-- For example, given this JSON data:
190--
191-- > { "name": "Joe", "age": 12 }
192--
193-- we create a matching data type:
194--
195-- > {-# LANGUAGE DeriveGeneric #-}
196-- >
197-- > import GHC.Generics
198-- >
199-- > data Person = Person {
200-- > name :: Text
201-- > , age :: Int
202-- > } deriving (Generic, Show)
203--
204-- The @LANGUAGE@ pragma and 'Generic' instance let us write empty
205-- 'FromJSON' and 'ToJSON' instances for which the compiler will
206-- generate sensible default implementations.
207--
208-- @
209-- instance 'ToJSON' Person where
210-- \-- No need to provide a 'toJSON' implementation.
211--
212-- \-- For efficiency, we write a simple 'toEncoding' implementation, as
213-- \-- the default version uses 'toJSON'.
214-- 'toEncoding' = 'genericToEncoding' 'defaultOptions'
215--
216-- instance 'FromJSON' Person
217-- \-- No need to provide a 'parseJSON' implementation.
218-- @
219--
220-- We can now encode a value like so:
221--
222-- > >>> encode (Person {name = "Joe", age = 12})
223-- > "{\"name\":\"Joe\",\"age\":12}"
225-- $manual
226--
227-- When necessary, we can write 'ToJSON' and 'FromJSON' instances by
228-- hand. This is valuable when the JSON-on-the-wire and Haskell data
229-- are different or otherwise need some more carefully managed
230-- translation. Let's revisit our JSON data:
231--
232-- > { "name": "Joe", "age": 12 }
233--
234-- We once again create a matching data type, without bothering to add
235-- a 'Generic' instance this time:
236--
237-- > data Person = Person {
238-- > name :: Text
239-- > , age :: Int
240-- > } deriving Show
241--
242-- To decode data, we need to define a 'FromJSON' instance:
243--
244-- > {-# LANGUAGE OverloadedStrings #-}
245-- >
246-- > instance FromJSON Person where
247-- > parseJSON (Object v) = Person <$>
248-- > v .: "name" <*>
249-- > v .: "age"
250-- > -- A non-Object value is of the wrong type, so fail.
251-- > parseJSON _ = empty
252--
253-- We can now parse the JSON data like so:
254--
255-- > >>> decode "{\"name\":\"Joe\",\"age\":12}" :: Maybe Person
256-- > Just (Person {name = "Joe", age = 12})
257--
258-- To encode data, we need to define a 'ToJSON' instance. Let's begin
259-- with an instance written entirely by hand.
260--
261-- @
262-- instance ToJSON Person where
263-- \-- this generates a 'Value'
264-- 'toJSON' (Person name age) =
265-- 'object' [\"name\" '.=' name, \"age\" '.=' age]
266--
267-- \-- this encodes directly to a bytestring Builder
268-- 'toEncoding' (Person name age) =
269-- 'pairs' (\"name\" '.=' 'name' '<>' \"age\" '.=' age)
270-- @
271--
272-- We can now encode a value like so:
273--
274-- > >>> encode (Person {name = "Joe", age = 12})
275-- > "{\"name\":\"Joe\",\"age\":12}"
276--
277-- There are predefined 'FromJSON' and 'ToJSON' instances for many
278-- types. Here's an example using lists and 'Int's:
279--
280-- > >>> decode "[1,2,3]" :: Maybe [Int]
281-- > Just [1,2,3]
282--
283-- And here's an example using the 'Data.Map.Map' type to get a map of
284-- 'Int's.
285--
286-- > >>> decode "{\"foo\":1,\"bar\":2}" :: Maybe (Map String Int)
287-- > Just (fromList [("bar",2),("foo",1)])
289-- While the notes below focus on decoding, you can apply almost the
290-- same techniques to /encoding/ data. (The main difference is that
291-- encoding always succeeds, but decoding has to handle the
292-- possibility of failure, where an input doesn't match our
293-- expectations.)
294--
295-- See the documentation of 'FromJSON' and 'ToJSON' for some examples
296-- of how you can automatically derive instances in many common
297-- circumstances.
299-- $ast
300--
301-- Sometimes you want to work with JSON data directly, without first
302-- converting it to a custom data type. This can be useful if you want
303-- to e.g. convert JSON data to YAML data, without knowing what the
304-- contents of the original JSON data was. The 'Value' type, which is
305-- an instance of 'FromJSON', is used to represent an arbitrary JSON
306-- AST (abstract syntax tree). Example usage:
307--
308-- > >>> decode "{\"foo\": 123}" :: Maybe Value
309-- > Just (Object (fromList [("foo",Number 123)]))
310--
311-- > >>> decode "{\"foo\": [\"abc\",\"def\"]}" :: Maybe Value
312-- > Just (Object (fromList [("foo",Array (fromList [String "abc",String "def"]))]))
313--
314-- Once you have a 'Value' you can write functions to traverse it and
315-- make arbitrary transformations.
317-- $haskell
318--
319-- We can decode to any instance of 'FromJSON':
320--
321-- > λ> decode "[1,2,3]" :: Maybe [Int]
322-- > Just [1,2,3]
323--
324-- Alternatively, there are instances for standard data types, so you
325-- can use them directly. For example, use the 'Data.Map.Map' type to
326-- get a map of 'Int's.
327--
328-- > λ> import Data.Map
329-- > λ> decode "{\"foo\":1,\"bar\":2}" :: Maybe (Map String Int)
330-- > Just (fromList [("bar",2),("foo",1)])
332-- $mixed
333--
334-- The above approach with maps of course will not work for mixed-type
335-- objects that don't follow a strict schema, but there are a couple
336-- of approaches available for these.
337--
338-- The 'Object' type contains JSON objects:
339--
340-- > λ> decode "{\"name\":\"Dave\",\"age\":2}" :: Maybe Object
341-- > Just (fromList) [("name",String "Dave"),("age",Number 2)]
342--
343-- You can extract values from it with a parser using 'parse',
344-- 'parseEither' or, in this example, 'parseMaybe':
345--
346-- > λ> do result <- decode "{\"name\":\"Dave\",\"age\":2}"
347-- > flip parseMaybe result $ \obj -> do
348-- > age <- obj .: "age"
349-- > name <- obj .: "name"
350-- > return (name ++ ": " ++ show (age*2))
351-- >
352-- > Just "Dave: 4"
353--
354-- Considering that any type that implements 'FromJSON' can be used
355-- here, this is quite a powerful way to parse JSON. See the
356-- documentation in 'FromJSON' for how to implement this class for
357-- your own data types.
358--
359-- The downside is that you have to write the parser yourself; the
360-- upside is that you have complete control over the way the JSON is
361-- parsed.
363-- $encoding_and_decoding
364--
365-- Decoding is a two-step process.
366--
367-- * When decoding a value, the process is reversed: the bytes are
368-- converted to a 'Value', then the 'FromJSON' class is used to
369-- convert to the desired type.
370--
371-- There are two ways to encode a value.
372--
373-- * Convert to a 'Value' using 'toJSON', then possibly further
374-- encode. This was the only method available in aeson 0.9 and
375-- earlier.
376--
377-- * Directly encode (to what will become a 'L.ByteString') using
378-- 'toEncoding'. This is much more efficient (about 3x faster, and
379-- less memory intensive besides), but is only available in aeson
380-- 0.10 and newer.
381--
382-- For convenience, the 'encode' and 'decode' functions combine both
383-- steps.
385-- $encoding
386--
387-- In older versions of this library, encoding a Haskell value
388-- involved converting to an intermediate 'Value', then encoding that.
389--
390-- A \"direct\" encoder converts straight from a source Haskell value
391-- to a 'BL.ByteString' without constructing an intermediate 'Value'.
392-- This approach is faster than 'toJSON', and allocates less memory.
393-- The 'toEncoding' method makes it possible to implement direct
394-- encoding with low memory overhead.
395--
396-- To complicate matters, the default implementation of 'toEncoding'
397-- uses 'toJSON'. Why? The 'toEncoding' method was added to this
398-- library much more recently than 'toJSON'. Using 'toJSON' ensures
399-- that packages written against older versions of this library will
400-- compile and produce correct output, but they will not see any
401-- speedup from direct encoding.
402--
403-- To write a minimal implementation of direct encoding, your type
404-- must implement GHC's 'Generic' class, and your code should look
405-- like this:
406--
407-- @
408-- 'toEncoding' = 'genericToEncoding' 'defaultOptions'
409-- @
410--
411-- What if you have more elaborate encoding needs? For example,
412-- perhaps you need to change the names of object keys, omit parts of
413-- a value.
414--
415-- To encode to a JSON \"object\", use the 'pairs' function.
416--
417-- @
418-- 'toEncoding' (Person name age) =
419-- 'pairs' (\"name\" '.=' 'name' '<>' \"age\" '.=' age)
420-- @
421--
422-- Any container type that implements 'Foldable' can be encoded to a
423-- JSON \"array\" using 'foldable'.
424--
425-- > > import Data.Sequence as Seq
426-- > > encode (Seq.fromList [1,2,3])
427-- > "[1,2,3]"