Skip to content

Commit

Permalink
Use Decoding parsers as default
Browse files Browse the repository at this point in the history
Move Data.Aeson.Parser(.Internal) into new package attoparsec-aeson

Update tests and benchmarks (mostly cleanup).
Very few error messages are now different, e.g. on unexpected
end-of-input.
  • Loading branch information
phadej committed Jun 9, 2023
1 parent 3e6cee2 commit e79a7ca
Show file tree
Hide file tree
Showing 34 changed files with 357 additions and 342 deletions.
11 changes: 9 additions & 2 deletions .github/workflows/haskell-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ jobs:
touch cabal.project
echo "packages: $GITHUB_WORKSPACE/source/." >> cabal.project
echo "packages: $GITHUB_WORKSPACE/source/attoparsec-iso8601" >> cabal.project
echo "packages: $GITHUB_WORKSPACE/source/attoparsec-aeson" >> cabal.project
echo "packages: $GITHUB_WORKSPACE/source/text-iso8601" >> cabal.project
echo "packages: $GITHUB_WORKSPACE/source/examples" >> cabal.project
echo "packages: $GITHUB_WORKSPACE/source/benchmarks" >> cabal.project
Expand All @@ -231,6 +232,8 @@ jobs:
echo "PKGDIR_aeson=${PKGDIR_aeson}" >> "$GITHUB_ENV"
PKGDIR_attoparsec_iso8601="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/attoparsec-iso8601-[0-9.]*')"
echo "PKGDIR_attoparsec_iso8601=${PKGDIR_attoparsec_iso8601}" >> "$GITHUB_ENV"
PKGDIR_attoparsec_aeson="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/attoparsec-aeson-[0-9.]*')"
echo "PKGDIR_attoparsec_aeson=${PKGDIR_attoparsec_aeson}" >> "$GITHUB_ENV"
PKGDIR_text_iso8601="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/text-iso8601-[0-9.]*')"
echo "PKGDIR_text_iso8601=${PKGDIR_text_iso8601}" >> "$GITHUB_ENV"
PKGDIR_aeson_examples="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/aeson-examples-[0-9.]*')"
Expand All @@ -242,13 +245,16 @@ jobs:
touch cabal.project.local
echo "packages: ${PKGDIR_aeson}" >> cabal.project
echo "packages: ${PKGDIR_attoparsec_iso8601}" >> cabal.project
echo "packages: ${PKGDIR_attoparsec_aeson}" >> cabal.project
echo "packages: ${PKGDIR_text_iso8601}" >> cabal.project
echo "packages: ${PKGDIR_aeson_examples}" >> cabal.project
echo "packages: ${PKGDIR_aeson_benchmarks}" >> cabal.project
echo "package aeson" >> cabal.project
echo " ghc-options: -Werror=missing-methods" >> cabal.project
echo "package attoparsec-iso8601" >> cabal.project
echo " ghc-options: -Werror=missing-methods" >> cabal.project
echo "package attoparsec-aeson" >> cabal.project
echo " ghc-options: -Werror=missing-methods" >> cabal.project
echo "package text-iso8601" >> cabal.project
echo " ghc-options: -Werror=missing-methods" >> cabal.project
echo "package aeson-examples" >> cabal.project
Expand All @@ -258,7 +264,7 @@ jobs:
cat >> cabal.project <<EOF
allow-newer: hermes-json:attoparsec-iso8601
EOF
$HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(aeson|aeson-benchmarks|aeson-examples|attoparsec-iso8601|text-iso8601)$/; }' >> cabal.project.local
$HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(aeson|aeson-benchmarks|aeson-examples|attoparsec-aeson|attoparsec-iso8601|text-iso8601)$/; }' >> cabal.project.local
cat cabal.project
cat cabal.project.local
- name: dump install plan
Expand Down Expand Up @@ -286,8 +292,9 @@ jobs:
cabal-docspec $ARG_COMPILER
- name: hlint
run: |
if [ $((HCNUMVER >= 90200 && HCNUMVER < 90400)) -ne 0 ] ; then (cd ${PKGDIR_aeson} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 src attoparsec-iso8601/src src-pure) ; fi
if [ $((HCNUMVER >= 90200 && HCNUMVER < 90400)) -ne 0 ] ; then (cd ${PKGDIR_aeson} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 src) ; fi
if [ $((HCNUMVER >= 90200 && HCNUMVER < 90400)) -ne 0 ] ; then (cd ${PKGDIR_attoparsec_iso8601} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 src) ; fi
if [ $((HCNUMVER >= 90200 && HCNUMVER < 90400)) -ne 0 ] ; then (cd ${PKGDIR_attoparsec_aeson} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 src) ; fi
if [ $((HCNUMVER >= 90200 && HCNUMVER < 90400)) -ne 0 ] ; then (cd ${PKGDIR_text_iso8601} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 src) ; fi
if [ $((HCNUMVER >= 90200 && HCNUMVER < 90400)) -ne 0 ] ; then (cd ${PKGDIR_aeson_examples} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 src/) ; fi
if [ $((HCNUMVER >= 90200 && HCNUMVER < 90400)) -ne 0 ] ; then (cd ${PKGDIR_aeson_benchmarks} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 .) ; fi
Expand Down
1 change: 1 addition & 0 deletions .hlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- ignore:
name: "Unused LANGUAGE pragma"
within:
- Data.Aeson.Internal.ByteString
- Data.Aeson.Internal.Text
- Compare.JsonBench

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
lint:
./run-hlint.sh --cpp-include include/ src/ attoparsec-iso8601/ benchmarks/ examples/ src-pure/ tests/ text-iso8601/src text-iso8601/tests
./run-hlint.sh --cpp-include include/ src/ attoparsec-iso8601/ benchmarks/ examples/ tests/ text-iso8601/src text-iso8601/tests attoparsec-aeson/src
12 changes: 3 additions & 9 deletions aeson.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ extra-source-files:
benchmarks/json-data/*.json
changelog.md
README.markdown
src-pure/Data/Aeson/Parser/*.hs
tests/golden/*.expected
tests/JSONTestSuite/results/*.tok
tests/JSONTestSuite/results/*.txt
Expand All @@ -54,7 +53,7 @@ flag ordered-keymap

library
default-language: Haskell2010
hs-source-dirs: src attoparsec-iso8601/src
hs-source-dirs: src
exposed-modules:
Data.Aeson
Data.Aeson.Decoding
Expand All @@ -65,31 +64,28 @@ library
Data.Aeson.Encoding.Internal
Data.Aeson.Key
Data.Aeson.KeyMap
Data.Aeson.Parser
Data.Aeson.Parser.Internal
Data.Aeson.QQ.Simple
Data.Aeson.Text
Data.Aeson.TH
Data.Aeson.Types

other-modules:
Data.Aeson.Decoding.Conversion
Data.Aeson.Decoding.Internal
Data.Aeson.Encoding.Builder
Data.Aeson.Internal.ByteString
Data.Aeson.Internal.Functions
Data.Aeson.Internal.Prelude
Data.Aeson.Internal.Text
Data.Aeson.Internal.TH
Data.Aeson.Internal.Unescape
Data.Aeson.Internal.Word8
Data.Aeson.Parser.Time
Data.Aeson.Parser.Unescape
Data.Aeson.Types.Class
Data.Aeson.Types.FromJSON
Data.Aeson.Types.Generic
Data.Aeson.Types.Internal
Data.Aeson.Types.ToJSON
Data.Attoparsec.Time
Data.Attoparsec.Time.Internal

-- GHC bundled libs
build-depends:
Expand Down Expand Up @@ -138,8 +134,6 @@ library
ghc-options: -Wall

-- String unescaping
hs-source-dirs: src-pure
other-modules: Data.Aeson.Parser.UnescapePure

if flag(ordered-keymap)
cpp-options: -DUSE_ORDEREDMAP=1
Expand Down
30 changes: 30 additions & 0 deletions attoparsec-aeson/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Copyright (c) 2011, MailRank, Inc.

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

3. Neither the name of the author nor the names of his contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
59 changes: 59 additions & 0 deletions attoparsec-aeson/attoparsec-aeson.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
cabal-version: 1.12
name: attoparsec-aeson
version: 2.2
synopsis: Parsing of aeson's Value with attoparsec
description:
Parsing of aeson's Value with attoparsec, originally from aeson.

license: BSD3
license-file: LICENSE
category: Parsing
copyright:
(c) 2011-2016 Bryan O'Sullivan
(c) 2011 MailRank, Inc.

author: Bryan O'Sullivan <[email protected]>
maintainer: Oleg Grenrus <[email protected]>
stability: experimental
homepage: https://github.com/haskell/aeson
bug-reports: https://github.com/haskell/aeson/issues
build-type: Simple
tested-with:
GHC ==8.2.2
|| ==8.4.4
|| ==8.6.5
|| ==8.8.4
|| ==8.10.7
|| ==9.0.2
|| ==9.2.8
|| ==9.4.5
|| ==9.6.2

library
hs-source-dirs: src
default-language: Haskell2010
ghc-options: -Wall
exposed-modules:
Data.Aeson.Parser
Data.Aeson.Parser.Internal

other-modules:
Data.Aeson.Internal.ByteString
Data.Aeson.Internal.Text
Data.Aeson.Internal.Word8

build-depends:
aeson >=2.2 && <2.3
, attoparsec >=0.14.2 && <0.15
, base >=4.10.0.0 && <5
, bytestring >=0.10.8.2 && <0.12
, integer-conversion >=0.1 && <0.2
, primitive >=0.8.0.0 && <0.9
, scientific >=0.3.7.0 && <0.4
, text >=1.2.3.0 && <1.3 || >=2.0 && <2.1
, vector >=0.12.0.1 && <0.14

source-repository head
type: git
location: git://github.com/haskell/aeson.git
subdir: attoparsec-aeson
1 change: 1 addition & 0 deletions attoparsec-aeson/src/Data/Aeson/Internal/ByteString.hs
1 change: 1 addition & 0 deletions attoparsec-aeson/src/Data/Aeson/Internal/Text.hs
1 change: 1 addition & 0 deletions attoparsec-aeson/src/Data/Aeson/Internal/Word8.hs
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,36 @@ module Data.Aeson.Parser.Internal
, unescapeText
) where

import Data.Aeson.Internal.Prelude

import Data.Aeson.Types.Internal (IResult(..), JSONPath, Object, Result(..), Value(..), Key)
import qualified Data.Aeson.KeyMap as KM
import qualified Data.Aeson.Key as Key
import Control.Applicative ((<|>))
import Control.Monad (when, void)
import Data.Attoparsec.ByteString.Char8 (Parser, char, decimal, endOfInput, isDigit_w8, signed, string)
import Data.Function (fix)
import Data.Functor (($>))
import Data.Integer.Conversion (byteStringToInteger)
import qualified Data.Vector as Vector (empty, fromList, fromListN, reverse)
import Data.Scientific (Scientific)
import Data.Text (Text)
import Data.Vector (Vector)

#if !MIN_VERSION_base(4,11,0)
import Data.Semigroup ((<>))
#endif

import qualified Data.Aeson.Key as Key
import qualified Data.Aeson.KeyMap as KM
import qualified Data.Attoparsec.ByteString as A
import qualified Data.Attoparsec.Lazy as L
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as B
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Builder as B
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Char8 as C
import qualified Data.ByteString.Builder as B
import qualified Data.ByteString.Unsafe as B
import qualified Data.Scientific as Sci
import Data.Aeson.Parser.Unescape (unescapeText)
import qualified Data.Vector as Vector (empty, fromList, fromListN, reverse)

import Data.Aeson.Types (IResult(..), JSONPath, Object, Result(..), Value(..), Key)
import Data.Aeson.Internal.Text
import Data.Aeson.Decoding (unescapeText)
import Data.Aeson.Internal.Word8

-- $setup
Expand Down
1 change: 1 addition & 0 deletions benchmarks/aeson-benchmarks.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ executable aeson-benchmark-suite
build-depends:
aeson
, attoparsec
, attoparsec-aeson
, base
, base-compat-batteries
, base16-bytestring
Expand Down
14 changes: 7 additions & 7 deletions benchmarks/bench/CompareWithJSON.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ decode' s = fromMaybe (error "fail to parse via Aeson") $ A.decode' s
decodeS :: BS.ByteString -> A.Value
decodeS s = fromMaybe (error "fail to parse via Aeson") $ A.decodeStrict' s

decodeIP :: BL.ByteString -> A.Value
decodeIP s = fromMaybe (error "fail to parse via Parser.decodeWith") $
decodeAtto :: BL.ByteString -> A.Value
decodeAtto s = fromMaybe (error "fail to parse via Parser.decodeWith") $
I.decodeWith I.jsonEOF A.fromJSON s

encodeJ :: J.JSValue -> BL.ByteString
Expand All @@ -73,11 +73,11 @@ benchmark =
bgroup "compare-json" [
bgroup "decode" [
bgroup "en" [
bench "aeson/lazy" $ nf decode enA
, bench "aeson/strict" $ nf decode' enA
, bench "aeson/stricter" $ nf decodeS enS
, bench "aeson/parser" $ nf decodeIP enA
, bench "json" $ nf decodeJ enJ
bench "aeson/lazy" $ nf decode enA
, bench "aeson/strict" $ nf decode' enA
, bench "aeson/stricter" $ nf decodeS enS
, bench "aeson/attoparsec" $ nf decodeAtto enA
, bench "json" $ nf decodeJ enJ
]
, bgroup "jp" [
bench "aeson" $ nf decode jpA
Expand Down
Loading

0 comments on commit e79a7ca

Please sign in to comment.