module Data.Aeson.BetterErrors.Utils where

import Control.Monad.Error.Class (MonadError(..))

import qualified Data.Aeson as A
import Data.Scientific (Scientific)
import Data.Text (Text, pack)

-----------------------
-- Various utilities

tshow :: Show a => a -> Text
tshow :: a -> Text
tshow = String -> Text
pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show

-- | A version of catchJust from "Control.Exception.Base", except for any
-- instance of 'MonadError'.
catchJust :: MonadError e m
  => (e -> Maybe b) -- ^ Predicate to select exceptions
  -> m a            -- ^ Computation to run
  -> (b -> m a)     -- ^ Handler
  -> m a
catchJust :: (e -> Maybe b) -> m a -> (b -> m a) -> m a
catchJust e -> Maybe b
p m a
act b -> m a
handler = m a -> (e -> m a) -> m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError m a
act e -> m a
handle
  where
  handle :: e -> m a
handle e
e =
    case e -> Maybe b
p e
e of
      Maybe b
Nothing -> e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError e
e
      Just b
b -> b -> m a
handler b
b

-- Value-level patterns for json values

patNull :: A.Value -> Maybe ()
patNull :: Value -> Maybe ()
patNull Value
A.Null = () -> Maybe ()
forall a. a -> Maybe a
Just ()
patNull Value
_ = Maybe ()
forall a. Maybe a
Nothing

patString :: A.Value -> Maybe Text
patString :: Value -> Maybe Text
patString (A.String Text
t) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
t
patString Value
_ = Maybe Text
forall a. Maybe a
Nothing

patNumber :: A.Value -> Maybe Scientific
patNumber :: Value -> Maybe Scientific
patNumber (A.Number Scientific
x) = Scientific -> Maybe Scientific
forall a. a -> Maybe a
Just Scientific
x
patNumber Value
_ = Maybe Scientific
forall a. Maybe a
Nothing

patBool :: A.Value -> Maybe Bool
patBool :: Value -> Maybe Bool
patBool (A.Bool Bool
x) = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
x
patBool Value
_ = Maybe Bool
forall a. Maybe a
Nothing

patObject :: A.Value -> Maybe A.Object
patObject :: Value -> Maybe Object
patObject (A.Object Object
obj) = Object -> Maybe Object
forall a. a -> Maybe a
Just Object
obj
patObject Value
_ = Maybe Object
forall a. Maybe a
Nothing

patArray :: A.Value -> Maybe A.Array
patArray :: Value -> Maybe Array
patArray (A.Array Array
arr) = Array -> Maybe Array
forall a. a -> Maybe a
Just Array
arr
patArray Value
_ = Maybe Array
forall a. Maybe a
Nothing