Data.Aeson.Types

aeson-0.9.0.1: Fast JSON parsing and encoding

Copyright | (c) 2011, 2012 Bryan O'Sullivan (c) 2011 MailRank, Inc.
License | Apache
Maintainer | Bryan O'Sullivan <bos@serpentine.com>
Stability | experimental
Portability | portable
Safe Haskell | None
Language | Haskell98

Data.Aeson.Types

Contents

- Core JSON types
- Convenience types and functions
- Type conversion
  - Generic JSON classes
- Inspecting ``Value`s`
- Constructors and accessors
- Generic and TH encoding configuration

Description

Types for working with JSON data.

Synopsis

- data Value
  - = Object !Object
  - | Array !Array
  - | String !Text
  - | Number !Scientific
  - | Bool !Bool
  - | Null
- type Array = Vector Value
- emptyArray :: Value
- type Pair = (Text, Value)
- type Object = HashMap Text Value
- emptyObject :: Value
- newtype DotNetTime = DotNetTime {
  - fromDotNetTime :: UTCTime
  }
- typeMismatch :: String -> Value -> Parser a
- data Parser a
- data Result a
  - = Error String
  - | Success a
- class FromJSON a where
  - parseJSON :: Value -> Parser a
- fromJSON :: FromJSON a => Value -> Result a
- parse :: (a -> Parser b) -> a -> Result b
- parseEither :: (a -> Parser b) -> a -> Either String b
- parseMaybe :: (a -> Parser b) -> a -> Maybe b
- class ToJSON a where
  - toJSON :: a -> Value
- modifyFailure :: (String -> String) -> Parser a -> Parser a
- class GFromJSON f where
  - gParseJSON :: Options -> Value -> Parser (f a)
- class GToJSON f where
  - gToJSON :: Options -> f a -> Value
- genericToJSON :: (Generic a, GToJSON (Rep a)) => Options -> a -> Value
- genericParseJSON :: (Generic a, GFromJSON (Rep a)) => Options -> Value -> Parser a
- withObject :: String -> (Object -> Parser a) -> Value -> Parser a
- withText :: String -> (Text -> Parser a) -> Value -> Parser a
- withArray :: String -> (Array -> Parser a) -> Value -> Parser a
- withNumber :: String -> (Number -> Parser a) -> Value -> Parser a
- withScientific :: String -> (Scientific -> Parser a) -> Value -> Parser a
- withBool :: String -> (Bool -> Parser a) -> Value -> Parser a
- (.=) :: ToJSON a => Text -> a -> Pair
- (.:) :: FromJSON a => Object -> Text -> Parser a
- (.:?) :: FromJSON a => Object -> Text -> Parser (Maybe a)
- (.!=) :: Parser (Maybe a) -> a -> Parser a
- object :: [Pair] -> Value
- data Options = Options {
  - fieldLabelModifier :: String -> String
  - constructorTagModifier :: String -> String
  - allNullaryToStringTag :: Bool
  - omitNothingFields :: Bool
  - sumEncoding :: SumEncoding
  }
- data SumEncoding
  - = TaggedObject {
    - tagFieldName :: String
    - contentsFieldName :: String
    }
  - | ObjectWithSingleField
  - | TwoElemArray
- camelTo :: Char -> String -> String
- defaultOptions :: Options
- defaultTaggedObject :: SumEncoding

# Core JSON types

data Value

A JSON value represented as a Haskell value.

Constructors

Object !Object |
Array !Array |
String !Text |
Number !Scientific |
Bool !Bool |
Null |

Instances

Eq Value |
Data Value |
Read Value |
Show Value |
IsString Value |
NFData Value |
Hashable Value |

type Array = Vector Value

A JSON "array" (sequence).

emptyArray :: Value

The empty array.

type Pair = (Text, Value)

A key/value pair for an `Object`.

type Object = HashMap Text Value

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

emptyObject :: Value

The empty object.

# Convenience types and functions

newtype DotNetTime

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

