aeson-commit 1.2 → 1.3
raw patch · 4 files changed
+30/−24 lines, 4 filesdep −containersdep −hspecdep −somedep ~aesondep ~aeson-qqdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies removed: containers, hspec, some, transformers
Dependency ranges changed: aeson, aeson-qq, base, tasty
API changes (from Hackage documentation)
Files
- CHANGELOG.md +5/−0
- README.md +5/−3
- aeson-commit.cabal +9/−14
- src/Data/Aeson/Commit.hs +11/−7
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Changelog +## [1.3]+### [Changed]+- Relax version bounds in preparation for uploading to stackage+- Rewords documentation -- again+ ## [1.2] ### [Changed] - Reword parts of the documentation
README.md view
@@ -1,7 +1,9 @@ # aeson-commit--[](https://hackage.haskell.org/package/aeson-commit)+[](https://hackage.haskell.org/package/aeson-commit)+[](https://www.stackage.org/package/aeson-commit)+[](https://travis-ci.org/xc-jp/aeson-commit) -Aeson parsers backtracks too much for some use cases. `aeson-commit` provides a mechanism for preserving parser errors.+Commitment mechanism for `aeson` parsers.+Commitment means that if some initial parsing succeeds, subsequent failures are unrecoverable. See [haddocks](https://hackage.haskell.org/package/aeson-commit/docs/Data-Aeson-Commit.html) for more information and examples.
aeson-commit.cabal view
@@ -1,6 +1,6 @@ cabal-version: >=1.10 name: aeson-commit-version: 1.2+version: 1.3 license: BSD3 copyright: 2020 Cross Compass Ltd. maintainer: Jonas Carpay <jonascarpay@gmail.com>@@ -11,8 +11,8 @@ synopsis: Parse Aeson data with commitment description:- Aeson parsers backtracks too much for some use cases.- The commit parser forbids backtracking for already committed parses.+ Commitment mechanism for @aeson@ parsers.+ Commitment means that if some initial parsing succeeds, subsequent failures are unrecoverable. category: Text, Web, JSON build-type: Simple@@ -30,8 +30,8 @@ default-language: Haskell2010 ghc-options: -Wall -Wno-name-shadowing build-depends:- aeson >=1.5 && <2- , base >=4.12 && <5+ aeson >=1.4 && <2+ , base >=4.10 && <5 , mtl >=2.2 && <3 , text >=1.2 && <2 @@ -42,15 +42,10 @@ default-language: Haskell2010 ghc-options: -Wall -Wno-name-shadowing build-depends:- aeson >=1.5 && <2+ aeson >=1.4 && <2 , aeson-commit- , aeson-qq >=0.8.3 && <1- , base >=4.12 && <5- , containers >=0.6.2 && <1- , hspec >=2.7.4 && <3- , mtl >=2.2 && <3- , some >=1.0.1 && <2- , tasty >=1.3.1 && <2+ , aeson-qq >=0.8 && <1+ , base >=4.10 && <5+ , tasty >=1.2 && <2 , tasty-hspec >=1.1.5.1 && <2 , text >=1.2 && <2- , transformers >=0.5.6 && <1
src/Data/Aeson/Commit.hs view
@@ -2,8 +2,9 @@ {-| Commitment mechanism for aeson 'Parser'.- This is comes up when you e.g. want to make a distinction between in error handling for missing keys and malformed keys.- As an example, this parser will yield @nested.value@ if there the key @nested@ is present, and @value@ if it is not present.+ Commitment means that if some initial parsing succeeds, subsequent failures are unrecoverable.+ In this example, not having the key @nested@ is a normal, recoverable failure, and parsing will continue looking for another key.+ However, if @nested@ is present but malformed, the entire parser fails. > parse o = (o .:> "nested") (withObject "nestedObj" (.: "value")) > <|> tryParser (o .: "value")@@ -46,17 +47,18 @@ -- The default, recoverable failure is the equivalent to aeson's default 'Parser' behavior. -- The non-recoverable failure mode is used to commit to a branch; to commit means that every subsequent failure is non-recoverable. ----- You turn a commit back into a normal 'Parser' using 'runCommit'.--- As an additional benefit, if no commit succeeded the parser error message will contain all encountered errors.+-- You turn run a 'Commit' and capture its result in a 'Parser' using 'runCommit'.+-- As an additional benefit, it will contain error info for all attempted parsing branches. ----- The implementation works by capturing failure in either the 'ExceptT' or in the underlying 'Parser'.--- The derived 'Alternative' instance will only recover from failures in the 'ExceptT'.+-- The implementation works by wrapping 'Parser' in an 'ExceptT'.+-- The derived 'Alternative' instance will then only recover from failures in the 'ExceptT'. -- This means that as soon as we successfully construct a 'Right' value, the 'Alternative' considers the 'Commit' a success, even though the underlying parser might have failed. -- The 'Void' represents the guarantee that we only collect error values. newtype Commit a = Commit {unCommit :: ExceptT [Parser Void] Parser a} deriving (Monad, Functor, Applicative, Alternative) -- | Construct a commit.+-- If the first parser fails, the failure is recoverable through 'Alternative'. -- If the first parser succeeds, the 'Commit' is a success, and any failures in the inner action will be preserved. commit :: Parser a -> (a -> Parser b) -> Commit b commit pre post = Commit $ do@@ -66,7 +68,7 @@ captureError :: Parser b -> Parser (Either [Parser Void] b) captureError p = Right <$> p <|> pure (Left [fmap (const undefined) p]) --- | Turn a 'Commit' back into a regular 'Parser'.+-- | Run a 'Commit', capturing its result in a 'Parser'. runCommit :: Commit a -> Parser a runCommit (Commit f) = runExceptT f >>= either handleErrors pure where@@ -92,6 +94,7 @@ -- Unlike 'liftParser', the parser's failure is recoverable. -- -- > tryParser empty <|> p = p+-- > tryParser p = commit p pure tryParser :: Parser a -> Commit a tryParser p = commit p pure @@ -99,5 +102,6 @@ -- Unlike 'tryParser', the parser's failure is _not_ recoverable, i.e. the parse is always committed. -- -- > liftParser empty <|> p = empty+-- > liftParser p = commit (pure ()) (const p) liftParser :: Parser a -> Commit a liftParser p = commit (pure ()) (const p)