5-- Copyright: (c) 2011, 2012 Bryan O'Sullivan
6-- (c) 2011 MailRank, Inc.
8-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>
9-- Stability: experimental
10-- Portability: portable
12-- Types and functions for working efficiently with JSON data.
14-- (A note on naming: in Greek mythology, Aeson was the father of Jason.)
18 -- * How to use this library
21 -- ** Working with the AST
24 -- ** Decoding to a Haskell value
27 -- ** Decoding a mixed-type object
30 -- ** Automatically decoding data types
36 -- * Encoding and decoding
37 -- $encoding_and_decoding
43 -- ** Variants for strict bytestrings
52 -- * Convenience types
60 -- ** Generic JSON classes
66 -- * Inspecting @'Value's@
73 -- * Constructors and accessors
84import Data.Aeson.Encode (encode)
85import Data.Aeson.Parser.Internal (decodeWith, decodeStrictWith,
86 eitherDecodeWith, eitherDecodeStrictWith,
87 jsonEOF, json, jsonEOF', json')
88import Data.Aeson.Types
89import qualified Data.ByteString as B
90import qualified Data.ByteString.Lazy as L
92-- | Efficiently deserialize a JSON value from a lazy 'L.ByteString'.
93-- If this fails due to incomplete or invalid input, 'Nothing' is
96-- The input must consist solely of a JSON document, with no trailing
97-- data except for whitespace.
99-- This function parses immediately, but defers conversion. See
100-- 'json' for details.
101decode :: (FromJSON a) => L.ByteString -> Maybe a
102decode = decodeWith jsonEOF fromJSON
105-- | Efficiently deserialize a JSON value from a strict 'B.ByteString'.
106-- If this fails due to incomplete or invalid input, 'Nothing' is
109-- The input must consist solely of a JSON document, with no trailing
110-- data except for whitespace.
112-- This function parses immediately, but defers conversion. See
113-- 'json' for details.
114decodeStrict :: (FromJSON a) => B.ByteString -> Maybe a
115decodeStrict = decodeStrictWith jsonEOF fromJSON
116{-# INLINE decodeStrict #-}
118-- | Efficiently deserialize a JSON value from a lazy 'L.ByteString'.
119-- If this fails due to incomplete or invalid input, 'Nothing' is
122-- The input must consist solely of a JSON document, with no trailing
123-- data except for whitespace. This restriction is necessary to ensure
124-- that if data is being lazily read from a file handle, the file
125-- handle will be closed in a timely fashion once the document has
128-- This function parses and performs conversion immediately. See
129-- 'json'' for details.
130decode' :: (FromJSON a) => L.ByteString -> Maybe a
131decode' = decodeWith jsonEOF' fromJSON
132{-# INLINE decode' #-}
134-- | Efficiently deserialize a JSON value from a lazy 'L.ByteString'.
135-- If this fails due to incomplete or invalid input, 'Nothing' is
138-- The input must consist solely of a JSON document, with no trailing
139-- data except for whitespace.
141-- This function parses and performs conversion immediately. See
142-- 'json'' for details.
143decodeStrict' :: (FromJSON a) => B.ByteString -> Maybe a
144decodeStrict' = decodeStrictWith jsonEOF' fromJSON
145{-# INLINE decodeStrict' #-}
147-- | Like 'decode' but returns an error message when decoding fails.
148eitherDecode :: (FromJSON a) => L.ByteString -> Either String a
149eitherDecode = eitherDecodeWith jsonEOF fromJSON
150{-# INLINE eitherDecode #-}
152-- | Like 'decodeStrict' but returns an error message when decoding fails.
153eitherDecodeStrict :: (FromJSON a) => B.ByteString -> Either String a
154eitherDecodeStrict = eitherDecodeStrictWith jsonEOF fromJSON
155{-# INLINE eitherDecodeStrict #-}
157-- | Like 'decode'' but returns an error message when decoding fails.
158eitherDecode' :: (FromJSON a) => L.ByteString -> Either String a
159eitherDecode' = eitherDecodeWith jsonEOF' fromJSON
160{-# INLINE eitherDecode' #-}
162-- | Like 'decodeStrict'' but returns an error message when decoding fails.
163eitherDecodeStrict' :: (FromJSON a) => B.ByteString -> Either String a
164eitherDecodeStrict' = eitherDecodeStrictWith jsonEOF' fromJSON
165{-# INLINE eitherDecodeStrict' #-}
169-- This section contains basic information on the different ways to
170-- decode data using this library. These range from simple but
171-- inflexible, to complex but flexible.
173-- The most common way to use the library is to define a data type,
174-- corresponding to some JSON data you want to work with, and then
175-- write either a 'FromJSON' instance, a to 'ToJSON' instance, or both
176-- for that type. For example, given this JSON data:
178-- > { "name": "Joe", "age": 12 }
180-- we create a matching data type:
182-- > data Person = Person
187-- To decode data, we need to define a 'FromJSON' instance:
189-- > {-# LANGUAGE OverloadedStrings #-}
191-- > instance FromJSON Person where
192-- > parseJSON (Object v) = Person <$>
195-- > -- A non-Object value is of the wrong type, so fail.
196-- > parseJSON _ = mzero
198-- We can now parse the JSON data like so:
200-- > >>> decode "{\"name\":\"Joe\",\"age\":12}" :: Maybe Person
201-- > Just (Person {name = "Joe", age = 12})
203-- To encode data, we need to define a 'ToJSON' instance:
205-- > instance ToJSON Person where
206-- > toJSON (Person name age) = object ["name" .= name, "age" .= age]
208-- We can now encode a value like so:
210-- > >>> encode (Person {name = "Joe", age = 12})
211-- > "{\"name\":\"Joe\",\"age\":12}"
213-- There are predefined 'FromJSON' and 'ToJSON' instances for many
214-- types. Here's an example using lists and 'Int's:
216-- > >>> decode "[1,2,3]" :: Maybe [Int]
219-- And here's an example using the 'Data.Map.Map' type to get a map of
222-- > >>> decode "{\"foo\":1,\"bar\":2}" :: Maybe (Map String Int)
223-- > Just (fromList [("bar",2),("foo",1)])
225-- While the notes below focus on decoding, you can apply almost the
226-- same techniques to /encoding/ data. (The main difference is that
227-- encoding always succeeds, but decoding has to handle the
228-- possibility of failure, where an input doesn't match our
231-- See the documentation of 'FromJSON' and 'ToJSON' for some examples
232-- of how you can automatically derive instances in some
237-- Sometimes you want to work with JSON data directly, without first
238-- converting it to a custom data type. This can be useful if you want
239-- to e.g. convert JSON data to YAML data, without knowing what the
240-- contents of the original JSON data was. The 'Value' type, which is
241-- an instance of 'FromJSON', is used to represent an arbitrary JSON
242-- AST (abstract syntax tree). Example usage:
244-- > >>> decode "{\"foo\": 123}" :: Maybe Value
245-- > Just (Object (fromList [("foo",Number 123)]))
247-- > >>> decode "{\"foo\": [\"abc\",\"def\"]}" :: Maybe Value
248-- > Just (Object (fromList [("foo",Array (fromList [String "abc",String "def"]))]))
250-- Once you have a 'Value' you can write functions to traverse it and
251-- make arbitrary transformations.
255-- Any instance of 'FromJSON' can be specified (but see the
256-- \"Pitfalls\" section here—"Data.Aeson#pitfalls"):
258-- > λ> decode "[1,2,3]" :: Maybe [Int]
261-- Alternatively, there are instances for standard data types, so you
262-- can use them directly. For example, use the 'Data.Map.Map' type to
263-- get a map of 'Int's.
266-- > λ> decode "{\"foo\":1,\"bar\":2}" :: Maybe (Map String Int)
267-- > Just (fromList [("bar",2),("foo",1)])
271-- The above approach with maps of course will not work for mixed-type
272-- objects that don't follow a strict schema, but there are a couple
273-- of approaches available for these.
275-- The 'Object' type contains JSON objects:
277-- > λ> decode "{\"name\":\"Dave\",\"age\":2}" :: Maybe Object
278-- > Just (fromList) [("name",String "Dave"),("age",Number 2)]
280-- You can extract values from it with a parser using 'parse',
281-- 'parseEither' or, in this example, 'parseMaybe':
283-- > λ> do result <- decode "{\"name\":\"Dave\",\"age\":2}"
284-- > flip parseMaybe result $ \obj -> do
285-- > age <- obj .: "age"
286-- > name <- obj .: "name"
287-- > return (name ++ ": " ++ show (age*2))
291-- Considering that any type that implements 'FromJSON' can be used
292-- here, this is quite a powerful way to parse JSON. See the
293-- documentation in 'FromJSON' for how to implement this class for
294-- your own data types.
296-- The downside is that you have to write the parser yourself; the
297-- upside is that you have complete control over the way the JSON is
302-- If you don't want fine control and would prefer the JSON be parsed
303-- to your own data types automatically according to some reasonably
304-- sensible isomorphic implementation, you can use the generic parser
305-- based on 'Data.Typeable.Typeable' and 'Data.Data.Data'. Switch to
306-- the 'Data.Aeson.Generic' module, and you can do the following:
308-- > λ> decode "[1]" :: Maybe [Int]
310-- > λ> :m + Data.Typeable Data.Data
311-- > λ> :set -XDeriveDataTypeable
312-- > λ> data Person = Person { personName :: String, personAge :: Int } deriving (Data,Typeable,Show)
313-- > λ> encode Person { personName = "Chris", personAge = 123 }
314-- > "{\"personAge\":123,\"personName\":\"Chris\"}"
315-- > λ> decode "{\"personAge\":123,\"personName\":\"Chris\"}" :: Maybe Person
317-- > personName = "Chris", personAge = 123
320-- Be aware that the encoding may not always be what you'd naively
323-- > λ> data Foo = Foo Int Int deriving (Data,Typeable,Show)
324-- > λ> encode (Foo 1 2)
327-- With this approach, it's best to treat the
328-- 'Data.Aeson.Generic.decode' and 'Data.Aeson.Generic.encode'
329-- functions as an isomorphism, and not to rely upon (or care about)
330-- the specific intermediate representation.
335-- Note that the JSON standard requires that the top-level value be
336-- either an array or an object. If you try to use 'decode' with a
337-- result type that is /not/ represented in JSON as an array or
338-- object, your code will typecheck, but it will always \"fail\" at
341-- > >>> decode "1" :: Maybe Int
343-- > >>> decode "1" :: Maybe String
346-- So stick to objects (e.g. maps in Haskell) or arrays (lists or
347-- vectors in Haskell):
349-- > >>> decode "[1,2,3]" :: Maybe [Int]
352-- When encoding to JSON you can encode anything that's an instance of
353-- 'ToJSON', and this may include simple types. So beware that this
354-- aspect of the API is not isomorphic. You can round-trip arrays and
355-- maps, but not simple values:
357-- > >>> encode [1,2,3]
359-- > >>> decode (encode [1]) :: Maybe [Int]
363-- > >>> decode (encode (1 :: Int)) :: Maybe Int
366-- Alternatively, see 'Data.Aeson.Parser.value' to parse non-top-level
369-- $encoding_and_decoding
371-- Encoding and decoding are each two-step processes.
373-- * To encode a value, it is first converted to an abstract syntax
374-- tree (AST), using 'ToJSON'. This generic representation is then
377-- * When decoding a value, the process is reversed: the bytes are
378-- converted to an AST, then the 'FromJSON' class is used to convert
379-- to the desired type.
381-- For convenience, the 'encode' and 'decode' functions combine both
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list