Instances

Eq DotNetTime |
Ord DotNetTime |
Read DotNetTime |
Show DotNetTime |
FormatTime DotNetTime |

typeMismatch

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.

# Type conversion

data Parser a

A continuation-based parser type.

Instances

Monad Parser |
Functor Parser |
Applicative Parser |
Alternative Parser |
MonadPlus Parser |
Monoid (Parser a) |

data Result a

The result of running a `Parser`.

Constructors

Error String |
Success a |

Instances

Monad Result |
Functor Result |
Applicative Result |
Alternative Result |
MonadPlus Result |
Eq a => Eq (Result a) |
Show a => Show (Result a) |
Monoid (Result a) |
NFData a => NFData (Result a) |

class FromJSON a where

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

When writing an instance, use `empty`, `mzero`, or `fail` to make a conversion fail, e.g. if an `Object` is missing a required key, or the value is of the wrong type.

An example type and instance:

    {-# LANGUAGE OverloadedStrings #-}

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

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

      -- A non-Object value is of the wrong type, so use mzero to fail.
      parseJSON _          = mzero

Note the use of the `OverloadedStrings` language extension which enables `Text` values to be written as string literals.

Instead of manually writing your `FromJSON` instance, there are three 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:
- Data.Aeson.Generic provides a generic `fromJSON` function that parses to any type which is an instance of `Data`.
- If your compiler has support for the `DeriveGeneric` and `DefaultSignatures` language extensions, `parseJSON` will have a default generic implementation.

To use this, 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

Note that, instead of using `DefaultSignatures`, it's also possible to parameterize the generic decoding using `genericParseJSON` applied to your encoding/decoding `Options`:

    instance FromJSON Coord where
        parseJSON = genericParseJSON defaultOptions

Minimal complete definition

Nothing

Methods

parseJSON :: Value -> Parser a

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

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

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

Run a `Parser`.

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

Run a `Parser` with an `Either` result type.

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

Run a `Parser` with a `Maybe` result type.

class ToJSON a where

A type that can be converted to JSON.

An example type and instance:

@{-# LANGUAGE OverloadedStrings #-}

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

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

Note the use of the `OverloadedStrings` language extension which enables `Text` values to be written as string literals.

Instead of manually writing your `ToJSON` instance, there are three 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:
- Data.Aeson.Generic provides a generic `toJSON` function that accepts any type which is an instance of `Data`.
- If your compiler has support for the `DeriveGeneric` and `DefaultSignatures` language extensions (GHC 7.2 and newer), `toJSON` will have a default generic implementation.

To use the latter option, simply add a `deriving `Generic`` clause to your datatype and declare a `ToJSON` instance for your datatype without giving a definition for `toJSON`.

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 ToJSON Coord @

Note that, instead of using `DefaultSignatures`, it's also possible to parameterize the generic encoding using `genericToJSON` applied to your encoding/decoding `Options`:

    instance ToJSON Coord where
        toJSON = genericToJSON defaultOptions

Minimal complete definition

Nothing

Methods

toJSON :: a -> Value

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

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

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

Methods

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

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

class GToJSON f where

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

Methods

gToJSON :: Options -> f a -> Value

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

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

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

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

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 ``Value`s`

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

`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

`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

`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

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

`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

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

# Constructors and accessors

(.=) :: ToJSON a => Text -> a -> Pair

Construct a `Pair` from a key and a value.

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

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)

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.

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

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

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

# Generic and TH encoding configuration

data Options

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.

data SumEncoding

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.
Fields tagFieldName :: String contentsFieldName :: String
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

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"

defaultOptions :: Options

Default encoding `Options`:

    Options
    { fieldLabelModifier      = id
    , constructorTagModifier  = id
    , allNullaryToStringTag   = True
    , omitNothingFields       = False
    , sumEncoding             = defaultTaggedObject
    }

defaultTaggedObject :: SumEncoding

Default `TaggedObject` `SumEncoding` options:

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