-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Better error messages when decoding JSON values. -- @package aeson-better-errors @version 0.4.0.0 module Data.Aeson.BetterErrors.Internal -- | The type of parsers: things which consume JSON values and produce -- either detailed errors or successfully parsed values (of other types). -- -- The err type parameter is for custom validation errors; for -- parsers that don't produce any custom validation errors, I recommend -- you just stick a type variable in for full generality: -- --
--   asTuple :: Parse e (Int, Int)
--   asTuple = (,) <$> nth 0 asIntegral <*> nth 1 asIntegral
--   
newtype Parse err a Parse :: (ReaderT ParseReader (Except (ParseError err)) a) -> Parse err a -- | The type of parsers which never produce custom validation errors. type Parse' = Parse Void runParser :: (s -> Either String Value) -> Parse err a -> s -> Either (ParseError err) a -- | Run a parser with a lazy ByteString containing JSON data. Note -- that the normal caveat applies: the JSON supplied must contain either -- an object or an array for this to work. parse :: Parse err a -> ByteString -> Either (ParseError err) a -- | Run a parser with a strict ByteString containing JSON data. -- Note that the normal caveat applies: the JSON supplied must contain -- either an object or an array for this to work. parseStrict :: Parse err a -> ByteString -> Either (ParseError err) a -- | Run a parser with a pre-parsed JSON Value. parseValue :: Parse err a -> Value -> Either (ParseError err) a -- | This function is useful when you have a Parse err a -- and you want to obtain an instance for FromJSON a. -- Simply define: -- --
--   parseJSON = toAesonParser showMyCustomError myParser
--   
toAesonParser :: (err -> Text) -> Parse err a -> Value -> Parser a -- | Take a parser which never produces custom validation errors and turn -- it into an Aeson parser. Note that in this case, there is no need to -- provide a display function. toAesonParser' :: Parse' a -> Value -> Parser a -- | Data used internally by the Parse type. data ParseReader ParseReader :: DList PathPiece -> Value -> ParseReader rdrPath :: ParseReader -> DList PathPiece rdrValue :: ParseReader -> Value appendPath :: PathPiece -> ParseReader -> ParseReader setValue :: Value -> ParseReader -> ParseReader -- | A piece of a path leading to a specific part of the JSON data. -- Internally, a list of these is maintained as the parser traverses the -- JSON data. This list is included in the error if one occurs. data PathPiece ObjectKey :: Text -> PathPiece ArrayIndex :: Int -> PathPiece -- | A value indicating that the JSON could not be decoded successfully. data ParseError err InvalidJSON :: String -> ParseError err BadSchema :: [PathPiece] -> (ErrorSpecifics err) -> ParseError err -- | Detailed information in the case where a value could be parsed as -- JSON, but a value of the required type could not be constructed from -- it, for some reason. data ErrorSpecifics err KeyMissing :: Text -> ErrorSpecifics err OutOfBounds :: Int -> ErrorSpecifics err -- | Expected type, actual value WrongType :: JSONType -> Value -> ErrorSpecifics err ExpectedIntegral :: Double -> ErrorSpecifics err CustomError :: err -> ErrorSpecifics err -- | An enumeration of the different types that JSON values may take. data JSONType TyObject :: JSONType TyArray :: JSONType TyString :: JSONType TyNumber :: JSONType TyBool :: JSONType TyNull :: JSONType displayJSONType :: JSONType -> Text -- | Turn a ParseError into a human-readable list of Text -- values. They will be in a sensible order. For example, you can feed -- the result to mapM putStrLn, or unlines. displayError :: (err -> Text) -> ParseError err -> [Text] displayPath :: [PathPiece] -> Text displaySpecifics :: (err -> Text) -> ErrorSpecifics err -> [Text] -- | Get the type of a JSON value. jsonTypeOf :: Value -> JSONType -- | Lift any parsing function into the Parse type. liftParse :: (Value -> Either (ErrorSpecifics err) a) -> Parse err a -- | Aborts parsing, due to an error in the structure of the JSON - that -- is, any error other than the JSON not actually being parseable into a -- Value. badSchema :: ErrorSpecifics err -> Parse err a as :: (Value -> Maybe a) -> JSONType -> Parse err a -- | Parse a single JSON string as Text. asText :: Parse err Text -- | Parse a single JSON string as a String. asString :: Parse err String -- | Parse a single JSON number as a Scientific. asScientific :: Parse err Scientific -- | Parse a single JSON number as any Integral type. asIntegral :: Integral a => Parse err a -- | Parse a single JSON number as any RealFloat type. asRealFloat :: RealFloat a => Parse err a -- | Parse a single JSON boolean as a Bool. asBool :: Parse err Bool -- | Parse a JSON object, as an Object. You should prefer functions -- like eachInObject where possible, since they will usually -- generate better error messages. asObject :: Parse err Object -- | Parse a JSON array, as an Array. You should prefer functions -- like eachInArray where possible, since they will usually -- generate better error messages. asArray :: Parse err Array -- | Parse a single JSON null value. Useful if you want to throw an error -- in the case where something is not null. asNull :: Parse err () -- | Take the value corresponding to a given key in the current object. key :: Text -> Parse err a -> Parse err a -- | Take the value corresponding to a given key in the current object, or -- if no property exists with that key, use the supplied default. keyOrDefault :: Text -> a -> Parse err a -> Parse err a -- | Take the value corresponding to a given key in the current object, or -- if no property exists with that key, return Nothing . keyMay :: Text -> Parse err a -> Parse err (Maybe a) key' :: Parse err a -> Text -> Parse err a -> Parse err a -- | Take the nth value of the current array. nth :: Int -> Parse err a -> Parse err a -- | Take the nth value of the current array, or if no value exists with -- that index, use the supplied default. nthOrDefault :: Int -> a -> Parse err a -> Parse err a -- | Take the nth value of the current array, or if no value exists with -- that index, return Nothing. nthMay :: Int -> Parse err a -> Parse err (Maybe a) nth' :: Parse err a -> Int -> Parse err a -> Parse err a -- | Attempt to parse each value in the array with the given parser, and -- collect the results. eachInArray :: Parse err a -> Parse err [a] -- | Attempt to parse each property value in the object with the given -- parser, and collect the results. eachInObject :: Parse err a -> Parse err [(Text, a)] -- | Attempt to parse each property in the object: parse the key with the -- given validation function, parse the value with the given parser, and -- collect the results. eachInObjectWithKey :: (Text -> Either err k) -> Parse err a -> Parse err [(k, a)] -- | Lifts a function attempting to validate an arbitrary JSON value into a -- parser. You should only use this if absolutely necessary; the other -- functions in this module will generally give better error reporting. withValue :: (Value -> Either err a) -> Parse err a liftEither :: Either err a -> Parse err a with :: Parse err a -> (a -> Either err b) -> Parse err b withText :: (Text -> Either err a) -> Parse err a withString :: (String -> Either err a) -> Parse err a withScientific :: (Scientific -> Either err a) -> Parse err a withIntegral :: Integral a => (a -> Either err b) -> Parse err b withRealFloat :: RealFloat a => (a -> Either err b) -> Parse err b withBool :: (Bool -> Either err a) -> Parse err a -- | Prefer to use functions like 'key or eachInObject to this one -- where possible, as they will generate better error messages. withObject :: (Object -> Either err a) -> Parse err a -- | Prefer to use functions like nth or eachInArray to this -- one where possible, as they will generate better error messages. withArray :: (Array -> Either err a) -> Parse err a instance Show PathPiece instance Eq PathPiece instance Ord PathPiece instance Show JSONType instance Eq JSONType instance Ord JSONType instance Show err => Show (ErrorSpecifics err) instance Eq err => Eq (ErrorSpecifics err) instance Show err => Show (ParseError err) instance Eq err => Eq (ParseError err) instance Functor (Parse err) instance Applicative (Parse err) instance Monad (Parse err) instance MonadReader ParseReader (Parse err) instance MonadError (ParseError err) (Parse err) -- | A module for decoding JSON, and generating good error messages. Note, -- however, that this package only deals with generating good error -- messages after the JSON has been parsed into a Value - -- unfortunately, invalid JSON will still produce poor error messages. -- -- See http://harry.garrood.me/blog/aeson-better-errors/ for a -- tutorial. -- -- Any kind of feedback is very welcome: suggestions for a better -- designed API, bug reports, whatever - the best place for it is -- probably the GitHub issue tracker: -- https://github.com/hdgarrood/aeson-better-errors/issues. module Data.Aeson.BetterErrors -- | The type of parsers: things which consume JSON values and produce -- either detailed errors or successfully parsed values (of other types). -- -- The err type parameter is for custom validation errors; for -- parsers that don't produce any custom validation errors, I recommend -- you just stick a type variable in for full generality: -- --
--   asTuple :: Parse e (Int, Int)
--   asTuple = (,) <$> nth 0 asIntegral <*> nth 1 asIntegral
--   
data Parse err a -- | The type of parsers which never produce custom validation errors. type Parse' = Parse Void -- | Parse a single JSON string as Text. asText :: Parse err Text -- | Parse a single JSON string as a String. asString :: Parse err String -- | Parse a single JSON number as a Scientific. asScientific :: Parse err Scientific -- | Parse a single JSON number as any Integral type. asIntegral :: Integral a => Parse err a -- | Parse a single JSON number as any RealFloat type. asRealFloat :: RealFloat a => Parse err a -- | Parse a single JSON boolean as a Bool. asBool :: Parse err Bool -- | Parse a single JSON null value. Useful if you want to throw an error -- in the case where something is not null. asNull :: Parse err () -- | Parse a JSON object, as an Object. You should prefer functions -- like eachInObject where possible, since they will usually -- generate better error messages. asObject :: Parse err Object -- | Parse a JSON array, as an Array. You should prefer functions -- like eachInArray where possible, since they will usually -- generate better error messages. asArray :: Parse err Array -- | Take the value corresponding to a given key in the current object. key :: Text -> Parse err a -> Parse err a -- | Take the value corresponding to a given key in the current object, or -- if no property exists with that key, use the supplied default. keyOrDefault :: Text -> a -> Parse err a -> Parse err a -- | Take the value corresponding to a given key in the current object, or -- if no property exists with that key, return Nothing . keyMay :: Text -> Parse err a -> Parse err (Maybe a) -- | Take the nth value of the current array. nth :: Int -> Parse err a -> Parse err a -- | Take the nth value of the current array, or if no value exists with -- that index, use the supplied default. nthOrDefault :: Int -> a -> Parse err a -> Parse err a -- | Take the nth value of the current array, or if no value exists with -- that index, return Nothing. nthMay :: Int -> Parse err a -> Parse err (Maybe a) -- | Attempt to parse each value in the array with the given parser, and -- collect the results. eachInArray :: Parse err a -> Parse err [a] -- | Attempt to parse each property value in the object with the given -- parser, and collect the results. eachInObject :: Parse err a -> Parse err [(Text, a)] -- | Attempt to parse each property in the object: parse the key with the -- given validation function, parse the value with the given parser, and -- collect the results. eachInObjectWithKey :: (Text -> Either err k) -> Parse err a -> Parse err [(k, a)] withText :: (Text -> Either err a) -> Parse err a withString :: (String -> Either err a) -> Parse err a withScientific :: (Scientific -> Either err a) -> Parse err a withIntegral :: Integral a => (a -> Either err b) -> Parse err b withRealFloat :: RealFloat a => (a -> Either err b) -> Parse err b withBool :: (Bool -> Either err a) -> Parse err a -- | Prefer to use functions like 'key or eachInObject to this one -- where possible, as they will generate better error messages. withObject :: (Object -> Either err a) -> Parse err a -- | Prefer to use functions like nth or eachInArray to this -- one where possible, as they will generate better error messages. withArray :: (Array -> Either err a) -> Parse err a -- | Run a parser with a lazy ByteString containing JSON data. Note -- that the normal caveat applies: the JSON supplied must contain either -- an object or an array for this to work. parse :: Parse err a -> ByteString -> Either (ParseError err) a -- | Run a parser with a strict ByteString containing JSON data. -- Note that the normal caveat applies: the JSON supplied must contain -- either an object or an array for this to work. parseStrict :: Parse err a -> ByteString -> Either (ParseError err) a -- | Run a parser with a pre-parsed JSON Value. parseValue :: Parse err a -> Value -> Either (ParseError err) a -- | A value indicating that the JSON could not be decoded successfully. data ParseError err InvalidJSON :: String -> ParseError err BadSchema :: [PathPiece] -> (ErrorSpecifics err) -> ParseError err -- | A piece of a path leading to a specific part of the JSON data. -- Internally, a list of these is maintained as the parser traverses the -- JSON data. This list is included in the error if one occurs. data PathPiece ObjectKey :: Text -> PathPiece ArrayIndex :: Int -> PathPiece -- | Detailed information in the case where a value could be parsed as -- JSON, but a value of the required type could not be constructed from -- it, for some reason. data ErrorSpecifics err KeyMissing :: Text -> ErrorSpecifics err OutOfBounds :: Int -> ErrorSpecifics err -- | Expected type, actual value WrongType :: JSONType -> Value -> ErrorSpecifics err ExpectedIntegral :: Double -> ErrorSpecifics err CustomError :: err -> ErrorSpecifics err -- | Turn a ParseError into a human-readable list of Text -- values. They will be in a sensible order. For example, you can feed -- the result to mapM putStrLn, or unlines. displayError :: (err -> Text) -> ParseError err -> [Text] displayPath :: [PathPiece] -> Text displaySpecifics :: (err -> Text) -> ErrorSpecifics err -> [Text] -- | This function is useful when you have a Parse err a -- and you want to obtain an instance for FromJSON a. -- Simply define: -- --
--   parseJSON = toAesonParser showMyCustomError myParser
--   
toAesonParser :: (err -> Text) -> Parse err a -> Value -> Parser a -- | Take a parser which never produces custom validation errors and turn -- it into an Aeson parser. Note that in this case, there is no need to -- provide a display function. toAesonParser' :: Parse' a -> Value -> Parser a -- | An enumeration of the different types that JSON values may take. data JSONType TyObject :: JSONType TyArray :: JSONType TyString :: JSONType TyNumber :: JSONType TyBool :: JSONType TyNull :: JSONType -- | Get the type of a JSON value. jsonTypeOf :: Value -> JSONType