aeson-0.11.1.4: Fast JSON parsing and encoding

Copyright(c) 2011-2016 Bryan O'Sullivan (c) 2011 MailRank, Inc.
LicenseBSD3
MaintainerBryan O'Sullivan <bos@serpentine.com>
Stabilityexperimental
Portabilityportable
Safe HaskellNone
LanguageHaskell2010

Data.Aeson.Types

Contents

Description

Types for working with JSON data.

Synopsis

Core JSON types

fromEncoding :: Encoding -> Builder Source

Acquire the underlying bytestring builder.

data Series Source

A series of values that, when encoded, should be separated by commas.

type Array = Vector Value Source

A JSON "array" (sequence).

emptyArray :: Value Source

The empty array.

type Pair = (Text, Value) Source

A key/value pair for an Object.

type Object = HashMap Text Value Source

A JSON "object" (key/value map).

emptyObject :: Value Source

The empty object.

Convenience types and functions

newtype DotNetTime Source

A newtype wrapper for UTCTime that uses the same non-standard serialization format as Microsoft .NET, whose System.DateTime type is by default serialized to JSON as in the following example:

/Date(1302547608878)/

The number represents milliseconds since the Unix epoch.

Constructors

DotNetTime 

Fields

fromDotNetTime :: UTCTime

Acquire the underlying value.

typeMismatch Source

Arguments

:: String

The name of the type you are trying to parse.

-> Value

The actual value encountered.

-> Parser a 

Fail parsing due to a type mismatch, with a descriptive message.

Example usage:

instance FromJSON Coord where
  parseJSON (Object v) = {- type matches, life is good -}
  parseJSON wat        = typeMismatch "Coord" wat

Type conversion

class FromJSON a where Source

A type that can be converted from JSON, with the possibility of failure.

In many cases, you can get the compiler to generate parsing code for you (see below). To begin, let's cover writing an instance by hand.

There are various reasons a conversion could fail. For example, an Object could be missing a required key, an Array could be of the wrong size, or a value could be of an incompatible type.

The basic ways to signal a failed conversion are as follows:

  • empty and mzero work, but are terse and uninformative
  • fail yields a custom error message
  • typeMismatch produces an informative message for cases when the value encountered is not of the expected type

An example type and instance:

