{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Data.Aeson.Result
( Ok (..)
, Err (..)
, err
, ok
, fromOk
, toOk
, throwError
, From
, Size
, Total
, List (..)
, emptyList
, merge
, toList
, fromList
) where
import Control.Exception (Exception, throwIO)
import Data.Aeson (FromJSON (..), Result (..), ToJSON (..),
Value, fromJSON, object, withObject, (.:),
(.=))
import Data.Aeson.Helper (replace)
import Data.Int (Int64)
import Data.Text (Text)
type From = Int64
type Size = Int64
type Total = Int64
newtype Ok a = Ok { getValue :: a }
deriving (Show)
instance (FromJSON a) => FromJSON (Ok a) where
parseJSON = withObject "Ok" $ \o -> do
getValue <- o .: "result"
return Ok{..}
instance (ToJSON a) => ToJSON (Ok a) where
toJSON Ok{..} = object [ "result" .= getValue ]
newtype Err = Err { errMsg :: String }
deriving (Show, Eq, Ord)
instance Exception Err
throwError :: Err -> IO a
throwError = throwIO
instance FromJSON Err where
parseJSON = withObject "Err" $ \o -> do
errMsg <- o .: "err"
return Err{..}
instance ToJSON Err where
toJSON Err{..} = object [ "err" .= errMsg ]
err :: String -> Err
err = Err
ok :: a -> Ok a
ok = Ok
toOk :: FromJSON a => Text -> Value -> Maybe (Ok a)
toOk okey v =
case fromJSON (replace okey "result" v) of
Success v' -> Just v'
_ -> Nothing
fromOk :: ToJSON a => Text -> Ok a -> Value
fromOk key ret = replace "result" key $ toJSON ret
data List a = List
{ getFrom :: From
, getSize :: Size
, getTotal :: Total
, getResult :: [a]
}
deriving (Show)
instance FromJSON a => FromJSON (List a) where
parseJSON = withObject "List" $ \o -> do
getFrom <- o .: "from"
getSize <- o .: "size"
getTotal <- o .: "total"
getResult <- o .: "result"
return List{..}
instance ToJSON a => ToJSON (List a) where
toJSON List{..} = object
[ "from" .= getFrom
, "size" .= getSize
, "total" .= getTotal
, "result" .= getResult
]
emptyList :: List a
emptyList = List
{ getFrom = 0
, getSize = 10
, getTotal = 0
, getResult = []
}
merge :: [a] -> List b -> List a
merge t List
{ getFrom = from
, getSize = size
, getTotal = total
} = List
{ getFrom = from
, getSize = size
, getTotal = total
, getResult = t
}
toList :: FromJSON a => Text -> Value -> Maybe (List a)
toList okey v =
case fromJSON (replace okey "result" v) of
Success v' -> Just v'
_ -> Nothing
fromList :: ToJSON a => Text -> List a -> Value
fromList key ret = replace "result" key $ toJSON ret