{- |
Module      : Data.Aeson.Extras
Description : Some stuff not included in Data.Aeson.
Copyright   : 2018, Automattic, Inc.
License     : BSD3
Maintainer  : Nathan Bloomfield (nbloomf@gmail.com)
Stability   : experimental
Portability : POSIX

JSON helpers.
-}

module Data.Aeson.Extras (
    JsonError(..)
) where

import Data.Aeson
  ( Value() )
import Data.ByteString.Lazy
  ( ByteString )
import Data.String
  ( fromString )
import Data.Text
  ( Text, pack )
import Test.QuickCheck
  ( Arbitrary(..), Gen )



-- | Represents the kinds of errors that can occur when parsing and decoding JSON.
data JsonError
  -- | A generic JSON error; try not to use this.
  = JsonError Text
  -- | A failed parse.
  | JsonParseError ByteString
  -- | An attempt to look up the value of a key that does not exist on an object.
  | JsonKeyDoesNotExist Text Value
  -- | An attempt to look up the value of a key on something other than an object.
  | JsonKeyLookupOffObject Text Value
  -- | A failed attempt to convert a `Value` to some other type.
  | JsonConstructError String
  deriving (JsonError -> JsonError -> Bool
(JsonError -> JsonError -> Bool)
-> (JsonError -> JsonError -> Bool) -> Eq JsonError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JsonError -> JsonError -> Bool
$c/= :: JsonError -> JsonError -> Bool
== :: JsonError -> JsonError -> Bool
$c== :: JsonError -> JsonError -> Bool
Eq, Int -> JsonError -> ShowS
[JsonError] -> ShowS
JsonError -> String
(Int -> JsonError -> ShowS)
-> (JsonError -> String)
-> ([JsonError] -> ShowS)
-> Show JsonError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [JsonError] -> ShowS
$cshowList :: [JsonError] -> ShowS
show :: JsonError -> String
$cshow :: JsonError -> String
showsPrec :: Int -> JsonError -> ShowS
$cshowsPrec :: Int -> JsonError -> ShowS
Show)

instance Arbitrary JsonError where
  arbitrary :: Gen JsonError
arbitrary = do
    let arbText :: Gen Text
arbText = String -> Text
pack (String -> Text) -> Gen String -> Gen Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String
forall a. Arbitrary a => Gen a
arbitrary
    Int
k <- Gen Int
forall a. Arbitrary a => Gen a
arbitrary :: Gen Int
    case Int
k Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
5 of
      Int
0 -> Text -> JsonError
JsonError (Text -> JsonError) -> Gen Text -> Gen JsonError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Text
arbText
      Int
1 -> ByteString -> JsonError
JsonParseError (ByteString -> JsonError) -> Gen ByteString -> Gen JsonError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> ByteString
forall a. IsString a => String -> a
fromString (String -> ByteString) -> Gen String -> Gen ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String
forall a. Arbitrary a => Gen a
arbitrary)
      Int
2 -> Text -> Value -> JsonError
JsonKeyDoesNotExist (Text -> Value -> JsonError)
-> Gen Text -> Gen (Value -> JsonError)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
             (String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> Gen String -> Gen Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String
forall a. Arbitrary a => Gen a
arbitrary) Gen (Value -> JsonError) -> Gen Value -> Gen JsonError
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
             (String -> Value
forall a. IsString a => String -> a
fromString (String -> Value) -> Gen String -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String
forall a. Arbitrary a => Gen a
arbitrary)
      Int
3 -> Text -> Value -> JsonError
JsonKeyLookupOffObject (Text -> Value -> JsonError)
-> Gen Text -> Gen (Value -> JsonError)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
             (String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> Gen String -> Gen Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String
forall a. Arbitrary a => Gen a
arbitrary) Gen (Value -> JsonError) -> Gen Value -> Gen JsonError
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
             (String -> Value
forall a. IsString a => String -> a
fromString (String -> Value) -> Gen String -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String
forall a. Arbitrary a => Gen a
arbitrary)
      Int
_ -> String -> JsonError
JsonConstructError (String -> JsonError) -> Gen String -> Gen JsonError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String
forall a. Arbitrary a => Gen a
arbitrary