Portability | portable |
---|---|
Stability | experimental |
Functions to mechanically derive ToJSON
and FromJSON
instances. Note that
you need to enable the TemplateHaskell
language extension in order to use this
module.
An example shows how instances are generated for arbitrary data types. First we define a data type:
data D a = Nullary | Unary Int | Product String Char a | Record { testOne :: Double , testTwo :: Bool , testThree :: D a } deriving Eq
Next we derive the necessary instances. Note that we make use of the feature to change record field names. In this case we drop the first 4 characters of every field name.
$(deriveJSON
(drop
4) ''D)
This will result in the following (simplified) code to be spliced in your program:
import Control.Applicative import Control.Monad import Data.Aeson import Data.Aeson.TH import qualified Data.Map as M import qualified Data.Text as T import qualified Data.Vector as V instanceToJSON
a =>ToJSON
(D a) wheretoJSON
= value -> case value of Nullary ->object
[pack
"Nullary" .=toJSON
([] :: [()])] Unary arg1 ->object
[pack
"Unary" .=toJSON
arg1] Product arg1 arg2 arg3 ->object
[pack
"Product" .=toJSON
[toJSON
arg1 ,toJSON
arg2 ,toJSON
arg3 ] ] Record arg1 arg2 arg3 ->object
[pack
"Record" .=object
[pack
"One".=
arg1 ,pack
"Two".=
arg2 ,pack
"Three".=
arg3 ] ]
instanceFromJSON
a =>FromJSON
(D a) whereparseJSON
= value -> case value ofObject
obj -> casetoList
obj of [(conKey, conVal)] -> case conKey of _ | (conKey==
pack
"Nullary") -> case conVal ofArray
arr |null
arr ->pure
Nullary _ ->mzero
| (conKey==
pack
"Unary") -> case conVal of arg -> Unary<$>
parseJSON
arg | (conKey==
pack
"Product") -> case conVal ofArray
arr |length
arr==
3 ->Product
<$>
parseJSON
(arr!
0)<*>
parseJSON
(arr!
1)<*>
parseJSON
(arr!
2) _ ->mzero
| (conKey==
pack
"Record") -> case conVal ofObject
obj -> Record<$>
(obj.:
pack
"One")<*>
(obj.:
pack
"Two")<*>
(obj.:
pack
"Three") _ ->mzero
|otherwise
->mzero
_ ->mzero
_ ->mzero
Now we can use the newly created instances.
d :: DInt
d = Record { testOne = 3.14159 , testTwo =True
, testThree = Product "test" 'A' 123 }
>>>
fromJSON (toJSON d) == Success d
> True
Documentation
:: (String -> String) | Function to change field names. |
-> Name | Name of the type for which to generate |
-> Q [Dec] |
Generates both ToJSON
and FromJSON
instance declarations for the given
data type.
This is a convienience function which is equivalent to calling both
deriveToJSON
and deriveFromJSON
.
:: (String -> String) | Function to change field names. |
-> Name | Name of the type for which to generate a |
-> Q [Dec] |
Generates a FromJSON
instance declaration for the given data type.
Example:
data Foo = FooChar
Int
$(deriveFromJSON
id
''Foo)
This will splice in the following code:
instanceFromJSON
Foo whereparseJSON
= value -> case value ofArray
arr | (length
arr==
2) -> Foo<$>
parseJSON
(arr!
0)<*>
parseJSON
(arr!
1) _ ->mzero
Generates a lambda expression which parses the JSON encoding of the given data type.
Example:
data Foo = Foo Int
parseFoo ::Value
->Parser
Foo parseFoo = $(mkParseJSON
id
''Foo)
This will splice in the following code:
\value -> case value of arg -> Foo<$>
parseJSON
arg