module Data.Aeson.Utils
( module Data.Aeson
, module Data.Aeson.Types
, decodeV
, eitherDecodeV
, fromFloatDigits
, (.=?)
, parseNumber
, floatingOrInteger
) where
import Control.Applicative ((<*))
import Data.Aeson
import Data.Aeson.Parser (value)
import Data.Aeson.Types
import Data.Attoparsec.Lazy (Result (..))
import Data.Scientific
import Data.Text (Text)
import qualified Data.Attoparsec.ByteString.Char8 as Atto (skipSpace)
import qualified Data.Attoparsec.Lazy as Atto
import qualified Data.ByteString.Lazy as L
eitherDecodeV :: FromJSON a => L.ByteString -> Either String a
eitherDecodeV v = case Atto.parse (value <* Atto.skipSpace <* Atto.endOfInput) v of
Fail _ _ err -> Left err
Done _ r -> case fromJSON r of
Error e -> Left e
Success a -> Right a
decodeV :: FromJSON a => L.ByteString -> Maybe a
decodeV = either (const Nothing) Just . eitherDecodeV
(.=?) :: ToJSON a => Text -> Maybe a -> Maybe Pair
k .=? v = fmap (k .=) v
parseNumber :: Scientific -> Either Integer Double
parseNumber = either Right Left . floatingOrInteger