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