-- Allow ourselves to write Text literals.
{-# LANGUAGE OverloadedStrings #-}

data Coord = Coord { x :: Double, y :: Double }

instance FromJSON Coord where
  parseJSON (Object v) = Coord    <$>
                         v .: "x" <*>
                         v .: "y"

  -- We do not expect a non-Object value here.
  -- We could use mzero to fail, but typeMismatch
  -- gives a much more informative error message.
  parseJSON invalid    = typeMismatch "Coord" invalid

Instead of manually writing your FromJSON instance, there are two options to do it automatically:

  • Data.Aeson.TH provides Template Haskell functions which will derive an instance at compile time. The generated instance is optimized for your type so will probably be more efficient than the following two options:
  • The compiler can provide a default generic implementation for parseJSON.

To use the second, simply add a deriving Generic clause to your datatype and declare a FromJSON instance for your datatype without giving a definition for parseJSON.

For example, the previous example can be simplified to just:

{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics

data Coord = Coord { x :: Double, y :: Double } deriving Generic

instance FromJSON Coord

If DefaultSignatures doesn't give exactly the results you want, you can customize the generic decoding with only a tiny amount of effort, using genericParseJSON with your preferred Options:

instance FromJSON Coord where
    parseJSON = genericParseJSON defaultOptions

Minimal complete definition

Nothing

Methods

parseJSON :: Value -> Parser a Source

fromJSON :: FromJSON a => Value -> Result a Source

Convert a value from JSON, failing if the types do not match.

parse :: (a -> Parser b) -> a -> Result b Source

Run a Parser.

parseEither :: (a -> Parser b) -> a -> Either String b Source

Run a Parser with an Either result type. If the parse fails, the Left payload will contain an error message.

parseMaybe :: (a -> Parser b) -> a -> Maybe b Source

Run a Parser with a Maybe result type.

class ToJSON a where Source

A type that can be converted to JSON.

An example type and instance:

-- Allow ourselves to write Text literals.
{-# LANGUAGE OverloadedStrings #-}

data Coord = Coord { x :: Double, y :: Double }

instance ToJSON Coord where
  toJSON (Coord x y) = object ["x" .= x, "y" .= y]

  toEncoding (Coord x y) = pairs ("x" .= x <> "y" .= y)

Instead of manually writing your ToJSON instance, there are two options to do it automatically:

  • Data.Aeson.TH provides Template Haskell functions which will derive an instance at compile time. The generated instance is optimized for your type so will probably be more efficient than the following two options:
  • The compiler can provide a default generic implementation for toJSON.

To use the second, simply add a deriving Generic clause to your datatype and declare a ToJSON instance for your datatype without giving definitions for toJSON or toEncoding.

For example, the previous example can be simplified to a more minimal instance:

{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics

data Coord = Coord { x :: Double, y :: Double } deriving Generic

instance ToJSON Coord where
    toEncoding = genericToEncoding defaultOptions

Why do we provide an implementation for toEncoding here? The toEncoding function is a relatively new addition to this class. To allow users of older versions of this library to upgrade without having to edit all of their instances or encounter surprising incompatibilities, the default implementation of toEncoding uses toJSON. This produces correct results, but since it performs an intermediate conversion to a Value, it will be less efficient than directly emitting an Encoding. Our one-liner definition of toEncoding above bypasses the intermediate Value.

If DefaultSignatures doesn't give exactly the results you want, you can customize the generic encoding with only a tiny amount of effort, using genericToJSON and genericToEncoding with your preferred Options:

instance ToJSON Coord where
    toJSON     = genericToJSON defaultOptions
    toEncoding = genericToEncoding defaultOptions

Minimal complete definition

Nothing

Methods

toJSON :: a -> Value Source

Convert a Haskell value to a JSON-friendly intermediate type.

toEncoding :: a -> Encoding Source

Encode a Haskell value as JSON.

The default implementation of this method creates an intermediate Value using toJSON. This provides source-level compatibility for people upgrading from older versions of this library, but obviously offers no performance advantage.

To benefit from direct encoding, you must provide an implementation for this method. The easiest way to do so is by having your types implement Generic using the DeriveGeneric extension, and then have GHC generate a method body as follows.

instance ToJSON Coord where
    toEncoding = genericToEncoding defaultOptions

class KeyValue kv where Source

A key-value pair for encoding a JSON object.

Methods

(.=) :: ToJSON v => Text -> v -> kv infixr 8 Source

modifyFailure :: (String -> String) -> Parser a -> Parser a Source

If the inner Parser failed, modify the failure message using the provided function. This allows you to create more descriptive error messages. For example:

parseJSON (Object o) = modifyFailure
    ("Parsing of the Foo value failed: " ++)
    (Foo <$> o .: "someField")

Since 0.6.2.0

Generic JSON classes

class GFromJSON f where Source

Class of generic representation types (Rep) that can be converted from JSON.

Methods

gParseJSON :: Options -> Value -> Parser (f a) Source

This method (applied to defaultOptions) is used as the default generic implementation of parseJSON.

class GToJSON f where Source

Class of generic representation types (Rep) that can be converted to JSON.

Methods

gToJSON :: Options -> f a -> Value Source

This method (applied to defaultOptions) is used as the default generic implementation of toJSON.

class GToEncoding f where Source

Class of generic representation types (Rep) that can be converted to a JSON Encoding.

Methods

gToEncoding :: Options -> f a -> Encoding Source

This method (applied to defaultOptions) can be used as the default generic implementation of toEncoding.

genericToJSON :: (Generic a, GToJSON (Rep a)) => Options -> a -> Value Source

A configurable generic JSON creator. This function applied to defaultOptions is used as the default for toJSON when the type is an instance of Generic.

genericToEncoding :: (Generic a, GToEncoding (Rep a)) => Options -> a -> Encoding Source

A configurable generic JSON encoder. This function applied to defaultOptions is used as the default for toEncoding when the type is an instance of Generic.

genericParseJSON :: (Generic a, GFromJSON (Rep a)) => Options -> Value -> Parser a Source

A configurable generic JSON decoder. This function applied to defaultOptions is used as the default for parseJSON when the type is an instance of Generic.

Inspecting Values

withObject :: String -> (Object -> Parser a) -> Value -> Parser a Source

withObject expected f value applies f to the Object when value is an Object and fails using typeMismatch expected otherwise.

withText :: String -> (Text -> Parser a) -> Value -> Parser a Source

withText expected f value applies f to the Text when value is a String and fails using typeMismatch expected otherwise.

withArray :: String -> (Array -> Parser a) -> Value -> Parser a Source

withArray expected f value applies f to the Array when value is an Array and fails using typeMismatch expected otherwise.

withNumber :: String -> (Number -> Parser a) -> Value -> Parser a Source

Deprecated: Use withScientific instead

withNumber expected f value applies f to the Number when value is a Number. and fails using typeMismatch expected otherwise.

withScientific :: String -> (Scientific -> Parser a) -> Value -> Parser a Source

withScientific expected f value applies f to the Scientific number when value is a Number. and fails using typeMismatch expected otherwise.

withBool :: String -> (Bool -> Parser a) -> Value -> Parser a Source

withBool expected f value applies f to the Bool when value is a Bool and fails using typeMismatch expected otherwise.

pairs :: Series -> Encoding Source

Encode a series of key/value pairs, separated by commas.

foldable :: (Foldable t, ToJSON a) => t a -> Encoding Source

Encode a Foldable as a JSON array.

(.:) :: FromJSON a => Object -> Text -> Parser a Source

Retrieve the value associated with the given key of an Object. The result is empty if the key is not present or the value cannot be converted to the desired type.

This accessor is appropriate if the key and value must be present in an object for it to be valid. If the key and value are optional, use .:? instead.

(.:?) :: FromJSON a => Object -> Text -> Parser (Maybe a) Source

Retrieve the value associated with the given key of an Object. The result is Nothing if the key is not present, or empty if the value cannot be converted to the desired type.

This accessor is most useful if the key and value can be absent from an object without affecting its validity. If the key and value are mandatory, use .: instead.

(.:!) :: FromJSON a => Object -> Text -> Parser (Maybe a) Source

Like .:?, but the resulting parser will fail, if the key is present but is Null.

(.!=) :: Parser (Maybe a) -> a -> Parser a Source

Helper for use in combination with .:? to provide default values for optional JSON object fields.

This combinator is most useful if the key and value can be absent from an object without affecting its validity and we know a default value to assign in that case. If the key and value are mandatory, use .: instead.

Example usage:

 v1 <- o .:? "opt_field_with_dfl" .!= "default_val"
 v2 <- o .:  "mandatory_field"
 v3 <- o .:? "opt_field2"

object :: [Pair] -> Value Source

Create a Value from a list of name/value Pairs. If duplicate keys arise, earlier keys and their associated values win.

Generic and TH encoding configuration

data Options Source

Options that specify how to encode/decode your datatype to/from JSON.

Constructors

Options 

Fields

fieldLabelModifier :: String -> String

Function applied to field labels. Handy for removing common record prefixes for example.

constructorTagModifier :: String -> String

Function applied to constructor tags which could be handy for lower-casing them for example.

allNullaryToStringTag :: Bool

If True the constructors of a datatype, with all nullary constructors, will be encoded to just a string with the constructor tag. If False the encoding will always follow the sumEncoding.

omitNothingFields :: Bool

If True record fields with a Nothing value will be omitted from the resulting object. If False the resulting object will include those fields mapping to null.

sumEncoding :: SumEncoding

Specifies how to encode constructors of a sum datatype.

unwrapUnaryRecords :: Bool

Hide the field name when a record constructor has only one field, like a newtype.

Instances

data SumEncoding Source

Specifies how to encode constructors of a sum datatype.

Constructors

TaggedObject

A constructor will be encoded to an object with a field tagFieldName which specifies the constructor tag (modified by the constructorTagModifier). If the constructor is a record the encoded record fields will be unpacked into this object. So make sure that your record doesn't have a field with the same label as the tagFieldName. Otherwise the tag gets overwritten by the encoded value of that field! If the constructor is not a record the encoded constructor contents will be stored under the contentsFieldName field.

ObjectWithSingleField

A constructor will be encoded to an object with a single field named after the constructor tag (modified by the constructorTagModifier) which maps to the encoded contents of the constructor.

TwoElemArray

A constructor will be encoded to a 2-element array where the first element is the tag of the constructor (modified by the constructorTagModifier) and the second element the encoded contents of the constructor.

camelTo :: Char -> String -> String Source

Deprecated: Use camelTo2 for better results

Converts from CamelCase to another lower case, interspersing the character between all capital letters and their previous entries, except those capital letters that appear together, like API.

For use by Aeson template haskell calls.

camelTo '_' 'CamelCaseAPI' == "camel_case_api"

camelTo2 :: Char -> String -> String Source

Better version of camelTo. Example where it works better:

camelTo '_' 'CamelAPICase' == "camel_apicase"
camelTo2 '_' 'CamelAPICase' == "camel_api_case"

defaultTaggedObject :: SumEncoding Source

Default TaggedObject SumEncoding options:

defaultTaggedObject = TaggedObject
                      { tagFieldName      = "tag"
                      , contentsFieldName = "contents"
                      }