This function:
eitherDecode :: FromJSON a => ByteString -> Either String a
Has a small limitation that I can't have an additional implementation of a decode that is NOT the one from FromJSON a
.
In other words I'm looking for some way to pass my own Bytestring -> Either String a
parsing function.
Okay... So I'll have to define my own function for this it seems.
It's defined as:
-- | Like 'decode' but returns an error message when decoding fails.
eitherDecode :: (FromJSON a) => L.ByteString -> Either String a
eitherDecode = eitherFormatError . eitherDecodeWith jsonEOF ifromJSON
Looks like ifrom
is what I need to modify which is defined as:
-- | Convert a value from JSON, failing if the types do not match.
ifromJSON :: (FromJSON a) => Value -> IResult a
ifromJSON = iparse parseJSON
Well eitherFormatError
is not exported from Aeson so this basically seems like I might be going down the wrong approach.
After a bit of type juggling...
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module AesonExtra where
import Data.Aeson
import Data.Aeson.Types
import qualified Data.ByteString.Lazy as L
import qualified Data.HashMap.Strict as HashMap
import Data.Foldable (toList)
import Data.String.Conversions
import Data.Text (Text)
eitherDecodeCustom :: (Value -> Parser a) -> L.ByteString -> Either String a
eitherDecodeCustom f x = do
xx <- eitherDecode x :: Either String Value
parseEither f xx