on 1.2.2.0 help sign in
470 lines 15 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 -- ** Keys for maps
61 , ToJSONKey(..)
62 , ToJSONKeyFunction(..)
63 , FromJSONKey(..)
64 , FromJSONKeyFunction(..)
65 -- ** Liftings to unary and binary type constructors
66 , FromJSON1(..)
67 , parseJSON1
68 , FromJSON2(..)
69 , parseJSON2
70 , ToJSON1(..)
71 , toJSON1
72 , toEncoding1
73 , ToJSON2(..)
74 , toJSON2
75 , toEncoding2
76 -- ** Generic JSON classes and options
77 , GFromJSON(..)
78 , FromArgs(..)
79 , GToJSON
80 , GToEncoding
81 , ToArgs(..)
82 , Zero
83 , One
84 , genericToJSON
85 , genericLiftToJSON
86 , genericToEncoding
87 , genericLiftToEncoding
88 , genericParseJSON
89 , genericLiftParseJSON
90 -- ** Generic and TH encoding configuration
91 , Options
92 , defaultOptions
93 -- *** Options fields
94 -- $optionsFields
95 , fieldLabelModifier
96 , constructorTagModifier
97 , allNullaryToStringTag
98 , omitNothingFields
99 , sumEncoding
100 , unwrapUnaryRecords
101 , tagSingleConstructors
102 -- *** Options utilities
103 , SumEncoding(..)
104 , camelTo2
105 , defaultTaggedObject
107 -- * Inspecting @'Value's@
108 , withObject
109 , withText
110 , withArray
111 , withNumber
112 , withScientific
113 , withBool
114 -- * Constructors and accessors
115 , Series
116 , pairs
117 , foldable
118 , (.:)
119 , (.:?)
120 , (.:!)
121 , (.!=)
122 , object
123 -- * Parsing
124 , json
125 , json'
126 ) where
128import Prelude ()
129import Prelude.Compat
131import Data.Aeson.Types.FromJSON (ifromJSON)
132import Data.Aeson.Encoding (encodingToLazyByteString)
133import Data.Aeson.Parser.Internal (decodeWith, decodeStrictWith, eitherDecodeWith, eitherDecodeStrictWith, jsonEOF, json, jsonEOF', json')
134import Data.Aeson.Types
135import Data.Aeson.Types.Internal (JSONPath, formatError)
136import qualified Data.ByteString as B
137import qualified Data.ByteString.Lazy as L
139-- | Efficiently serialize a JSON value as a lazy 'L.ByteString'.
140--
141-- This is implemented in terms of the 'ToJSON' class's 'toEncoding' method.
142encode :: (ToJSON a) => a -> L.ByteString
143encode = encodingToLazyByteString . toEncoding
145-- | Efficiently deserialize a JSON value from a lazy 'L.ByteString'.
146-- If this fails due to incomplete or invalid input, 'Nothing' is
147-- returned.
148--
149-- The input must consist solely of a JSON document, with no trailing
150-- data except for whitespace.
151--
152-- This function parses immediately, but defers conversion. See
153-- 'json' for details.
154decode :: (FromJSON a) => L.ByteString -> Maybe a
155decode = decodeWith jsonEOF fromJSON
156{-# INLINE decode #-}
158-- | Efficiently deserialize a JSON value from a strict 'B.ByteString'.
159-- If this fails due to incomplete or invalid input, 'Nothing' is
160-- returned.
161--
162-- The input must consist solely of a JSON document, with no trailing
163-- data except for whitespace.
164--
165-- This function parses immediately, but defers conversion. See
166-- 'json' for details.
167decodeStrict :: (FromJSON a) => B.ByteString -> Maybe a
168decodeStrict = decodeStrictWith jsonEOF fromJSON
169{-# INLINE decodeStrict #-}
171-- | Efficiently deserialize a JSON value from a lazy 'L.ByteString'.
172-- If this fails due to incomplete or invalid input, 'Nothing' is
173-- returned.
174--
175-- The input must consist solely of a JSON document, with no trailing
176-- data except for whitespace.
177--
178-- This function parses and performs conversion immediately. See
179-- 'json'' for details.
180decode' :: (FromJSON a) => L.ByteString -> Maybe a
181decode' = decodeWith jsonEOF' fromJSON
182{-# INLINE decode' #-}
184-- | Efficiently deserialize a JSON value from a strict 'B.ByteString'.
185-- If this fails due to incomplete or invalid input, 'Nothing' is
186-- returned.
187--
188-- The input must consist solely of a JSON document, with no trailing
189-- data except for whitespace.
190--
191-- This function parses and performs conversion immediately. See
192-- 'json'' for details.
193decodeStrict' :: (FromJSON a) => B.ByteString -> Maybe a
194decodeStrict' = decodeStrictWith jsonEOF' fromJSON
195{-# INLINE decodeStrict' #-}
197eitherFormatError :: Either (JSONPath, String) a -> Either String a
198eitherFormatError = either (Left . uncurry formatError) Right
199{-# INLINE eitherFormatError #-}
201-- | Like 'decode' but returns an error message when decoding fails.
202eitherDecode :: (FromJSON a) => L.ByteString -> Either String a
203eitherDecode = eitherFormatError . eitherDecodeWith jsonEOF ifromJSON
204{-# INLINE eitherDecode #-}
206-- | Like 'decodeStrict' but returns an error message when decoding fails.
207eitherDecodeStrict :: (FromJSON a) => B.ByteString -> Either String a
208eitherDecodeStrict =
209 eitherFormatError . eitherDecodeStrictWith jsonEOF ifromJSON
210{-# INLINE eitherDecodeStrict #-}
212-- | Like 'decode'' but returns an error message when decoding fails.
213eitherDecode' :: (FromJSON a) => L.ByteString -> Either String a
214eitherDecode' = eitherFormatError . eitherDecodeWith jsonEOF' ifromJSON
215{-# INLINE eitherDecode' #-}
217-- | Like 'decodeStrict'' but returns an error message when decoding fails.
218eitherDecodeStrict' :: (FromJSON a) => B.ByteString -> Either String a
219eitherDecodeStrict' =
220 eitherFormatError . eitherDecodeStrictWith jsonEOF' ifromJSON
221{-# INLINE eitherDecodeStrict' #-}
223-- $use
224--
225-- This section contains basic information on the different ways to
226-- work with data using this library. These range from simple but
227-- inflexible, to complex but flexible.
228--
229-- The most common way to use the library is to define a data type,
230-- corresponding to some JSON data you want to work with, and then
231-- write either a 'FromJSON' instance, a to 'ToJSON' instance, or both
232-- for that type.
233--
234-- For example, given this JSON data:
235--
236-- > { "name": "Joe", "age": 12 }
237--
238-- we create a matching data type:
239--
240-- > {-# LANGUAGE DeriveGeneric #-}
241-- >
242-- > import GHC.Generics
243-- >
244-- > data Person = Person {
245-- > name :: Text
246-- > , age :: Int
247-- > } deriving (Generic, Show)
248--
249-- The @LANGUAGE@ pragma and 'Generic' instance let us write empty
250-- 'FromJSON' and 'ToJSON' instances for which the compiler will
251-- generate sensible default implementations.
252--
253-- @
254-- instance 'ToJSON' Person where
255-- \-- No need to provide a 'toJSON' implementation.
256--
257-- \-- For efficiency, we write a simple 'toEncoding' implementation, as
258-- \-- the default version uses 'toJSON'.
259-- 'toEncoding' = 'genericToEncoding' 'defaultOptions'
260--
261-- instance 'FromJSON' Person
262-- \-- No need to provide a 'parseJSON' implementation.
263-- @
264--
265-- We can now encode a value like so:
266--
267-- > >>> encode (Person {name = "Joe", age = 12})
268-- > "{\"name\":\"Joe\",\"age\":12}"
270-- $manual
271--
272-- When necessary, we can write 'ToJSON' and 'FromJSON' instances by
273-- hand. This is valuable when the JSON-on-the-wire and Haskell data
274-- are different or otherwise need some more carefully managed
275-- translation. Let's revisit our JSON data:
276--
277-- > { "name": "Joe", "age": 12 }
278--
279-- We once again create a matching data type, without bothering to add
280-- a 'Generic' instance this time:
281--
282-- > data Person = Person {
283-- > name :: Text
284-- > , age :: Int
285-- > } deriving Show
286--
287-- To decode data, we need to define a 'FromJSON' instance:
288--
289-- > {-# LANGUAGE OverloadedStrings #-}
290-- >
291-- > instance FromJSON Person where
292-- > parseJSON = withObject "Person" $ \v -> Person
293-- > <$> v .: "name"
294-- > <*> v .: "age"
295--
296-- We can now parse the JSON data like so:
297--
298-- > >>> decode "{\"name\":\"Joe\",\"age\":12}" :: Maybe Person
299-- > Just (Person {name = "Joe", age = 12})
300--
301-- To encode data, we need to define a 'ToJSON' instance. Let's begin
302-- with an instance written entirely by hand.
303--
304-- @
305-- instance ToJSON Person where
306-- \-- this generates a 'Value'
307-- 'toJSON' (Person name age) =
308-- 'object' [\"name\" '.=' name, \"age\" '.=' age]
309--
310-- \-- this encodes directly to a bytestring Builder
311-- 'toEncoding' (Person name age) =
312-- 'pairs' (\"name\" '.=' 'name' '<>' \"age\" '.=' age)
313-- @
314--
315-- We can now encode a value like so:
316--
317-- > >>> encode (Person {name = "Joe", age = 12})
318-- > "{\"name\":\"Joe\",\"age\":12}"
319--
320-- There are predefined 'FromJSON' and 'ToJSON' instances for many
321-- types. Here's an example using lists and 'Int's:
322--
323-- > >>> decode "[1,2,3]" :: Maybe [Int]
324-- > Just [1,2,3]
325--
326-- And here's an example using the 'Data.Map.Map' type to get a map of
327-- 'Int's.
328--
329-- > >>> decode "{\"foo\":1,\"bar\":2}" :: Maybe (Map String Int)
330-- > Just (fromList [("bar",2),("foo",1)])
332-- While the notes below focus on decoding, you can apply almost the
333-- same techniques to /encoding/ data. (The main difference is that
334-- encoding always succeeds, but decoding has to handle the
335-- possibility of failure, where an input doesn't match our
336-- expectations.)
337--
338-- See the documentation of 'FromJSON' and 'ToJSON' for some examples
339-- of how you can automatically derive instances in many common
340-- circumstances.
342-- $ast
343--
344-- Sometimes you want to work with JSON data directly, without first
345-- converting it to a custom data type. This can be useful if you want
346-- to e.g. convert JSON data to YAML data, without knowing what the
347-- contents of the original JSON data was. The 'Value' type, which is
348-- an instance of 'FromJSON', is used to represent an arbitrary JSON
349-- AST (abstract syntax tree). Example usage:
350--
351-- > >>> decode "{\"foo\": 123}" :: Maybe Value
352-- > Just (Object (fromList [("foo",Number 123)]))
353--
354-- > >>> decode "{\"foo\": [\"abc\",\"def\"]}" :: Maybe Value
355-- > Just (Object (fromList [("foo",Array (fromList [String "abc",String "def"]))]))
356--
357-- Once you have a 'Value' you can write functions to traverse it and
358-- make arbitrary transformations.
360-- $haskell
361--
362-- We can decode to any instance of 'FromJSON':
363--
364-- > λ> decode "[1,2,3]" :: Maybe [Int]
365-- > Just [1,2,3]
366--
367-- Alternatively, there are instances for standard data types, so you
368-- can use them directly. For example, use the 'Data.Map.Map' type to
369-- get a map of 'Int's.
370--
371-- > λ> import Data.Map
372-- > λ> decode "{\"foo\":1,\"bar\":2}" :: Maybe (Map String Int)
373-- > Just (fromList [("bar",2),("foo",1)])
375-- $mixed
376--
377-- The above approach with maps of course will not work for mixed-type
378-- objects that don't follow a strict schema, but there are a couple
379-- of approaches available for these.
380--
381-- The 'Object' type contains JSON objects:
382--
383-- > λ> decode "{\"name\":\"Dave\",\"age\":2}" :: Maybe Object
384-- > Just (fromList) [("name",String "Dave"),("age",Number 2)]
385--
386-- You can extract values from it with a parser using 'parse',
387-- 'parseEither' or, in this example, 'parseMaybe':
388--
389-- > λ> do result <- decode "{\"name\":\"Dave\",\"age\":2}"
390-- > flip parseMaybe result $ \obj -> do
391-- > age <- obj .: "age"
392-- > name <- obj .: "name"
393-- > return (name ++ ": " ++ show (age*2))
394-- >
395-- > Just "Dave: 4"
396--
397-- Considering that any type that implements 'FromJSON' can be used
398-- here, this is quite a powerful way to parse JSON. See the
399-- documentation in 'FromJSON' for how to implement this class for
400-- your own data types.
401--
402-- The downside is that you have to write the parser yourself; the
403-- upside is that you have complete control over the way the JSON is
404-- parsed.
406-- $encoding_and_decoding
407--
408-- Decoding is a two-step process.
409--
410-- * When decoding a value, the process is reversed: the bytes are
411-- converted to a 'Value', then the 'FromJSON' class is used to
412-- convert to the desired type.
413--
414-- There are two ways to encode a value.
415--
416-- * Convert to a 'Value' using 'toJSON', then possibly further
417-- encode. This was the only method available in aeson 0.9 and
418-- earlier.
419--
420-- * Directly encode (to what will become a 'L.ByteString') using
421-- 'toEncoding'. This is much more efficient (about 3x faster, and
422-- less memory intensive besides), but is only available in aeson
423-- 0.10 and newer.
424--
425-- For convenience, the 'encode' and 'decode' functions combine both
426-- steps.
428-- $encoding
429--
430-- In older versions of this library, encoding a Haskell value
431-- involved converting to an intermediate 'Value', then encoding that.
432--
433-- A \"direct\" encoder converts straight from a source Haskell value
434-- to a 'BL.ByteString' without constructing an intermediate 'Value'.
435-- This approach is faster than 'toJSON', and allocates less memory.
436-- The 'toEncoding' method makes it possible to implement direct
437-- encoding with low memory overhead.
438--
439-- To complicate matters, the default implementation of 'toEncoding'
440-- uses 'toJSON'. Why? The 'toEncoding' method was added to this
441-- library much more recently than 'toJSON'. Using 'toJSON' ensures
442-- that packages written against older versions of this library will
443-- compile and produce correct output, but they will not see any
444-- speedup from direct encoding.
445--
446-- To write a minimal implementation of direct encoding, your type
447-- must implement GHC's 'Generic' class, and your code should look
448-- like this:
449--
450-- @
451-- 'toEncoding' = 'genericToEncoding' 'defaultOptions'
452-- @
453--
454-- What if you have more elaborate encoding needs? For example,
455-- perhaps you need to change the names of object keys, omit parts of
456-- a value.
457--
458-- To encode to a JSON \"object\", use the 'pairs' function.
459--
460-- @
461-- 'toEncoding' (Person name age) =
462-- 'pairs' (\"name\" '.=' 'name' '<>' \"age\" '.=' age)
463-- @
464--
465-- Any container type that implements 'Foldable' can be encoded to a
466-- JSON \"array\" using 'foldable'.
467--
468-- > > import Data.Sequence as Seq
469-- > > encode (Seq.fromList [1,2,3])
470-- > "[1,2,3]"