on da1db20 help sign in
1052 files changed+3954−71337
since splitsnapshots
unifiedsplit
.gitattributes−1 .gitignore−10 .hlint.yaml−11 .travis.yml+16−43 CONTRIBUTING.md+1−39 Data/Aeson.hs+12−82 Data/Aeson/Encode.hs+1−2 Data/Aeson/Encoding.hs+1−4 Data/Aeson/Encoding/Builder.hs+87−13 Data/Aeson/Encoding/Internal.hs+3−14 Data/Aeson/Internal.hs+1−1 Data/Aeson/Internal/Functions.hs+1−1 Data/Aeson/Internal/Time.hs+41−1 Data/Aeson/Parser.hs+4−13 Data/Aeson/Parser/Internal.hs+65−307 Data/Aeson/Parser/Time.hs+102−19 Data/Aeson/Parser/Unescape.hs+51−11 Data/Aeson/QQ/Simple.hs−25 Data/Aeson/TH.hs+897−447 Data/Aeson/Text.hs+4−5 Data/Aeson/Types.hs+5−49 Data/Aeson/Types/Class.hs+7−26 Data/Aeson/Types/FromJSON.hs+457−983 Data/Aeson/Types/Generic.hs+8−12 Data/Aeson/Types/Internal.hs+26−175 Data/Aeson/Types/ToJSON.hs+534−626 Makefile−2 README.markdown+4−3 aeson.cabal+65−107 attoparsec-iso8601/Data/Attoparsec/Time.hs−148 attoparsec-iso8601/Data/Attoparsec/Time/Internal.hs−64 attoparsec-iso8601/LICENSE−30 attoparsec-iso8601/README.md−19 attoparsec-iso8601/attoparsec-iso8601.cabal−55 attoparsec-iso8601/changelog.md−5 benchmarks/AesonCompareAutoInstances.hs+229 benchmarks/AesonEncode.hs+5−4 benchmarks/AesonFoldable.hs+42−14 benchmarks/AesonMap.hs+56−39 benchmarks/AesonParse.hs+5−3 benchmarks/AesonTuples.hs+2−1 benchmarks/Auto/G/BigProduct.hs−33 benchmarks/Auto/G/BigRecord.hs−33 benchmarks/Auto/G/BigSum.hs−28 benchmarks/Auto/G/D.hs−44 benchmarks/Auto/T/BigProduct.hs−27 benchmarks/Auto/T/BigRecord.hs−27 benchmarks/Auto/T/BigSum.hs−22 benchmarks/Auto/T/D.hs−38 benchmarks/AutoCompare.hs−73 benchmarks/Compare.hs+5−10 benchmarks/Compare/BufferBuilder.hs+3−2 benchmarks/Compare/JsonBench.hs+10−18 benchmarks/Compare/JsonBuilder.hs+3−2 benchmarks/CompareWithJSON.hs+21−33 benchmarks/Dates.hs+9−10 benchmarks/Escape.hs−32 benchmarks/Issue673.hs−165 benchmarks/JsonParse.hs+2−3 benchmarks/Micro.hs+6−8 benchmarks/Options.hs+4−1 benchmarks/ReadFile.hs+2−2 benchmarks/Typed.hs+1−5 benchmarks/Typed/Common.hs+8−1 benchmarks/Typed/Generic.hs+25−27 benchmarks/Typed/Manual.hs+24−26 benchmarks/Typed/TH.hs+24−26 benchmarks/aeson-benchmarks.cabal+62−183 cabal.project−5 cbits/unescape_string.c+2−1 changelog.md+3−252 examples/Generic.hs+1−1 examples/Simplest.hs+1−1 examples/TemplateHaskell.hs+1−1 examples/Twitter.hs+2−4 examples/Twitter/Generic.hs+37−31 examples/Twitter/Manual.hs+136−3 examples/Twitter/Options.hs−10 examples/Twitter/TH.hs+19−7 ffi/Data/Aeson/Parser/UnescapeFFI.hs−52 include/incoherent-compat.h−7 pure/Data/Aeson/Parser/UnescapePure.hs−254 run-hlint.sh−7 stack-bench.yaml+6−10 stack-ffi-unescape.yaml−9 stack-lts12.yaml−15 stack-lts6.yaml+12 stack-nightly.yaml+7−6 tests/DataFamilies/Encoders.hs+2−2 tests/DataFamilies/Instances.hs+1−2 tests/DataFamilies/Properties.hs+5−6 tests/DataFamilies/Types.hs+2−2 tests/Encoders.hs+8−142 tests/ErrorMessages.hs−224 tests/Functions.hs+1−2 tests/Instances.hs+55−9 tests/JSONTestSuite/LICENSE−21 tests/JSONTestSuite/README.md−50 tests/JSONTestSuite/parsers/test-AppleJSONSerialization/bin/test-AppleJSONSerialization tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization.xcodeproj/project.pbxproj−260 tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test-AppleJSONSerialization.xcscheme−91 tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization/main.swift−34 tests/JSONTestSuite/parsers/test_Bash_JSON/JSON.sh−208 tests/JSONTestSuite/parsers/test_Freddy_20160830/bin/test_Freddy tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/project.pbxproj−300 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/project.xcworkspace/xcshareddata/test_Freddy.xcscmblueprint−30 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_Freddy.xcscheme−91 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSON.swift−95 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONDecodable.swift−177 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONEncodable.swift−83 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONEncodingDetector.swift−110 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONLiteralConvertible.swift−130 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONParser.swift−907 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONParsing.swift−126 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONSerializing.swift−43 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONSubscripting.swift−705 tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/main.swift−37 tests/JSONTestSuite/parsers/test_Freddy_20161018/bin/test_Freddy tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/project.pbxproj−300 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/project.xcworkspace/xcshareddata/test_Freddy.xcscmblueprint−30 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_Freddy.xcscheme−91 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSON.swift−98 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONDecodable.swift−186 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONEncodable.swift−83 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONEncodingDetector.swift−110 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONLiteralConvertible.swift−134 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONParser.swift−918 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONParsing.swift−126 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONSerializing.swift−54 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONSubscripting.swift−613 tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/main.swift−40 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/bin/test_Freddy_2_1_0 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/project.pbxproj−300 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/project.xcworkspace/xcshareddata/test_Freddy.xcscmblueprint−30 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_Freddy.xcscheme−91 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSON.swift−95 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONDecodable.swift−151 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONEncodable.swift−83 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONEncodingDetector.swift−110 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONLiteralConvertible.swift−130 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONParser.swift−903 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONParsing.swift−126 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONSerializing.swift−43 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONSubscripting.swift−643 tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/main.swift−37 tests/JSONTestSuite/parsers/test_JSONKit/JSONKit.h−251 tests/JSONTestSuite/parsers/test_JSONKit/JSONKit.m−3065 tests/JSONTestSuite/parsers/test_JSONKit/bin/test-JSONKit tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit.xcodeproj/project.pbxproj−252 tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test-JSONKit.xcscheme−91 tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit/main.m−73 tests/JSONTestSuite/parsers/test_Json.NET/Program.cs−46 tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/Newtonsoft.Json.dll tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/System.Runtime.Serialization.Primitives.dll tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/test_Json.NET.deps.json−49 tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/test_Json.NET.dll tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/test_Json.NET.pdb tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/test_Json.NET.runtimeconfig.json−8 tests/JSONTestSuite/parsers/test_Json.NET/project.json−21 tests/JSONTestSuite/parsers/test_Json.NET/project.lock.json−6741 tests/JSONTestSuite/parsers/test_Lua_JSON/JSON.lua−1451 tests/JSONTestSuite/parsers/test_Lua_JSON/test_JSON.lua−22 tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/bin/test_ObjCNSJSONSerializer tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer.xcodeproj/project.pbxproj−246 tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_ObjCNSJSONSerializer.xcscheme−97 tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer/a.out tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer/a.out.dSYM/Contents/Info.plist−20 tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer/a.out.dSYM/Contents/Resources/DWARF/a.out tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer/findings_dir/plot_data−1 tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer/main.m−32 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/Accessors.swift−255 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/DecimalNumber.swift−236 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/Decoder.swift−294 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/Encoder.swift−167 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/JSON.swift−170 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/JSONError.swift−1619 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/JSONObject.swift−215 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/ObjectiveC.swift−233 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/Parser.swift−674 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/bin/test_PMJSON tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON.xcodeproj/project.pbxproj−296 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_PMJSON.xcscheme−97 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON/main.swift−46 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/Accessors.swift−255 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/DecimalNumber.swift−236 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/Decoder.swift−502 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/Encoder.swift−215 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/JSON.swift−170 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/JSONError.swift−1619 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/JSONObject.swift−215 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/ObjectiveC.swift−331 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/Parser.swift−745 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/bin/test_PMJSON tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON.xcodeproj/project.pbxproj−296 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_PMJSON.xcscheme−97 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON/main.swift−46 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4.h−35 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4Parser.h−248 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4Parser.m−287 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamParser.h−131 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamParser.m−317 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamParserState.h−82 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamParserState.m−355 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamTokeniser.h−40 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamTokeniser.m−395 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamWriter.h−210 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamWriter.m−358 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamWriterState.h−69 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamWriterState.m−147 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4Writer.h−103 tests/JSONTestSuite/parsers/test_SBJSON/SBJson4Writer.m−102 tests/JSONTestSuite/parsers/test_SBJSON/bin/test_SBJSON tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/project.pbxproj−290 tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist−5 tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_SBJSON.xcscheme−91 tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON/main.m−38 tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/project.pbxproj−361 tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/project.xcworkspace/xcshareddata/STJSON.xcscmblueprint−30 tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/STJSON.xcscheme−91 tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/STJSONTests.xcscheme−56 tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−32 tests/JSONTestSuite/parsers/test_STJSON/STJSON/STJSONParser.swift−663 tests/JSONTestSuite/parsers/test_STJSON/STJSON/main.swift−47 tests/JSONTestSuite/parsers/test_STJSON/STJSONTests/Info.plist−22 tests/JSONTestSuite/parsers/test_STJSON/STJSONTests/STJSONTests.swift−92 tests/JSONTestSuite/parsers/test_STJSON/bin/STJSON tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Info.plist−563 tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/MacOS/Squeak tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/English.lproj/Localizable.strings−9 tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/English.lproj/MainMenu.nib tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/Squeak.icns tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakChanges.icns tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakGeneric.icns tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakImage.icns tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakPlugin.icns tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakProject.icns tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakScript.icns tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakSources.icns tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak5.1-16549-32bit.image tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/test_JSON.st−9 tests/JSONTestSuite/parsers/test_TouchJSON/bin/test_TouchJSON tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON.xcodeproj/project.pbxproj−262 tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_TouchJSON.xcscheme−97 tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON/CJSONDeserializer.h−96 tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON/CJSONDeserializer.m−1240 tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON/main.m−25 tests/JSONTestSuite/parsers/test_cJSON/bin/test-cJSON tests/JSONTestSuite/parsers/test_cJSON/cJSON.c−754 tests/JSONTestSuite/parsers/test_cJSON/cJSON.h−153 tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/project.pbxproj−257 tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist−5 tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test-cJSON.xcscheme−91 tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_cJSON/test-cJSON/main.c−69 tests/JSONTestSuite/parsers/test_ccan_json/bin/test_ccan tests/JSONTestSuite/parsers/test_ccan_json/json/_test/common.h−18 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_10.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_101.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_11.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_12.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_125.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_127.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_13.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_136.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_137.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_139.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_14.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_140.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_145.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_147.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_149.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_15.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_150.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_151.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_153.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_154.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_155.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_156.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_157.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_158.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_159.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_16.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_160.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_161.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_162.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_163.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_164.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_165.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_169.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_17.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_171.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_172.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_173.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_175.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_176.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_177.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_178.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_179.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_18.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_180.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_181.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_183.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_184.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_185.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_186.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_187.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_188.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_189.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_19.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_190.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_191.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_192.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_193.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_194.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_195.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_197.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_198.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_199.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_2.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_20.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_200.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_201.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_202.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_203.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_204.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_205.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_206.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_207.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_208.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_209.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_21.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_210.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_211.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_212.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_213.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_214.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_216.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_217.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_218.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_219.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_22.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_220.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_221.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_222.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_223.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_23.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_24.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_25.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_26.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_27.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_28.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_29.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_3.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_30.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_31.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_32.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_33.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_34.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_35.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_36.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_37.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_4.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_40.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_44.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_46.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_5.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_54.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_55.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_59.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_6.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_63.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_64.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_66.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_69.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_7.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_77.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_78.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_79.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_8.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_80.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_81.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_82.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_83.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_85.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_86.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_87.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_9.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_91.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_100.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_102.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_103.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_104.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_105.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_106.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_107.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_108.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_109.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_110.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_111.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_112.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_113.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_114.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_115.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_116.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_117.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_118.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_119.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_120.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_121.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_122.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_123.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_124.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_126.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_128.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_129.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_130.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_131.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_132.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_133.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_134.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_135.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_138.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_141.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_142.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_143.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_144.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_146.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_148.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_152.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_166.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_167.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_168.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_170.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_174.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_182.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_196.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_215.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_38.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_39.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_41.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_42.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_43.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_45.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_47.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_48.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_49.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_50.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_51.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_52.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_53.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_56.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_57.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_58.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_60.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_61.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_62.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_65.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_67.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_68.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_70.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_71.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_72.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_73.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_74.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_75.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_76.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_84.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_88.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_89.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_90.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_92.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_93.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_94.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_95.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_96.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_97.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_98.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_99.json−1 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/run-construction.c−191 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/run-decode-encode.c−77 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/run-stringify.c−108 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/run-validate.c−49 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/test-strings−224 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/test-strings-reencoded−90 tests/JSONTestSuite/parsers/test_ccan_json/json/_test/x.py−21 tests/JSONTestSuite/parsers/test_ccan_json/json/json.c−1381 tests/JSONTestSuite/parsers/test_ccan_json/json/json.h−117 tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan.xcodeproj/project.pbxproj−262 tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_ccan.xcscheme−91 tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan/main.c−44 tests/JSONTestSuite/parsers/test_dkjson.lua−25 tests/JSONTestSuite/parsers/test_go/test_json tests/JSONTestSuite/parsers/test_go/test_json.go−30 tests/JSONTestSuite/parsers/test_haskell-aeson/.gitignore−1 tests/JSONTestSuite/parsers/test_haskell-aeson/package.yaml−12 tests/JSONTestSuite/parsers/test_haskell-aeson/src/Main.hs−29 tests/JSONTestSuite/parsers/test_haskell-aeson/stack.yaml−1 tests/JSONTestSuite/parsers/test_haskell-aeson/testaeson−8 tests/JSONTestSuite/parsers/test_haskell-aeson/testaeson.cabal−21 tests/JSONTestSuite/parsers/test_jansson/bin/test_jansson tests/JSONTestSuite/parsers/test_jansson/dump.c−467 tests/JSONTestSuite/parsers/test_jansson/error.c−63 tests/JSONTestSuite/parsers/test_jansson/hashtable.c−356 tests/JSONTestSuite/parsers/test_jansson/hashtable.h−184 tests/JSONTestSuite/parsers/test_jansson/hashtable_seed.c−277 tests/JSONTestSuite/parsers/test_jansson/jansson.h−298 tests/JSONTestSuite/parsers/test_jansson/jansson_config.h−43 tests/JSONTestSuite/parsers/test_jansson/jansson_private.h−109 tests/JSONTestSuite/parsers/test_jansson/load.c−1110 tests/JSONTestSuite/parsers/test_jansson/lookup3.h−381 tests/JSONTestSuite/parsers/test_jansson/memory.c−69 tests/JSONTestSuite/parsers/test_jansson/pack_unpack.c−871 tests/JSONTestSuite/parsers/test_jansson/strbuffer.c−111 tests/JSONTestSuite/parsers/test_jansson/strbuffer.h−34 tests/JSONTestSuite/parsers/test_jansson/strconv.c−145 tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/project.pbxproj−309 tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist−5 tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_jansson.xcscheme−91 tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_jansson/test_jansson/main.c−208 tests/JSONTestSuite/parsers/test_jansson/utf.c−187 tests/JSONTestSuite/parsers/test_jansson/utf.h−27 tests/JSONTestSuite/parsers/test_jansson/value.c−1048 tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/META-INF/MANIFEST.MF−3 tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/README.txt−5 tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/TestJSONParsing.class tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/TestJSONParsing.jar tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/TestJSONParsing.java−40 tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/com.leastfixedpoint.json-1.0.jar tests/JSONTestSuite/parsers/test_java_gson_2_7/META-INF/MANIFEST.MF−3 tests/JSONTestSuite/parsers/test_java_gson_2_7/README.txt−5 tests/JSONTestSuite/parsers/test_java_gson_2_7/TestJSONParsing.class tests/JSONTestSuite/parsers/test_java_gson_2_7/TestJSONParsing.jar tests/JSONTestSuite/parsers/test_java_gson_2_7/TestJSONParsing.java−51 tests/JSONTestSuite/parsers/test_java_gson_2_7/gson-2.7.jar tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/META-INF/MANIFEST.MF−3 tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/README.txt−5 tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/TestJSONParsing.class tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/TestJSONParsing.jar tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/TestJSONParsing.java−48 tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/jackson-annotations-2.2.3.jar tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/jackson-core-2.8.4.jar tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/jackson-databind-2.3.1.jar tests/JSONTestSuite/parsers/test_java_nanojson_1_0/META-INF/MANIFEST.MF−3 tests/JSONTestSuite/parsers/test_java_nanojson_1_0/README.txt−5 tests/JSONTestSuite/parsers/test_java_nanojson_1_0/TestJSONParsing.class tests/JSONTestSuite/parsers/test_java_nanojson_1_0/TestJSONParsing.jar tests/JSONTestSuite/parsers/test_java_nanojson_1_0/TestJSONParsing.java−45 tests/JSONTestSuite/parsers/test_java_nanojson_1_0/nanojson-1.0.jar tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/META-INF/MANIFEST.MF−3 tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/README.txt−3 tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/TestJSONParsing.class tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/TestJSONParsing.jar tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/TestJSONParsing.java−43 tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/json-simple-1.1.1.jar tests/JSONTestSuite/parsers/test_jsmn/bin/test_jsmn tests/JSONTestSuite/parsers/test_jsmn/jsmn.c−311 tests/JSONTestSuite/parsers/test_jsmn/jsmn.h−76 tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/project.pbxproj−253 tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist−23 tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_jsmn.xcscheme−101 tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn/main.c−50 tests/JSONTestSuite/parsers/test_json-jq.py−34 tests/JSONTestSuite/parsers/test_json-parser/bin/test_json-parser tests/JSONTestSuite/parsers/test_json-parser/test_json-parser.xcodeproj/project.pbxproj−258 tests/JSONTestSuite/parsers/test_json-parser/test_json-parser.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_json-parser/test_json-parser.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_json-parser/test_json-parser.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_json-parser.xcscheme−91 tests/JSONTestSuite/parsers/test_json-parser/test_json-parser.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_json-parser/test_json-parser/json.c−1011 tests/JSONTestSuite/parsers/test_json-parser/test_json-parser/json.h−283 tests/JSONTestSuite/parsers/test_json-parser/test_json-parser/main.c−66 tests/JSONTestSuite/parsers/test_json-rust-serde_json/rj/.gitignore−2 tests/JSONTestSuite/parsers/test_json-rust-serde_json/rj/Cargo.toml−7 tests/JSONTestSuite/parsers/test_json-rust-serde_json/rj/README−2 tests/JSONTestSuite/parsers/test_json-rust-serde_json/rj/src/main.rs−30 tests/JSONTestSuite/parsers/test_json-rust/Cargo.lock−14 tests/JSONTestSuite/parsers/test_json-rust/Cargo.toml−7 tests/JSONTestSuite/parsers/test_json-rust/README−2 tests/JSONTestSuite/parsers/test_json-rust/src/main.rs−42 tests/JSONTestSuite/parsers/test_json-rust/target/debug/.cargo-lock tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/json-74a82b4ec4439e90/dep-lib-json tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/json-74a82b4ec4439e90/lib-json−1 tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/json-74a82b4ec4439e90/lib-json.json−1 tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-b5d63a9d8da2968e/bin-tj−1 tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-b5d63a9d8da2968e/bin-tj.json−1 tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-b5d63a9d8da2968e/dep-bin-tj tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bb890ae6f101bb25/bin-tj−1 tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bb890ae6f101bb25/bin-tj.json−1 tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bb890ae6f101bb25/dep-bin-tj tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bf24d0bdc8d0f4d6/bin-tj−1 tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bf24d0bdc8d0f4d6/bin-tj.json−1 tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bf24d0bdc8d0f4d6/dep-bin-tj tests/JSONTestSuite/parsers/test_json-rust/target/debug/deps/libjson-6bbf4c11dd6d7c25.rlib tests/JSONTestSuite/parsers/test_json-rust/target/debug/tj tests/JSONTestSuite/parsers/test_json-rust/target/debug/tj.dSYM/Contents/Info.plist−20 tests/JSONTestSuite/parsers/test_json-rust/target/debug/tj.dSYM/Contents/Resources/DWARF/tj tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/Cargo.lock−14 tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/Cargo.toml−7 tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/README−2 tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/src/main.rs−32 tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.cargo-lock tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-8f8b750d20f3bf10/bin-rj−1 tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-8f8b750d20f3bf10/bin-rj.json−1 tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-8f8b750d20f3bf10/dep-bin-rj tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-da0f8f63b87cf531/bin-rj−1 tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-da0f8f63b87cf531/bin-rj.json−1 tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-da0f8f63b87cf531/dep-bin-rj tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rustc-serialize-80c565222c5ccdbb/dep-lib-rustc-serialize tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rustc-serialize-80c565222c5ccdbb/lib-rustc-serialize−1 tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rustc-serialize-80c565222c5ccdbb/lib-rustc-serialize.json−1 tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/deps/librustc_serialize-3561541d79c18212.rlib tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/rj tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/rj.dSYM/Contents/Info.plist−20 tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/rj.dSYM/Contents/Resources/DWARF/rj tests/JSONTestSuite/parsers/test_json.cr−19 tests/JSONTestSuite/parsers/test_json.js−13 tests/JSONTestSuite/parsers/test_json.php−21 tests/JSONTestSuite/parsers/test_json.pl−32 tests/JSONTestSuite/parsers/test_json.py−39 tests/JSONTestSuite/parsers/test_json.rb−23 tests/JSONTestSuite/parsers/test_jsonChecker/bin/jsonChecker tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/JSON_checker.c−400 tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/JSON_checker.h−13 tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker.xcodeproj/project.pbxproj−253 tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/jsonChecker.xcscheme−91 tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker/main.c−53 tests/JSONTestSuite/parsers/test_jsonChecker2/FSM.rtf−103 tests/JSONTestSuite/parsers/test_jsonChecker2/bin/jsonChecker2 tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/JSON_checker.c−402 tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/JSON_checker.h−13 tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker/main.c−53 tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker2.xcodeproj/project.pbxproj−253 tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker2.xcodeproj/project.xcworkspace/contents.xcworkspacedata−7 tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker2.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker2.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/jsonChecker.xcscheme−97 tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker2.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plist−22 tests/JSONTestSuite/parsers/test_json_re.rb−33 tests/JSONTestSuite/parsers/test_json_xs.pl−28 tests/JSONTestSuite/parsers/test_jsonlite.r−7 tests/JSONTestSuite/parsers/test_oj_compat.rb−25 tests/JSONTestSuite/parsers/test_oj_strict.rb−25 tests/JSONTestSuite/parsers/test_qt/build.sh−4 tests/JSONTestSuite/parsers/test_qt/main.cpp−25 tests/JSONTestSuite/parsers/test_qt/test_qt.pro−12 tests/JSONTestSuite/parsers/test_rjson.r−7 tests/JSONTestSuite/parsers/test_yajl.rb−24 tests/JSONTestSuite/results/logs.txt−2048 tests/JSONTestSuite/results/parsing.html−2816 tests/JSONTestSuite/results/parsing_pruned.html−2661 tests/JSONTestSuite/results/pruned_results.png tests/JSONTestSuite/results/style.css−89 tests/JSONTestSuite/results/transform.html−1492 tests/JSONTestSuite/run_tests.py−673 tests/JSONTestSuite/test_parsing/i_object_key_lone_2nd_surrogate.json−1 tests/JSONTestSuite/test_parsing/i_string_1st_surrogate_but_2nd_missing.json−1 tests/JSONTestSuite/test_parsing/i_string_1st_valid_surrogate_2nd_invalid.json−1 tests/JSONTestSuite/test_parsing/i_string_UTF-16LE_with_BOM.json tests/JSONTestSuite/test_parsing/i_string_UTF-8_invalid_sequence.json−1 tests/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_and_escape_valid.json−1 tests/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_pair.json−1 tests/JSONTestSuite/test_parsing/i_string_incomplete_surrogates_escape_valid.json−1 tests/JSONTestSuite/test_parsing/i_string_invalid_lonely_surrogate.json−1 tests/JSONTestSuite/test_parsing/i_string_invalid_surrogate.json−1 tests/JSONTestSuite/test_parsing/i_string_inverted_surrogates_U+1D11E.json−1 tests/JSONTestSuite/test_parsing/i_string_lone_second_surrogate.json−1 tests/JSONTestSuite/test_parsing/i_string_not_in_unicode_range.json−1 tests/JSONTestSuite/test_parsing/i_string_truncated-utf-8.json−1 tests/JSONTestSuite/test_parsing/i_string_unicode_U+10FFFE_nonchar.json−1 tests/JSONTestSuite/test_parsing/i_string_unicode_U+1FFFE_nonchar.json−1 tests/JSONTestSuite/test_parsing/i_string_unicode_U+FDD0_nonchar.json−1 tests/JSONTestSuite/test_parsing/i_string_unicode_U+FFFE_nonchar.json−1 tests/JSONTestSuite/test_parsing/i_structure_500_nested_arrays.json−1 tests/JSONTestSuite/test_parsing/i_structure_UTF-8_BOM_empty_object.json−1 tests/JSONTestSuite/test_parsing/n_array_1_true_without_comma.json−1 tests/JSONTestSuite/test_parsing/n_array_a_invalid_utf8.json−1 tests/JSONTestSuite/test_parsing/n_array_colon_instead_of_comma.json−1 tests/JSONTestSuite/test_parsing/n_array_comma_after_close.json−1 tests/JSONTestSuite/test_parsing/n_array_comma_and_number.json−1 tests/JSONTestSuite/test_parsing/n_array_double_comma.json−1 tests/JSONTestSuite/test_parsing/n_array_double_extra_comma.json−1 tests/JSONTestSuite/test_parsing/n_array_extra_close.json−1 tests/JSONTestSuite/test_parsing/n_array_extra_comma.json−1 tests/JSONTestSuite/test_parsing/n_array_incomplete.json−1 tests/JSONTestSuite/test_parsing/n_array_incomplete_invalid_value.json−1 tests/JSONTestSuite/test_parsing/n_array_inner_array_no_comma.json−1 tests/JSONTestSuite/test_parsing/n_array_invalid_utf8.json−1 tests/JSONTestSuite/test_parsing/n_array_items_separated_by_semicolon.json−1 tests/JSONTestSuite/test_parsing/n_array_just_comma.json−1 tests/JSONTestSuite/test_parsing/n_array_just_minus.json−1 tests/JSONTestSuite/test_parsing/n_array_missing_value.json−1 tests/JSONTestSuite/test_parsing/n_array_newlines_unclosed.json−3 tests/JSONTestSuite/test_parsing/n_array_number_and_comma.json−1 tests/JSONTestSuite/test_parsing/n_array_number_and_several_commas.json−1 tests/JSONTestSuite/test_parsing/n_array_spaces_vertical_tab_formfeed.json−1 tests/JSONTestSuite/test_parsing/n_array_star_inside.json−1 tests/JSONTestSuite/test_parsing/n_array_unclosed.json−1 tests/JSONTestSuite/test_parsing/n_array_unclosed_trailing_comma.json−1 tests/JSONTestSuite/test_parsing/n_array_unclosed_with_new_lines.json−3 tests/JSONTestSuite/test_parsing/n_array_unclosed_with_object_inside.json−1 tests/JSONTestSuite/test_parsing/n_incomplete_false.json−1 tests/JSONTestSuite/test_parsing/n_incomplete_null.json−1 tests/JSONTestSuite/test_parsing/n_incomplete_true.json−1 tests/JSONTestSuite/test_parsing/n_number_++.json−1 tests/JSONTestSuite/test_parsing/n_number_+1.json−1 tests/JSONTestSuite/test_parsing/n_number_+Inf.json−1 tests/JSONTestSuite/test_parsing/n_number_-01.json−1 tests/JSONTestSuite/test_parsing/n_number_-1.0..json−1 tests/JSONTestSuite/test_parsing/n_number_-2..json−1 tests/JSONTestSuite/test_parsing/n_number_-NaN.json−1 tests/JSONTestSuite/test_parsing/n_number_.-1.json−1 tests/JSONTestSuite/test_parsing/n_number_.2e-3.json−1 tests/JSONTestSuite/test_parsing/n_number_0.1.2.json−1 tests/JSONTestSuite/test_parsing/n_number_0.3e+.json−1 tests/JSONTestSuite/test_parsing/n_number_0.3e.json−1 tests/JSONTestSuite/test_parsing/n_number_0.e1.json−1 tests/JSONTestSuite/test_parsing/n_number_0_capital_E+.json−1 tests/JSONTestSuite/test_parsing/n_number_0_capital_E.json−1 tests/JSONTestSuite/test_parsing/n_number_0e+.json−1 tests/JSONTestSuite/test_parsing/n_number_0e.json−1 tests/JSONTestSuite/test_parsing/n_number_1.0e+.json−1 tests/JSONTestSuite/test_parsing/n_number_1.0e-.json−1 tests/JSONTestSuite/test_parsing/n_number_1.0e.json−1 tests/JSONTestSuite/test_parsing/n_number_1_000.json−1 tests/JSONTestSuite/test_parsing/n_number_1eE2.json−1 tests/JSONTestSuite/test_parsing/n_number_2.e+3.json−1 tests/JSONTestSuite/test_parsing/n_number_2.e-3.json−1 tests/JSONTestSuite/test_parsing/n_number_2.e3.json−1 tests/JSONTestSuite/test_parsing/n_number_9.e+.json−1 tests/JSONTestSuite/test_parsing/n_number_Inf.json−1 tests/JSONTestSuite/test_parsing/n_number_NaN.json−1 tests/JSONTestSuite/test_parsing/n_number_U+FF11_fullwidth_digit_one.json−1 tests/JSONTestSuite/test_parsing/n_number_expression.json−1 tests/JSONTestSuite/test_parsing/n_number_hex_1_digit.json−1 tests/JSONTestSuite/test_parsing/n_number_hex_2_digits.json−1 tests/JSONTestSuite/test_parsing/n_number_infinity.json−1 tests/JSONTestSuite/test_parsing/n_number_invalid+-.json−1 tests/JSONTestSuite/test_parsing/n_number_invalid-negative-real.json−1 tests/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-bigger-int.json−1 tests/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-exponent.json−1 tests/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-int.json−1 tests/JSONTestSuite/test_parsing/n_number_minus_infinity.json−1 tests/JSONTestSuite/test_parsing/n_number_minus_sign_with_trailing_garbage.json−1 tests/JSONTestSuite/test_parsing/n_number_minus_space_1.json−1 tests/JSONTestSuite/test_parsing/n_number_neg_int_starting_with_zero.json−1 tests/JSONTestSuite/test_parsing/n_number_neg_real_without_int_part.json−1 tests/JSONTestSuite/test_parsing/n_number_neg_with_garbage_at_end.json−1 tests/JSONTestSuite/test_parsing/n_number_real_garbage_after_e.json−1 tests/JSONTestSuite/test_parsing/n_number_real_with_invalid_utf8_after_e.json−1 tests/JSONTestSuite/test_parsing/n_number_real_without_fractional_part.json−1 tests/JSONTestSuite/test_parsing/n_number_starting_with_dot.json−1 tests/JSONTestSuite/test_parsing/n_number_then_00.json tests/JSONTestSuite/test_parsing/n_number_with_alpha.json−1 tests/JSONTestSuite/test_parsing/n_number_with_alpha_char.json−1 tests/JSONTestSuite/test_parsing/n_number_with_leading_zero.json−1 tests/JSONTestSuite/test_parsing/n_object_bad_value.json−1 tests/JSONTestSuite/test_parsing/n_object_bracket_key.json−1 tests/JSONTestSuite/test_parsing/n_object_comma_instead_of_colon.json−1 tests/JSONTestSuite/test_parsing/n_object_double_colon.json−1 tests/JSONTestSuite/test_parsing/n_object_emoji.json−1 tests/JSONTestSuite/test_parsing/n_object_garbage_at_end.json−1 tests/JSONTestSuite/test_parsing/n_object_key_with_single_quotes.json−1 tests/JSONTestSuite/test_parsing/n_object_missing_colon.json−1 tests/JSONTestSuite/test_parsing/n_object_missing_key.json−1 tests/JSONTestSuite/test_parsing/n_object_missing_semicolon.json−1 tests/JSONTestSuite/test_parsing/n_object_missing_value.json−1 tests/JSONTestSuite/test_parsing/n_object_no-colon.json−1 tests/JSONTestSuite/test_parsing/n_object_non_string_key.json−1 tests/JSONTestSuite/test_parsing/n_object_non_string_key_but_huge_number_instead.json−1 tests/JSONTestSuite/test_parsing/n_object_pi_in_key_and_trailing_comma.json−1 tests/JSONTestSuite/test_parsing/n_object_repeated_null_null.json−1 tests/JSONTestSuite/test_parsing/n_object_several_trailing_commas.json−1 tests/JSONTestSuite/test_parsing/n_object_single_quote.json−1 tests/JSONTestSuite/test_parsing/n_object_trailing_comma.json−1 tests/JSONTestSuite/test_parsing/n_object_trailing_comment.json−1 tests/JSONTestSuite/test_parsing/n_object_trailing_comment_open.json−1 tests/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open.json−1 tests/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open_incomplete.json−1 tests/JSONTestSuite/test_parsing/n_object_two_commas_in_a_row.json−1 tests/JSONTestSuite/test_parsing/n_object_unquoted_key.json−1 tests/JSONTestSuite/test_parsing/n_object_unterminated-value.json−1 tests/JSONTestSuite/test_parsing/n_object_with_single_string.json−1 tests/JSONTestSuite/test_parsing/n_object_with_trailing_garbage.json−1 tests/JSONTestSuite/test_parsing/n_single_space.json−1 tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u.json−1 tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u1.json−1 tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u1x.json−1 tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape.json−1 tests/JSONTestSuite/test_parsing/n_string_UTF8_surrogate_U+D800.json−1 tests/JSONTestSuite/test_parsing/n_string_accentuated_char_no_quotes.json−1 tests/JSONTestSuite/test_parsing/n_string_backslash_00.json tests/JSONTestSuite/test_parsing/n_string_escape_x.json−1 tests/JSONTestSuite/test_parsing/n_string_escaped_backslash_bad.json−1 tests/JSONTestSuite/test_parsing/n_string_escaped_ctrl_char_tab.json−1 tests/JSONTestSuite/test_parsing/n_string_escaped_emoji.json−1 tests/JSONTestSuite/test_parsing/n_string_incomplete_escape.json−1 tests/JSONTestSuite/test_parsing/n_string_incomplete_escaped_character.json−1 tests/JSONTestSuite/test_parsing/n_string_incomplete_surrogate.json−1 tests/JSONTestSuite/test_parsing/n_string_incomplete_surrogate_escape_invalid.json−1 tests/JSONTestSuite/test_parsing/n_string_invalid-utf-8-in-escape.json−1 tests/JSONTestSuite/test_parsing/n_string_invalid_backslash_esc.json−1 tests/JSONTestSuite/test_parsing/n_string_invalid_unicode_escape.json−1 tests/JSONTestSuite/test_parsing/n_string_invalid_utf-8.json−1 tests/JSONTestSuite/test_parsing/n_string_invalid_utf8_after_escape.json−1 tests/JSONTestSuite/test_parsing/n_string_iso_latin_1.json−1 tests/JSONTestSuite/test_parsing/n_string_leading_uescaped_thinspace.json−1 tests/JSONTestSuite/test_parsing/n_string_lone_utf8_continuation_byte.json−1 tests/JSONTestSuite/test_parsing/n_string_no_quotes_with_bad_escape.json−1 tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_2_bytes.json−1 tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_6_bytes.json−1 tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_6_bytes_null.json−1 tests/JSONTestSuite/test_parsing/n_string_single_doublequote.json−1 tests/JSONTestSuite/test_parsing/n_string_single_quote.json−1 tests/JSONTestSuite/test_parsing/n_string_single_string_no_double_quotes.json−1 tests/JSONTestSuite/test_parsing/n_string_start_escape_unclosed.json−1 tests/JSONTestSuite/test_parsing/n_string_unescaped_crtl_char.json tests/JSONTestSuite/test_parsing/n_string_unescaped_newline.json−2 tests/JSONTestSuite/test_parsing/n_string_unescaped_tab.json−1 tests/JSONTestSuite/test_parsing/n_string_unicode_CapitalU.json−1 tests/JSONTestSuite/test_parsing/n_string_with_trailing_garbage.json−1 tests/JSONTestSuite/test_parsing/n_structure_..json−1 tests/JSONTestSuite/test_parsing/n_structure_100000_opening_arrays.json−1 tests/JSONTestSuite/test_parsing/n_structure_U+2060_word_joined.json−1 tests/JSONTestSuite/test_parsing/n_structure_UTF8_BOM_no_data.json−1 tests/JSONTestSuite/test_parsing/n_structure_array_trailing_garbage.json−1 tests/JSONTestSuite/test_parsing/n_structure_array_with_extra_array_close.json−1 tests/JSONTestSuite/test_parsing/n_structure_array_with_unclosed_string.json−1 tests/JSONTestSuite/test_parsing/n_structure_ascii-unicode-identifier.json−1 tests/JSONTestSuite/test_parsing/n_structure_capitalized_True.json−1 tests/JSONTestSuite/test_parsing/n_structure_close_unopened_array.json−1 tests/JSONTestSuite/test_parsing/n_structure_comma_instead_of_closing_brace.json−1 tests/JSONTestSuite/test_parsing/n_structure_double_array.json−1 tests/JSONTestSuite/test_parsing/n_structure_end_array.json−1 tests/JSONTestSuite/test_parsing/n_structure_incomplete_UTF8_BOM.json−1 tests/JSONTestSuite/test_parsing/n_structure_lone-invalid-utf-8.json−1 tests/JSONTestSuite/test_parsing/n_structure_lone-open-bracket.json−1 tests/JSONTestSuite/test_parsing/n_structure_no_data.json tests/JSONTestSuite/test_parsing/n_structure_null-byte-outside-string.json tests/JSONTestSuite/test_parsing/n_structure_null.json−1 tests/JSONTestSuite/test_parsing/n_structure_number_with_trailing_garbage.json−1 tests/JSONTestSuite/test_parsing/n_structure_object_followed_by_closing_object.json−1 tests/JSONTestSuite/test_parsing/n_structure_object_unclosed_no_value.json−1 tests/JSONTestSuite/test_parsing/n_structure_object_with_comment.json−1 tests/JSONTestSuite/test_parsing/n_structure_object_with_trailing_garbage.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_array_apostrophe.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_array_comma.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_array_object.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_array_open_object.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_array_open_string.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_array_string.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_object.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_object_close_array.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_object_comma.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_object_open_array.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_object_open_string.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_object_string_with_apostrophes.json−1 tests/JSONTestSuite/test_parsing/n_structure_open_open.json−1 tests/JSONTestSuite/test_parsing/n_structure_single_point.json−1 tests/JSONTestSuite/test_parsing/n_structure_single_star.json−1 tests/JSONTestSuite/test_parsing/n_structure_trailing_#.json−1 tests/JSONTestSuite/test_parsing/n_structure_uescaped_LF_before_string.json−1 tests/JSONTestSuite/test_parsing/n_structure_unclosed_array.json−1 tests/JSONTestSuite/test_parsing/n_structure_unclosed_array_partial_null.json−1 tests/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_false.json−1 tests/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_true.json−1 tests/JSONTestSuite/test_parsing/n_structure_unclosed_object.json−1 tests/JSONTestSuite/test_parsing/n_structure_unicode-identifier.json−1 tests/JSONTestSuite/test_parsing/n_structure_whitespace_U+2060_word_joiner.json−1 tests/JSONTestSuite/test_parsing/n_structure_whitespace_formfeed.json−1 tests/JSONTestSuite/test_parsing/y_array_arraysWithSpaces.json−1 tests/JSONTestSuite/test_parsing/y_array_empty-string.json−1 tests/JSONTestSuite/test_parsing/y_array_empty.json−1 tests/JSONTestSuite/test_parsing/y_array_ending_with_newline.json−1 tests/JSONTestSuite/test_parsing/y_array_false.json−1 tests/JSONTestSuite/test_parsing/y_array_heterogeneous.json−1 tests/JSONTestSuite/test_parsing/y_array_null.json−1 tests/JSONTestSuite/test_parsing/y_array_with_1_and_newline.json−2 tests/JSONTestSuite/test_parsing/y_array_with_leading_space.json−1 tests/JSONTestSuite/test_parsing/y_array_with_several_null.json−1 tests/JSONTestSuite/test_parsing/y_array_with_trailing_space.json−1 tests/JSONTestSuite/test_parsing/y_number.json−1 tests/JSONTestSuite/test_parsing/y_number_0e+1.json−1 tests/JSONTestSuite/test_parsing/y_number_0e1.json−1 tests/JSONTestSuite/test_parsing/y_number_after_space.json−1 tests/JSONTestSuite/test_parsing/y_number_double_close_to_zero.json−1 tests/JSONTestSuite/test_parsing/y_number_double_huge_neg_exp.json−1 tests/JSONTestSuite/test_parsing/y_number_huge_exp.json−1 tests/JSONTestSuite/test_parsing/y_number_int_with_exp.json−1 tests/JSONTestSuite/test_parsing/y_number_minus_zero.json−1 tests/JSONTestSuite/test_parsing/y_number_neg_int_huge_exp.json−1 tests/JSONTestSuite/test_parsing/y_number_negative_int.json−1 tests/JSONTestSuite/test_parsing/y_number_negative_one.json−1 tests/JSONTestSuite/test_parsing/y_number_negative_zero.json−1 tests/JSONTestSuite/test_parsing/y_number_pos_double_huge_exp.json−1 tests/JSONTestSuite/test_parsing/y_number_real_capital_e.json−1 tests/JSONTestSuite/test_parsing/y_number_real_capital_e_neg_exp.json−1 tests/JSONTestSuite/test_parsing/y_number_real_capital_e_pos_exp.json−1 tests/JSONTestSuite/test_parsing/y_number_real_exponent.json−1 tests/JSONTestSuite/test_parsing/y_number_real_fraction_exponent.json−1 tests/JSONTestSuite/test_parsing/y_number_real_neg_exp.json−1 tests/JSONTestSuite/test_parsing/y_number_real_neg_overflow.json−1 tests/JSONTestSuite/test_parsing/y_number_real_pos_exponent.json−1 tests/JSONTestSuite/test_parsing/y_number_real_pos_overflow.json−1 tests/JSONTestSuite/test_parsing/y_number_real_underflow.json−1 tests/JSONTestSuite/test_parsing/y_number_simple_int.json−1 tests/JSONTestSuite/test_parsing/y_number_simple_real.json−1 tests/JSONTestSuite/test_parsing/y_number_too_big_neg_int.json−1 tests/JSONTestSuite/test_parsing/y_number_too_big_pos_int.json−1 tests/JSONTestSuite/test_parsing/y_number_very_big_negative_int.json−1 tests/JSONTestSuite/test_parsing/y_object.json−1 tests/JSONTestSuite/test_parsing/y_object_basic.json−1 tests/JSONTestSuite/test_parsing/y_object_duplicated_key.json−1 tests/JSONTestSuite/test_parsing/y_object_duplicated_key_and_value.json−1 tests/JSONTestSuite/test_parsing/y_object_empty.json−1 tests/JSONTestSuite/test_parsing/y_object_empty_key.json−1 tests/JSONTestSuite/test_parsing/y_object_escaped_null_in_key.json−1 tests/JSONTestSuite/test_parsing/y_object_extreme_numbers.json−1 tests/JSONTestSuite/test_parsing/y_object_long_strings.json−1 tests/JSONTestSuite/test_parsing/y_object_simple.json−1 tests/JSONTestSuite/test_parsing/y_object_string_unicode.json−1 tests/JSONTestSuite/test_parsing/y_object_with_newlines.json−3 tests/JSONTestSuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json−1 tests/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pair.json−1 tests/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pairs.json−1 tests/JSONTestSuite/test_parsing/y_string_allowed_escapes.json−1 tests/JSONTestSuite/test_parsing/y_string_backslash_and_u_escaped_zero.json−1 tests/JSONTestSuite/test_parsing/y_string_backslash_doublequotes.json−1 tests/JSONTestSuite/test_parsing/y_string_comments.json−1 tests/JSONTestSuite/test_parsing/y_string_double_escape_a.json−1 tests/JSONTestSuite/test_parsing/y_string_double_escape_n.json−1 tests/JSONTestSuite/test_parsing/y_string_escaped_control_character.json−1 tests/JSONTestSuite/test_parsing/y_string_escaped_noncharacter.json−1 tests/JSONTestSuite/test_parsing/y_string_in_array.json−1 tests/JSONTestSuite/test_parsing/y_string_in_array_with_leading_space.json−1 tests/JSONTestSuite/test_parsing/y_string_last_surrogates_1_and_2.json−1 tests/JSONTestSuite/test_parsing/y_string_newline_uescaped.json−1 tests/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json−1 tests/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.json−1 tests/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json−1 tests/JSONTestSuite/test_parsing/y_string_null_escape.json−1 tests/JSONTestSuite/test_parsing/y_string_one-byte-utf-8.json−1 tests/JSONTestSuite/test_parsing/y_string_pi.json−1 tests/JSONTestSuite/test_parsing/y_string_simple_ascii.json−1 tests/JSONTestSuite/test_parsing/y_string_space.json−1 tests/JSONTestSuite/test_parsing/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json−1 tests/JSONTestSuite/test_parsing/y_string_three-byte-utf-8.json−1 tests/JSONTestSuite/test_parsing/y_string_two-byte-utf-8.json−1 tests/JSONTestSuite/test_parsing/y_string_u+2028_line_sep.json−1 tests/JSONTestSuite/test_parsing/y_string_u+2029_par_sep.json−1 tests/JSONTestSuite/test_parsing/y_string_uEscape.json−1 tests/JSONTestSuite/test_parsing/y_string_unescaped_char_delete.json−1 tests/JSONTestSuite/test_parsing/y_string_unicode.json−1 tests/JSONTestSuite/test_parsing/y_string_unicodeEscapedBackslash.json−1 tests/JSONTestSuite/test_parsing/y_string_unicode_2.json−1 tests/JSONTestSuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json−1 tests/JSONTestSuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json−1 tests/JSONTestSuite/test_parsing/y_string_unicode_escaped_double_quote.json−1 tests/JSONTestSuite/test_parsing/y_string_utf16BE_no_BOM.json tests/JSONTestSuite/test_parsing/y_string_utf16LE_no_BOM.json tests/JSONTestSuite/test_parsing/y_string_utf8.json−1 tests/JSONTestSuite/test_parsing/y_string_with_del_character.json−1 tests/JSONTestSuite/test_parsing/y_structure_lonely_false.json−1 tests/JSONTestSuite/test_parsing/y_structure_lonely_int.json−1 tests/JSONTestSuite/test_parsing/y_structure_lonely_negative_real.json−1 tests/JSONTestSuite/test_parsing/y_structure_lonely_null.json−1 tests/JSONTestSuite/test_parsing/y_structure_lonely_string.json−1 tests/JSONTestSuite/test_parsing/y_structure_lonely_true.json−1 tests/JSONTestSuite/test_parsing/y_structure_string_empty.json−1 tests/JSONTestSuite/test_parsing/y_structure_trailing_newline.json−1 tests/JSONTestSuite/test_parsing/y_structure_true_in_array.json−1 tests/JSONTestSuite/test_parsing/y_structure_whitespace_array.json−1 tests/JSONTestSuite/test_transform/number_1.0.json−1 tests/JSONTestSuite/test_transform/number_1.000000000000000005.json−1 tests/JSONTestSuite/test_transform/number_1000000000000000.json−1 tests/JSONTestSuite/test_transform/number_10000000000000000999.json−1 tests/JSONTestSuite/test_transform/number_1e-999.json−1 tests/JSONTestSuite/test_transform/number_1e6.json−1 tests/JSONTestSuite/test_transform/object_key_nfc_nfd.json−1 tests/JSONTestSuite/test_transform/object_key_nfd_nfc.json−1 tests/JSONTestSuite/test_transform/object_same_key_different_values.json−1 tests/JSONTestSuite/test_transform/object_same_key_same_value.json−1 tests/JSONTestSuite/test_transform/object_same_key_unclear_values.json−1 tests/JSONTestSuite/test_transform/string_1_escaped_invalid_codepoint.json−1 tests/JSONTestSuite/test_transform/string_1_invalid_codepoint.json−1 tests/JSONTestSuite/test_transform/string_2_escaped_invalid_codepoints.json−1 tests/JSONTestSuite/test_transform/string_2_invalid_codepoints.json−1 tests/JSONTestSuite/test_transform/string_3_escaped_invalid_codepoints.json−1 tests/JSONTestSuite/test_transform/string_3_invalid_codepoints.json−1 tests/JSONTestSuite/test_transform/string_with_escaped_NULL.json−1 tests/Options.hs+2−26 tests/PropUtils.hs−208 tests/Properties.hs+444−17 tests/PropertyGeneric.hs−116 tests/PropertyKeys.hs−40 tests/PropertyRTFunctors.hs−51 tests/PropertyRoundTrip.hs−74 tests/PropertyTH.hs−130 tests/SerializationFormatSpec.hs−294 tests/Tests.hs+3−5 tests/Types.hs+5−70 tests/UnitTests.hs+254−424 tests/UnitTests/NullaryConstructors.hs+3−8 tests/golden/generic.expected−48 tests/golden/simple.expected−22 travis/cabal_macros.h−448 travis/install.sh−11 travis/script.sh+1−8
.gitattributesdeleted−1
@@ -1 +0,0 @@
1−tests/JSONTestSuite/* linguist-vendored
.gitignore−10
@@ -1,21 +1,11 @@
11dist
2−dist-newstyle
3−.ghc.environment.*
42.cabal-sandbox/
53cabal.sandbox.config
64.stack-work/
7−.stack-work-bench/
8−*.yaml.lock
95
106*.o
117*.hi
128*.nix
13−*.swp
14−.\#*
15−\#*
16−
17−# Emacs backup files
18−*~
199
2010benchmarks/AesonEncode
2111
.hlint.yamldeleted−11
@@ -1,11 +0,0 @@
1−# Ignore some builtin hints
2−- ignore:
3− name: "Reduce duplication"
4− within:
5− - Data.Aeson.Types.ToJSON
6−- ignore:
7− name: "Eta reduce"
8−- ignore:
9− name: "Use newtype instead of data"
10− within:
11− - Data.Aeson.Types.Internal
.travis.yml+16−43
@@ -12,58 +12,31 @@ cache:
1212 - $HOME/.stack
1313 - $HOME/.cabsnap
1414 - $HOME/.cabal/packages
15− - $HOME/.cabal/store
1615
1716before_cache:
1817 - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
19− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.*
20− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/*.json
21− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.cache
22− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar
23− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar.idx
18+ - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
2419
2520matrix:
2621 include:
27−
28− - env: BUILD=hlint CABALVER=2.2 GHCVER=8.4.4
29− compiler: ": #GHC 8.4.4"
30− addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.4], sources: [hvr-ghc]}}
31−
32− - env: BUILD=stack CABALVER=2.4 GHCVER=8.6.5 STACK_YAML=stack-bench.yaml
33− compiler: ": #GHC 8.6.5"
34− addons: {apt: {packages: [cabal-install-2.4,ghc-8.6.5], sources: [hvr-ghc]}}
35−
36− - env: BUILD=stack CABALVER=2.2 GHCVER=8.6.5 STACK_YAML=stack-ffi-unescape.yaml
37− compiler: ": #GHC 8.6.5"
38− addons: {apt: {packages: [cabal-install-2.2,ghc-8.6.5], sources: [hvr-ghc]}}
39−
40− - env: BUILD=cabal2 CABALVER=3.0 GHCVER=8.8.1
41− compiler: ": #GHC 8.8.1"
42− addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.1], sources: [hvr-ghc]}}
43−
44− - env: BUILD=cabal CABALVER=2.4 GHCVER=8.6.5
45− compiler: ": #GHC 8.6.5"
46− addons: {apt: {packages: [cabal-install-2.4,ghc-8.6.5], sources: [hvr-ghc]}}
47−
48− - env: BUILD=cabal CABALVER=2.2 GHCVER=8.4.4
49− compiler: ": #GHC 8.4.4"
50− addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.4], sources: [hvr-ghc]}}
51−
52− - env: BUILD=cabal CABALVER=2.0 GHCVER=8.2.2
53− compiler: ": #GHC 8.2.2"
54− addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2], sources: [hvr-ghc]}}
55−
56− - env: BUILD=cabal CABALVER=2.0 GHCVER=8.0.2
57− compiler: ": #GHC 8.0.2"
58− addons: {apt: {packages: [cabal-install-2.0,ghc-8.0.2], sources: [hvr-ghc]}}
59−
60− - env: BUILD=cabal CABALVER=1.22 GHCVER=7.10.3
61− compiler: ": #GHC 7.10.3"
62− addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}}
63−
22+ - env: BUILD=cabal CABALVER=1.18 GHCVER=7.4.2
23+ compiler: ": #GHC 7.4.2"
24+ addons: {apt: {packages: [cabal-install-1.18,ghc-7.4.2], sources: [hvr-ghc]}}
25+ - env: BUILD=cabal CABALVER=1.18 GHCVER=7.6.3
26+ compiler: ": #GHC 7.6.3"
27+ addons: {apt: {packages: [cabal-install-1.18,ghc-7.6.3], sources: [hvr-ghc]}}
6428 - env: BUILD=cabal CABALVER=1.18 GHCVER=7.8.4
6529 compiler: ": #GHC 7.8.4"
6630 addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.4], sources: [hvr-ghc]}}
31+ - env: BUILD=cabal CABALVER=1.22 GHCVER=7.10.2
32+ compiler: ": #GHC 7.10.2"
33+ addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2], sources: [hvr-ghc]}}
34+ - env: BUILD=cabal CABALVER=1.24 GHCVER=8.0.1
35+ compiler: ": #GHC 8.0.1"
36+ addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1], sources: [hvr-ghc]}}
37+ - env: BUILD=stack CABALVER=1.22 GHCVER=7.10.3 STACK_YAML=stack-bench.yaml
38+ compiler: ": #GHC 7.10.3"
39+ addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}}
6740
6841before_install:
6942 - unset CC
CONTRIBUTING.md+1−39
@@ -8,7 +8,7 @@ Changes that affect users of aeson should be mentioned in `changelog.md`. It sho
88 * When it should be used
99 * What it supersedes
1010
11−Add this entry under an `## Upcoming` header above existing releases.
11+Add this entry under an `# Upcoming` header above existing releases.
1212
1313The exact format of entries is not important as we'll go through everything before a release is made.
1414
@@ -58,41 +58,3 @@ import Foo as F
5858import Qux (Q(..), q)
5959import qualified A
6060```
61−
62−## Development Workflow (If you plan on using Stack)
63−
64−Here we outline a general workflow new contributors could adopt for a nice incremental development experience.
65−
66−The root folder consists of two stack-*.yaml config files.
67−
68−1. stack-nightly.yaml - Config file defines all the settings to build and test any changes.
69−2. stack-bench.yaml - Used to run benchmark tests.
70−3. stack-ffi-unescape.yaml - This is for replacing certain parts with a C-implementation.
71−
72−Therefore, a ghci development experience would be:
73−
74−1. `stack ghci --stack-yaml stack-nightly.yaml --test`
75−2. :r to recompile
76−3. `main` to run all tests, or `:main --pattern Foo` to run specific tests matched by pattern.
77−
78−Some discussion on this topic can also be found here [here](https://github.com/bos/aeson/issues/733)
79−
80−Of course before submitting a PR, the following steps are recommended:
81−
82−1. 'stack test --stack-yaml stack-nightly.yaml` - Run the entire suite of tests
83−2. `make hlint` - Run hlint on the source folders.
84−3. 'stack test --stack-yaml stack-bench.yaml` - Run the benchmark tests if you believe your changes could affect the benchmarks.
85−
86−## Development Workflow (If you plan on using Cabal)
87−
88−A ghci development experience would be:
89−
90−1. `cabal new-repl test:tests`
91−2. `:r` to recompile
92−3. `Main.main` to run all tests, or `:m Main; :main --pattern Foo` to run specific tests matched by pattern.
93−
94−Of course before submitting a PR, the following steps are recommended:
95−
96−1. `cabal new-test` - Run the entire suite of tests
97−2. `make hlint` - Run hlint on the source folders.
98−3. Uncomment the `benchmarks` line in `cabal.project` - Run the benchmark tests if you believe your changes could affect the benchmarks.
Data/Aeson.hs+12−82
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21-- |
32-- Module: Data.Aeson
43-- Copyright: (c) 2011-2016 Bryan O'Sullivan
@@ -39,16 +38,11 @@ module Data.Aeson
3938 , eitherDecode
4039 , eitherDecode'
4140 , encode
42− , encodeFile
4341 -- ** Variants for strict bytestrings
4442 , decodeStrict
45− , decodeFileStrict
4643 , decodeStrict'
47− , decodeFileStrict'
4844 , eitherDecodeStrict
49− , eitherDecodeFileStrict
5045 , eitherDecodeStrict'
51− , eitherDecodeFileStrict'
5246 -- * Core JSON types
5347 , Value(..)
5448 , Encoding
@@ -63,18 +57,11 @@ module Data.Aeson
6357 , fromJSON
6458 , ToJSON(..)
6559 , KeyValue(..)
66− , (<?>)
67− , JSONPath
6860 -- ** Keys for maps
6961 , ToJSONKey(..)
7062 , ToJSONKeyFunction(..)
7163 , FromJSONKey(..)
7264 , FromJSONKeyFunction(..)
73− -- *** Generic keys
74− , GToJSONKey()
75− , genericToJSONKey
76− , GFromJSONKey()
77− , genericFromJSONKey
7865 -- ** Liftings to unary and binary type constructors
7966 , FromJSON1(..)
8067 , parseJSON1
@@ -89,8 +76,8 @@ module Data.Aeson
8976 -- ** Generic JSON classes and options
9077 , GFromJSON(..)
9178 , FromArgs(..)
92− , GToJSON
93− , GToEncoding
79+ , GToJSON(..)
80+ , GToEncoding(..)
9481 , ToArgs(..)
9582 , Zero
9683 , One
@@ -100,34 +87,15 @@ module Data.Aeson
10087 , genericLiftToEncoding
10188 , genericParseJSON
10289 , genericLiftParseJSON
103− -- ** Generic and TH encoding configuration
104− , Options
10590 , defaultOptions
106− -- *** Options fields
107− -- $optionsFields
108− , fieldLabelModifier
109− , constructorTagModifier
110− , allNullaryToStringTag
111− , omitNothingFields
112− , sumEncoding
113− , unwrapUnaryRecords
114− , tagSingleConstructors
115− -- *** Options utilities
116− , SumEncoding(..)
117− , camelTo2
118− , defaultTaggedObject
119− -- ** Options for object keys
120− , JSONKeyOptions
121− , keyModifier
122− , defaultJSONKeyOptions
12391
12492 -- * Inspecting @'Value's@
12593 , withObject
12694 , withText
12795 , withArray
96+ , withNumber
12897 , withScientific
12998 , withBool
130− , withEmbeddedJSON
13199 -- * Constructors and accessors
132100 , Series
133101 , pairs
@@ -140,16 +108,16 @@ module Data.Aeson
140108 -- * Parsing
141109 , json
142110 , json'
143− , parseIndexedJSON
144111 ) where
145112
113+import Prelude ()
146114import Prelude.Compat
147115
148−import Data.Aeson.Types.FromJSON (ifromJSON, parseIndexedJSON)
116+import Data.Aeson.Types.FromJSON (ifromJSON)
149117import Data.Aeson.Encoding (encodingToLazyByteString)
150118import Data.Aeson.Parser.Internal (decodeWith, decodeStrictWith, eitherDecodeWith, eitherDecodeStrictWith, jsonEOF, json, jsonEOF', json')
151119import Data.Aeson.Types
152−import Data.Aeson.Types.Internal (JSONPath, formatError, (<?>))
120+import Data.Aeson.Types.Internal (JSONPath, formatError)
153121import qualified Data.ByteString as B
154122import qualified Data.ByteString.Lazy as L
155123
@@ -159,10 +127,6 @@ import qualified Data.ByteString.Lazy as L
159127encode :: (ToJSON a) => a -> L.ByteString
160128encode = encodingToLazyByteString . toEncoding
161129
162−-- | Efficiently serialize a JSON value as a lazy 'L.ByteString' and write it to a file.
163−encodeFile :: (ToJSON a) => FilePath -> a -> IO ()
164−encodeFile fp = L.writeFile fp . encode
165−
166130-- | Efficiently deserialize a JSON value from a lazy 'L.ByteString'.
167131-- If this fails due to incomplete or invalid input, 'Nothing' is
168132-- returned.
@@ -189,18 +153,6 @@ decodeStrict :: (FromJSON a) => B.ByteString -> Maybe a
189153decodeStrict = decodeStrictWith jsonEOF fromJSON
190154{-# INLINE decodeStrict #-}
191155
192−-- | Efficiently deserialize a JSON value from a file.
193−-- If this fails due to incomplete or invalid input, 'Nothing' is
194−-- returned.
195−--
196−-- The input file's content must consist solely of a JSON document,
197−-- with no trailing data except for whitespace.
198−--
199−-- This function parses immediately, but defers conversion. See
200−-- 'json' for details.
201−decodeFileStrict :: (FromJSON a) => FilePath -> IO (Maybe a)
202−decodeFileStrict = fmap decodeStrict . B.readFile
203−
204156-- | Efficiently deserialize a JSON value from a lazy 'L.ByteString'.
205157-- If this fails due to incomplete or invalid input, 'Nothing' is
206158-- returned.
@@ -227,18 +179,6 @@ decodeStrict' :: (FromJSON a) => B.ByteString -> Maybe a
227179decodeStrict' = decodeStrictWith jsonEOF' fromJSON
228180{-# INLINE decodeStrict' #-}
229181
230−-- | Efficiently deserialize a JSON value from a file.
231−-- If this fails due to incomplete or invalid input, 'Nothing' is
232−-- returned.
233−--
234−-- The input file's content must consist solely of a JSON document,
235−-- with no trailing data except for whitespace.
236−--
237−-- This function parses and performs conversion immediately. See
238−-- 'json'' for details.
239−decodeFileStrict' :: (FromJSON a) => FilePath -> IO (Maybe a)
240−decodeFileStrict' = fmap decodeStrict' . B.readFile
241−
242182eitherFormatError :: Either (JSONPath, String) a -> Either String a
243183eitherFormatError = either (Left . uncurry formatError) Right
244184{-# INLINE eitherFormatError #-}
@@ -254,12 +194,6 @@ eitherDecodeStrict =
254194 eitherFormatError . eitherDecodeStrictWith jsonEOF ifromJSON
255195{-# INLINE eitherDecodeStrict #-}
256196
257−-- | Like 'decodeFileStrict' but returns an error message when decoding fails.
258−eitherDecodeFileStrict :: (FromJSON a) => FilePath -> IO (Either String a)
259−eitherDecodeFileStrict =
260− fmap (eitherFormatError . eitherDecodeStrictWith jsonEOF ifromJSON) . B.readFile
261−{-# INLINE eitherDecodeFileStrict #-}
262−
263197-- | Like 'decode'' but returns an error message when decoding fails.
264198eitherDecode' :: (FromJSON a) => L.ByteString -> Either String a
265199eitherDecode' = eitherFormatError . eitherDecodeWith jsonEOF' ifromJSON
@@ -271,12 +205,6 @@ eitherDecodeStrict' =
271205 eitherFormatError . eitherDecodeStrictWith jsonEOF' ifromJSON
272206{-# INLINE eitherDecodeStrict' #-}
273207
274−-- | Like 'decodeFileStrict'' but returns an error message when decoding fails.
275−eitherDecodeFileStrict' :: (FromJSON a) => FilePath -> IO (Either String a)
276−eitherDecodeFileStrict' =
277− fmap (eitherFormatError . eitherDecodeStrictWith jsonEOF' ifromJSON) . B.readFile
278−{-# INLINE eitherDecodeFileStrict' #-}
279−
280208-- $use
281209--
282210-- This section contains basic information on the different ways to
@@ -346,9 +274,11 @@ eitherDecodeFileStrict' =
346274-- > {-# LANGUAGE OverloadedStrings #-}
347275-- >
348276-- > instance FromJSON Person where
349−-- > parseJSON = withObject "Person" $ \v -> Person
350−-- > <$> v .: "name"
351−-- > <*> v .: "age"
277+-- > parseJSON (Object v) = Person <$>
278+-- > v .: "name" <*>
279+-- > v .: "age"
280+-- > -- A non-Object value is of the wrong type, so fail.
281+-- > parseJSON _ = empty
352282--
353283-- We can now parse the JSON data like so:
354284--
@@ -438,7 +368,7 @@ eitherDecodeFileStrict' =
438368-- The 'Object' type contains JSON objects:
439369--
440370-- > λ> decode "{\"name\":\"Dave\",\"age\":2}" :: Maybe Object
441−-- > Just (fromList [("name",String "Dave"),("age",Number 2)])
371+-- > Just (fromList) [("name",String "Dave"),("age",Number 2)]
442372--
443373-- You can extract values from it with a parser using 'parse',
444374-- 'parseEither' or, in this example, 'parseMaybe':
Data/Aeson/Encode.hs+1−2
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21-- |
32-- Module: Data.Aeson.Encode
43-- Copyright: (c) 2012-2016 Bryan O'Sullivan
@@ -9,13 +8,13 @@
98-- Portability: portable
109--
1110-- This module is left to supply limited backwards-compatibility.
12−
1311module Data.Aeson.Encode {-# DEPRECATED "Use Data.Aeson or Data.Aeson.Text instead" #-}
1412 (
1513 encode
1614 , encodeToTextBuilder
1715 ) where
1816
17+import Prelude ()
1918
2019import Data.ByteString.Lazy (ByteString)
2120import Data.Text.Lazy.Builder (Builder)
Data/Aeson/Encoding.hs+1−4
@@ -1,10 +1,8 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21-- |
32--
43-- Functions in this module return well-formed 'Encoding''.
54-- Polymorphic variants, which return @'Encoding' a@, return a textual JSON
65-- value, so it can be used as both @'Encoding'' 'Text'@ and @'Encoding' = 'Encoding'' 'Value'@.
7−
86module Data.Aeson.Encoding
97 (
108 -- * Encoding
@@ -16,8 +14,6 @@ module Data.Aeson.Encoding
1614 , Series
1715 , pairs
1816 , pair
19− , pairStr
20− , pair'
2117 -- * Predicates
2218 , nullEncoding
2319 -- * Encoding constructors
@@ -51,5 +47,6 @@ module Data.Aeson.Encoding
5147 , value
5248 ) where
5349
50+import Prelude ()
5451
5552import Data.Aeson.Encoding.Internal
Data/Aeson/Encoding/Builder.hs+87−13
@@ -1,6 +1,7 @@
11{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
3−{-# LANGUAGE TupleSections #-}
2+{-# LANGUAGE CPP #-}
3+{-# LANGUAGE OverloadedStrings #-}
4+
45-- |
56-- Module: Data.Aeson.Encoding.Builder
67-- Copyright: (c) 2011 MailRank, Inc.
@@ -36,6 +37,7 @@ module Data.Aeson.Encoding.Builder
3637 , ascii5
3738 ) where
3839
40+import Prelude ()
3941import Prelude.Compat
4042
4143import Data.Aeson.Internal.Time
@@ -44,9 +46,8 @@ import Data.ByteString.Builder as B
4446import Data.ByteString.Builder.Prim as BP
4547import Data.ByteString.Builder.Scientific (scientificBuilder)
4648import Data.Char (chr, ord)
47−import Data.Semigroup ((<>))
49+import Data.Monoid ((<>))
4850import Data.Scientific (Scientific, base10Exponent, coefficient)
49−import Data.Text.Encoding (encodeUtf8BuilderEscaped)
5051import Data.Time (UTCTime(..))
5152import Data.Time.Calendar (Day(..), toGregorian)
5253import Data.Time.LocalTime
@@ -55,6 +56,20 @@ import qualified Data.HashMap.Strict as HMS
5556import qualified Data.Text as T
5657import qualified Data.Vector as V
5758
59+#if MIN_VERSION_bytestring(0,10,4)
60+import Data.Text.Encoding (encodeUtf8BuilderEscaped)
61+#else
62+import Data.Bits ((.&.))
63+import Data.Text.Internal (Text(..))
64+import Data.Text.Internal.Unsafe.Shift (shiftR)
65+import Foreign.Ptr (minusPtr, plusPtr)
66+import Foreign.Storable (poke)
67+import qualified Data.ByteString.Builder.Internal as B
68+import qualified Data.ByteString.Builder.Prim.Internal as BP
69+import qualified Data.Text.Array as A
70+import qualified Data.Text.Internal.Encoding.Utf16 as U16
71+#endif
72+
5873-- | Encode a JSON value to a "Data.ByteString" 'B.Builder'.
5974--
6075-- Use this function if you are encoding over the wire, or need to
@@ -133,7 +148,7 @@ c2w c = fromIntegral (ord c)
133148-- | Encode a JSON number.
134149scientific :: Scientific -> Builder
135150scientific s
136− | e < 0 || e > 1024 = scientificBuilder s
151+ | e < 0 = scientificBuilder s
137152 | otherwise = B.integerDec (coefficient s * 10 ^ e)
138153 where
139154 e = base10Exponent s
@@ -178,13 +193,12 @@ day dd = encodeYear yr <>
178193 !(T dh dl) = twoDigits d
179194 encodeYear y
180195 | y >= 1000 = B.integerDec y
181− | y >= 0 = BP.primBounded (ascii4 (padYear y)) ()
182− | y >= -999 = BP.primBounded (ascii5 ('-',padYear (- y))) ()
183− | otherwise = B.integerDec y
184− padYear y =
185− let (ab,c) = fromIntegral y `quotRem` 10
186− (a,b) = ab `quotRem` 10
187− in ('0',(digit a,(digit b,digit c)))
196+ | y > 0 =
197+ let (ab,c) = fromIntegral y `quotRem` 10
198+ (a,b) = ab `quotRem` 10
199+ in BP.primBounded (ascii4 ('0',(digit a,(digit b,digit c)))) ()
200+ | otherwise =
201+ error "Data.Aeson.Encode.Builder.day: years BCE not supported"
188202{-# INLINE day #-}
189203
190204timeOfDay :: TimeOfDay -> Builder
@@ -201,7 +215,7 @@ timeOfDay64 (TOD h m s)
201215 !(T mh ml) = twoDigits m
202216 !(T sh sl) = twoDigits (fromIntegral real)
203217 (real,frac) = s `quotRem` pico
204− showFrac = ('.',) >$< (BP.liftFixedToBounded BP.char7 >*< trunc12)
218+ showFrac = (\x -> ('.', x)) >$< (BP.liftFixedToBounded BP.char7 >*< trunc12)
205219 trunc12 = (`quotRem` micro) >$<
206220 BP.condB (\(_,y) -> y == 0) (fst >$< trunc6) (digits6 >*< trunc6)
207221 digits6 = ((`quotRem` milli) . fromIntegral) >$< (digits3 >*< digits3)
@@ -219,6 +233,7 @@ timeOfDay64 (TOD h m s)
219233 pico = 1000000000000 -- number of picoseconds in 1 second
220234 micro = 1000000 -- number of microseconds in 1 second
221235 milli = 1000 -- number of milliseconds in 1 second
236+{-# INLINE timeOfDay64 #-}
222237
223238timeZone :: TimeZone -> Builder
224239timeZone (TimeZone off _ _)
@@ -254,3 +269,62 @@ twoDigits a = T (digit hi) (digit lo)
254269
255270digit :: Int -> Char
256271digit x = chr (x + 48)
272+
273+#if !(MIN_VERSION_bytestring(0,10,4))
274+-- | Encode text using UTF-8 encoding and escape the ASCII characters using
275+-- a 'BP.BoundedPrim'.
276+--
277+-- Use this function is to implement efficient encoders for text-based formats
278+-- like JSON or HTML.
279+{-# INLINE encodeUtf8BuilderEscaped #-}
280+-- TODO: Extend documentation with references to source code in @blaze-html@
281+-- or @aeson@ that uses this function.
282+encodeUtf8BuilderEscaped :: BP.BoundedPrim Word8 -> Text -> B.Builder
283+encodeUtf8BuilderEscaped be =
284+ -- manual eta-expansion to ensure inlining works as expected
285+ \txt -> B.builder (mkBuildstep txt)
286+ where
287+ bound = max 4 $ BP.sizeBound be
288+
289+ mkBuildstep (Text arr off len) !k =
290+ outerLoop off
291+ where
292+ iend = off + len
293+
294+ outerLoop !i0 !br@(B.BufferRange op0 ope)
295+ | i0 >= iend = k br
296+ | outRemaining > 0 = goPartial (i0 + min outRemaining inpRemaining)
297+ -- TODO: Use a loop with an integrated bound's check if outRemaining
298+ -- is smaller than 8, as this will save on divisions.
299+ | otherwise = return $ B.bufferFull bound op0 (outerLoop i0)
300+ where
301+ outRemaining = (ope `minusPtr` op0) `div` bound
302+ inpRemaining = iend - i0
303+
304+ goPartial !iendTmp = go i0 op0
305+ where
306+ go !i !op
307+ | i < iendTmp = case A.unsafeIndex arr i of
308+ w | w <= 0x7F -> do
309+ BP.runB be (fromIntegral w) op >>= go (i + 1)
310+ | w <= 0x7FF -> do
311+ poke8 0 $ (w `shiftR` 6) + 0xC0
312+ poke8 1 $ (w .&. 0x3f) + 0x80
313+ go (i + 1) (op `plusPtr` 2)
314+ | 0xD800 <= w && w <= 0xDBFF -> do
315+ let c = ord $ U16.chr2 w (A.unsafeIndex arr (i+1))
316+ poke8 0 $ (c `shiftR` 18) + 0xF0
317+ poke8 1 $ ((c `shiftR` 12) .&. 0x3F) + 0x80
318+ poke8 2 $ ((c `shiftR` 6) .&. 0x3F) + 0x80
319+ poke8 3 $ (c .&. 0x3F) + 0x80
320+ go (i + 2) (op `plusPtr` 4)
321+ | otherwise -> do
322+ poke8 0 $ (w `shiftR` 12) + 0xE0
323+ poke8 1 $ ((w `shiftR` 6) .&. 0x3F) + 0x80
324+ poke8 2 $ (w .&. 0x3F) + 0x80
325+ go (i + 1) (op `plusPtr` 3)
326+ | otherwise =
327+ outerLoop i (B.BufferRange op ope)
328+ where
329+ poke8 j v = poke (op `plusPtr` j) (fromIntegral v :: Word8)
330+#endif
Data/Aeson/Encoding/Internal.hs+3−14
@@ -1,9 +1,7 @@
11{-# LANGUAGE DeriveDataTypeable #-}
22{-# LANGUAGE EmptyDataDecls #-}
3−{-# LANGUAGE NoImplicitPrelude #-}
43{-# LANGUAGE OverloadedStrings #-}
54{-# LANGUAGE RankNTypes #-}
6−
75module Data.Aeson.Encoding.Internal
86 (
97 -- * Encoding
@@ -15,8 +13,6 @@ module Data.Aeson.Encoding.Internal
1513 , Series (..)
1614 , pairs
1715 , pair
18− , pairStr
19− , pair'
2016 -- * Predicates
2117 , nullEncoding
2218 -- * Encoding constructors
@@ -57,6 +53,7 @@ module Data.Aeson.Encoding.Internal
5753 , comma, colon, openBracket, closeBracket, openCurly, closeCurly
5854 ) where
5955
56+import Prelude ()
6057import Prelude.Compat
6158
6259import Data.Aeson.Types.Internal (Value)
@@ -82,7 +79,7 @@ newtype Encoding' tag = Encoding {
8279 -- ^ Acquire the underlying bytestring builder.
8380 } deriving (Typeable)
8481
85−-- | Often used synonym for 'Encoding''.
82+-- | Often used synonnym for 'Encoding''.
8683type Encoding = Encoding' Value
8784
8885-- | Make Encoding from Builder.
@@ -125,15 +122,7 @@ data Series = Empty
125122 deriving (Typeable)
126123
127124pair :: Text -> Encoding -> Series
128−pair name val = pair' (text name) val
129−{-# INLINE pair #-}
130−
131−pairStr :: String -> Encoding -> Series
132−pairStr name val = pair' (string name) val
133−{-# INLINE pairStr #-}
134−
135−pair' :: Encoding' Text -> Encoding -> Series
136−pair' name val = Value $ retagEncoding $ retagEncoding name >< colon >< val
125+pair name val = Value $ retagEncoding $ text name >< colon >< val
137126
138127instance Semigroup Series where
139128 Empty <> a = a
Data/Aeson/Internal.hs+1−1
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21-- |
32-- Module: Data.Aeson.Internal
43-- Copyright: (c) 2015-2016 Bryan O'Sullivan
@@ -23,6 +22,7 @@ module Data.Aeson.Internal
2322 , iparse
2423 ) where
2524
25+import Prelude ()
2626
2727import Data.Aeson.Types.Internal
2828import Data.Aeson.Types.FromJSON (ifromJSON)
Data/Aeson/Internal/Functions.hs+1−1
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21-- |
32-- Module: Data.Aeson.Functions
43-- Copyright: (c) 2011-2016 Bryan O'Sullivan
@@ -15,6 +14,7 @@ module Data.Aeson.Internal.Functions
1514 , mapKey
1615 ) where
1716
17+import Prelude ()
1818import Prelude.Compat
1919
2020import Data.Hashable (Hashable)
Data/Aeson/Internal/Time.hs+41−1
@@ -17,4 +17,44 @@ module Data.Aeson.Internal.Time
1717 , toTimeOfDay64
1818 ) where
1919
20−import Data.Attoparsec.Time.Internal
20+import Prelude ()
21+import Prelude.Compat
22+
23+import Data.Fixed (Pico)
24+import Data.Int (Int64)
25+import Data.Time
26+import Unsafe.Coerce (unsafeCoerce)
27+
28+#if MIN_VERSION_base(4,7,0)
29+
30+import Data.Fixed (Fixed(MkFixed))
31+
32+toPico :: Integer -> Pico
33+toPico = MkFixed
34+
35+fromPico :: Pico -> Integer
36+fromPico (MkFixed i) = i
37+
38+#else
39+
40+toPico :: Integer -> Pico
41+toPico = unsafeCoerce
42+
43+fromPico :: Pico -> Integer
44+fromPico = unsafeCoerce
45+
46+#endif
47+
48+-- | Like TimeOfDay, but using a fixed-width integer for seconds.
49+data TimeOfDay64 = TOD {-# UNPACK #-} !Int
50+ {-# UNPACK #-} !Int
51+ {-# UNPACK #-} !Int64
52+
53+diffTimeOfDay64 :: DiffTime -> TimeOfDay64
54+diffTimeOfDay64 t = TOD (fromIntegral h) (fromIntegral m) s
55+ where (h,mp) = fromIntegral pico `quotRem` 3600000000000000
56+ (m,s) = mp `quotRem` 60000000000000
57+ pico = unsafeCoerce t :: Integer
58+
59+toTimeOfDay64 :: TimeOfDay -> TimeOfDay64
60+toTimeOfDay64 (TimeOfDay h m s) = TOD h m (fromIntegral (fromPico s))
Data/Aeson/Parser.hs+4−13
@@ -1,4 +1,5 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
1+{-# LANGUAGE OverloadedStrings #-}
2+
23-- |
34-- Module: Data.Aeson.Parser
45-- Copyright: (c) 2012-2016 Bryan O'Sullivan
@@ -34,21 +35,10 @@ module Data.Aeson.Parser
3435 json
3536 , value
3637 , jstring
37− , scientific
38− -- ** Handling objects with duplicate keys
39− , jsonWith
40− , jsonLast
41− , jsonAccum
42− , jsonNoDup
4338 -- * Strict parsers
4439 -- $strict
4540 , json'
4641 , value'
47− -- ** Handling objects with duplicate keys
48− , jsonWith'
49− , jsonLast'
50− , jsonAccum'
51− , jsonNoDup'
5242 -- * Decoding without FromJSON instances
5343 , decodeWith
5444 , decodeStrictWith
@@ -56,8 +46,9 @@ module Data.Aeson.Parser
5646 , eitherDecodeStrictWith
5747 ) where
5848
49+import Prelude ()
5950
60−import Data.Aeson.Parser.Internal
51+import Data.Aeson.Parser.Internal (decodeStrictWith, decodeWith, eitherDecodeStrictWith, eitherDecodeWith, json, json', jstring, value, value')
6152
6253-- $lazy
6354--
Data/Aeson/Parser/Internal.hs+65−307
@@ -1,14 +1,10 @@
11{-# LANGUAGE BangPatterns #-}
22{-# LANGUAGE CPP #-}
3−{-# LANGUAGE NoImplicitPrelude #-}
43{-# LANGUAGE OverloadedStrings #-}
54#if MIN_VERSION_ghc_prim(0,3,1)
65{-# LANGUAGE MagicHash #-}
76#endif
8−#if __GLASGOW_HASKELL__ <= 710 && __GLASGOW_HASKELL__ >= 706
9−-- Work around a compiler bug
10−{-# OPTIONS_GHC -fsimpl-tick-factor=200 #-}
11−#endif
7+
128-- |
139-- Module: Data.Aeson.Parser.Internal
1410-- Copyright: (c) 2011-2016 Bryan O'Sullivan
@@ -25,56 +21,39 @@ module Data.Aeson.Parser.Internal
2521 (
2622 -- * Lazy parsers
2723 json, jsonEOF
28− , jsonWith
29− , jsonLast
30− , jsonAccum
31− , jsonNoDup
3224 , value
3325 , jstring
34− , jstring_
35− , scientific
3626 -- * Strict parsers
3727 , json', jsonEOF'
38− , jsonWith'
39− , jsonLast'
40− , jsonAccum'
41− , jsonNoDup'
4228 , value'
4329 -- * Helpers
4430 , decodeWith
4531 , decodeStrictWith
4632 , eitherDecodeWith
4733 , eitherDecodeStrictWith
48− -- ** Handling objects with duplicate keys
49− , fromListAccum
50− , parseListNoDup
5134 ) where
5235
36+import Prelude ()
5337import Prelude.Compat
5438
55−import Control.Applicative ((<|>))
56−import Control.Monad (void, when)
57−import Data.Aeson.Types.Internal (IResult(..), JSONPath, Object, Result(..), Value(..))
58−import Data.Attoparsec.ByteString.Char8 (Parser, char, decimal, endOfInput, isDigit_w8, signed, string)
59−import Data.Function (fix)
60−import Data.Functor.Compat (($>))
61−import Data.Scientific (Scientific)
39+import Data.Aeson.Types.Internal (IResult(..), JSONPath, Result(..), Value(..))
40+import Data.Attoparsec.ByteString.Char8 (Parser, char, endOfInput, scientific, skipSpace, string)
41+import Data.Attoparsec.ByteString.Char8 (Parser, char, endOfInput, scientific, skipSpace, string)
42+import Data.Bits ((.|.), shiftL)
43+import Data.ByteString.Internal (ByteString(..))
44+import Data.Char (chr)
6245import Data.Text (Text)
63−import Data.Vector (Vector)
64−import qualified Data.Vector as Vector (empty, fromList, fromListN, reverse)
46+import Data.Vector as Vector (Vector, empty, fromListN, reverse)
6547import qualified Data.Attoparsec.ByteString as A
6648import qualified Data.Attoparsec.Lazy as L
6749import qualified Data.ByteString as B
68−import qualified Data.ByteString.Unsafe as B
6950import qualified Data.ByteString.Lazy as L
7051import qualified Data.HashMap.Strict as H
71−import qualified Data.Scientific as Sci
72−import Data.Aeson.Parser.Unescape (unescapeText)
52+import Data.Aeson.Parser.Unescape
7353
7454#if MIN_VERSION_ghc_prim(0,3,1)
75−import GHC.Base (Int#, (==#), isTrue#, word2Int#, orI#, andI#)
55+import GHC.Base (Int#, (==#), isTrue#, word2Int#)
7656import GHC.Word (Word8(W8#))
77−import qualified Data.Text.Encoding as TE
7857#endif
7958
8059#define BACKSLASH 92
@@ -93,7 +72,7 @@ import qualified Data.Text.Encoding as TE
9372#define C_n 110
9473#define C_t 116
9574
96−-- | Parse any JSON value.
75+-- | Parse a top-level JSON value.
9776--
9877-- The conversion of a parsed value to a Haskell value is deferred
9978-- until the Haskell value is needed. This may improve performance if
@@ -103,15 +82,10 @@ import qualified Data.Text.Encoding as TE
10382-- This function is an alias for 'value'. In aeson 0.8 and earlier, it
10483-- parsed only object or array types, in conformance with the
10584-- now-obsolete RFC 4627.
106−--
107−-- ==== Warning
108−--
109−-- If an object contains duplicate keys, only the first one will be kept.
110−-- For a more flexible alternative, see 'jsonWith'.
11185json :: Parser Value
11286json = value
11387
114−-- | Parse any JSON value.
88+-- | Parse a top-level JSON value.
11589--
11690-- This is a strict version of 'json' which avoids building up thunks
11791-- during parsing; it performs all conversions immediately. Prefer
@@ -120,35 +94,23 @@ json = value
12094-- This function is an alias for 'value''. In aeson 0.8 and earlier, it
12195-- parsed only object or array types, in conformance with the
12296-- now-obsolete RFC 4627.
123−--
124−-- ==== Warning
125−--
126−-- If an object contains duplicate keys, only the first one will be kept.
127−-- For a more flexible alternative, see 'jsonWith''.
12897json' :: Parser Value
12998json' = value'
13099
131−-- Open recursion: object_, object_', array_, array_' are parameterized by the
132−-- toplevel Value parser to be called recursively, to keep the parameter
133−-- mkObject outside of the recursive loop for proper inlining.
134−
135−object_ :: ([(Text, Value)] -> Either String Object) -> Parser Value -> Parser Value
136−object_ mkObject val = {-# SCC "object_" #-} Object <$> objectValues mkObject jstring val
137−{-# INLINE object_ #-}
100+object_ :: Parser Value
101+object_ = {-# SCC "object_" #-} Object <$> objectValues jstring value
138102
139−object_' :: ([(Text, Value)] -> Either String Object) -> Parser Value -> Parser Value
140−object_' mkObject val' = {-# SCC "object_'" #-} do
141− !vals <- objectValues mkObject jstring' val'
103+object_' :: Parser Value
104+object_' = {-# SCC "object_'" #-} do
105+ !vals <- objectValues jstring' value'
142106 return (Object vals)
143107 where
144108 jstring' = do
145109 !s <- jstring
146110 return s
147−{-# INLINE object_' #-}
148111
149−objectValues :: ([(Text, Value)] -> Either String Object)
150− -> Parser Text -> Parser Value -> Parser (H.HashMap Text Value)
151−objectValues mkObject str val = do
112+objectValues :: Parser Text -> Parser Value -> Parser (H.HashMap Text Value)
113+objectValues str val = do
152114 skipSpace
153115 w <- A.peekWord8'
154116 if w == CLOSE_CURLY
@@ -158,26 +120,22 @@ objectValues mkObject str val = do
158120 -- Why use acc pattern here, you may ask? because 'H.fromList' use 'unsafeInsert'
159121 -- and it's much faster because it's doing in place update to the 'HashMap'!
160122 loop acc = do
161− k <- (str A.<?> "object key") <* skipSpace <* (char ':' A.<?> "':'")
162− v <- (val A.<?> "object value") <* skipSpace
163− ch <- A.satisfy (\w -> w == COMMA || w == CLOSE_CURLY) A.<?> "',' or '}'"
123+ k <- str <* skipSpace <* char ':'
124+ v <- val <* skipSpace
125+ ch <- A.satisfy $ \w -> w == COMMA || w == CLOSE_CURLY
164126 let acc' = (k, v) : acc
165127 if ch == COMMA
166128 then skipSpace >> loop acc'
167− else case mkObject acc' of
168− Left err -> fail err
169− Right obj -> pure obj
129+ else return (H.fromList acc')
170130{-# INLINE objectValues #-}
171131
172−array_ :: Parser Value -> Parser Value
173−array_ val = {-# SCC "array_" #-} Array <$> arrayValues val
174−{-# INLINE array_ #-}
132+array_ :: Parser Value
133+array_ = {-# SCC "array_" #-} Array <$> arrayValues value
175134
176−array_' :: Parser Value -> Parser Value
177−array_' val = {-# SCC "array_'" #-} do
178− !vals <- arrayValues val
135+array_' :: Parser Value
136+array_' = {-# SCC "array_'" #-} do
137+ !vals <- arrayValues value'
179138 return (Array vals)
180−{-# INLINE array_' #-}
181139
182140arrayValues :: Parser Value -> Parser (Vector Value)
183141arrayValues val = do
@@ -188,133 +146,57 @@ arrayValues val = do
188146 else loop [] 1
189147 where
190148 loop acc !len = do
191− v <- (val A.<?> "json list value") <* skipSpace
192− ch <- A.satisfy (\w -> w == COMMA || w == CLOSE_SQUARE) A.<?> "',' or ']'"
149+ v <- val <* skipSpace
150+ ch <- A.satisfy $ \w -> w == COMMA || w == CLOSE_SQUARE
193151 if ch == COMMA
194152 then skipSpace >> loop (v:acc) (len+1)
195153 else return (Vector.reverse (Vector.fromListN len (v:acc)))
196154{-# INLINE arrayValues #-}
197155
198−-- | Parse any JSON value. Synonym of 'json'.
199−value :: Parser Value
200−value = jsonWith (pure . H.fromList)
201−
202−-- | Parse any JSON value.
203−--
204−-- This parser is parameterized by a function to construct an 'Object'
205−-- from a raw list of key-value pairs, where duplicates are preserved.
206−-- The pairs appear in __reverse order__ from the source.
207−--
208−-- ==== __Examples__
209−--
210−-- 'json' keeps only the first occurence of each key, using 'HashMap.Lazy.fromList'.
211−--
212−-- @
213−-- 'json' = 'jsonWith' ('Right' '.' 'H.fromList')
214−-- @
215−--
216−-- 'jsonLast' keeps the last occurence of each key, using
217−-- @'HashMap.Lazy.fromListWith' ('const' 'id')@.
156+-- | Parse any JSON value. You should usually 'json' in preference to
157+-- this function, as this function relaxes the object-or-array
158+-- requirement of RFC 4627.
218159--
219−-- @
220−-- 'jsonLast' = 'jsonWith' ('Right' '.' 'HashMap.Lazy.fromListWith' ('const' 'id'))
221−-- @
222−--
223−-- 'jsonAccum' keeps wraps all values in arrays to keep duplicates, using
224−-- 'fromListAccum'.
225−--
226−-- @
227−-- 'jsonAccum' = 'jsonWith' ('Right' . 'fromListAccum')
228−-- @
229−--
230−-- 'jsonNoDup' fails if any object contains duplicate keys, using 'parseListNoDup'.
231−--
232−-- @
233−-- 'jsonNoDup' = 'jsonWith' 'parseListNoDup'
234−-- @
235−jsonWith :: ([(Text, Value)] -> Either String Object) -> Parser Value
236−jsonWith mkObject = fix $ \value_ -> do
160+-- In particular, be careful in using this function if you think your
161+-- code might interoperate with Javascript. A na&#xef;ve Javascript
162+-- library that parses JSON data using @eval@ is vulnerable to attack
163+-- unless the encoded data represents an object or an array. JSON
164+-- implementations in other languages conform to that same restriction
165+-- to preserve interoperability and security.
166+value :: Parser Value
167+value = do
237168 skipSpace
238169 w <- A.peekWord8'
239170 case w of
240171 DOUBLE_QUOTE -> A.anyWord8 *> (String <$> jstring_)
241− OPEN_CURLY -> A.anyWord8 *> object_ mkObject value_
242− OPEN_SQUARE -> A.anyWord8 *> array_ value_
243− C_f -> string "false" $> Bool False
244− C_t -> string "true" $> Bool True
245− C_n -> string "null" $> Null
172+ OPEN_CURLY -> A.anyWord8 *> object_
173+ OPEN_SQUARE -> A.anyWord8 *> array_
174+ C_f -> string "false" *> pure (Bool False)
175+ C_t -> string "true" *> pure (Bool True)
176+ C_n -> string "null" *> pure Null
246177 _ | w >= 48 && w <= 57 || w == 45
247178 -> Number <$> scientific
248179 | otherwise -> fail "not a valid json value"
249−{-# INLINE jsonWith #-}
250−
251−-- | Variant of 'json' which keeps only the last occurence of every key.
252−jsonLast :: Parser Value
253−jsonLast = jsonWith (Right . H.fromListWith (const id))
254−
255−-- | Variant of 'json' wrapping all object mappings in 'Array' to preserve
256−-- key-value pairs with the same keys.
257−jsonAccum :: Parser Value
258−jsonAccum = jsonWith (Right . fromListAccum)
259180
260−-- | Variant of 'json' which fails if any object contains duplicate keys.
261−jsonNoDup :: Parser Value
262−jsonNoDup = jsonWith parseListNoDup
263−
264−-- | @'fromListAccum' kvs@ is an object mapping keys to arrays containing all
265−-- associated values from the original list @kvs@.
266−--
267−-- >>> fromListAccum [("apple", Bool True), ("apple", Bool False), ("orange", Bool False)]
268−-- fromList [("apple", [Bool False, Bool True]), ("orange", [Bool False])]
269−fromListAccum :: [(Text, Value)] -> Object
270−fromListAccum =
271− fmap (Array . Vector.fromList . ($ [])) . H.fromListWith (.) . (fmap . fmap) (:)
272−
273−-- | @'fromListNoDup' kvs@ fails if @kvs@ contains duplicate keys.
274−parseListNoDup :: [(Text, Value)] -> Either String Object
275−parseListNoDup =
276− H.traverseWithKey unwrap . H.fromListWith (\_ _ -> Nothing) . (fmap . fmap) Just
277− where
278− unwrap k Nothing = Left $ "found duplicate key: " ++ show k
279− unwrap _ (Just v) = Right v
280−
281−-- | Strict version of 'value'. Synonym of 'json''.
181+-- | Strict version of 'value'. See also 'json''.
282182value' :: Parser Value
283−value' = jsonWith' (pure . H.fromList)
284−
285−-- | Strict version of 'jsonWith'.
286−jsonWith' :: ([(Text, Value)] -> Either String Object) -> Parser Value
287−jsonWith' mkObject = fix $ \value_ -> do
183+value' = do
288184 skipSpace
289185 w <- A.peekWord8'
290186 case w of
291187 DOUBLE_QUOTE -> do
292188 !s <- A.anyWord8 *> jstring_
293189 return (String s)
294− OPEN_CURLY -> A.anyWord8 *> object_' mkObject value_
295− OPEN_SQUARE -> A.anyWord8 *> array_' value_
296− C_f -> string "false" $> Bool False
297− C_t -> string "true" $> Bool True
298− C_n -> string "null" $> Null
190+ OPEN_CURLY -> A.anyWord8 *> object_'
191+ OPEN_SQUARE -> A.anyWord8 *> array_'
192+ C_f -> string "false" *> pure (Bool False)
193+ C_t -> string "true" *> pure (Bool True)
194+ C_n -> string "null" *> pure Null
299195 _ | w >= 48 && w <= 57 || w == 45
300196 -> do
301197 !n <- scientific
302198 return (Number n)
303199 | otherwise -> fail "not a valid json value"
304−{-# INLINE jsonWith' #-}
305−
306−-- | Variant of 'json'' which keeps only the last occurence of every key.
307−jsonLast' :: Parser Value
308−jsonLast' = jsonWith' (pure . H.fromListWith (const id))
309−
310−-- | Variant of 'json'' wrapping all object mappings in 'Array' to preserve
311−-- key-value pairs with the same keys.
312−jsonAccum' :: Parser Value
313−jsonAccum' = jsonWith' (pure . fromListAccum)
314−
315−-- | Variant of 'json'' which fails if any object contains duplicate keys.
316−jsonNoDup' :: Parser Value
317−jsonNoDup' = jsonWith' parseListNoDup
318200
319201-- | Parse a quoted JSON string.
320202jstring :: Parser Text
@@ -324,39 +206,21 @@ jstring = A.word8 DOUBLE_QUOTE *> jstring_
324206jstring_ :: Parser Text
325207{-# INLINE jstring_ #-}
326208jstring_ = {-# SCC "jstring_" #-} do
327−#if MIN_VERSION_ghc_prim(0,3,1)
328− (s, S _ escaped) <- A.runScanner startState go <* A.anyWord8
329− -- We escape only if there are
330− -- non-ascii (over 7bit) characters or backslash present.
331− --
332− -- Note: if/when text will have fast ascii -> text conversion
333− -- (e.g. uses utf8 encoding) we can have further speedup.
334− if isTrue# escaped
335− then case unescapeText s of
336− Right r -> return r
337− Left err -> fail $ show err
338− else return (TE.decodeUtf8 s)
339− where
340− startState = S 0# 0#
341− go (S skip escaped) (W8# c)
342− | isTrue# skip = Just (S 0# escaped')
343− | isTrue# (w ==# 34#) = Nothing -- double quote
344− | otherwise = Just (S skip' escaped')
345− where
346− w = word2Int# c
347− skip' = w ==# 92# -- backslash
348− escaped' = escaped
349− `orI#` (w `andI#` 0x80# ==# 0x80#) -- c >= 0x80
350− `orI#` skip'
351− `orI#` (w `andI#` 0x1f# ==# w) -- c < 0x20
352−
353−data S = S Int# Int#
354−#else
355209 s <- A.scan startState go <* A.anyWord8
356210 case unescapeText s of
357211 Right r -> return r
358212 Left err -> fail $ show err
359213 where
214+#if MIN_VERSION_ghc_prim(0,3,1)
215+ startState = S 0#
216+ go (S a) (W8# c)
217+ | isTrue# a = Just (S 0#)
218+ | isTrue# (word2Int# c ==# 34#) = Nothing -- double quote
219+ | otherwise = let a' = word2Int# c ==# 92# -- backslash
220+ in Just (S a')
221+
222+data S = S Int#
223+#else
360224 startState = False
361225 go a c
362226 | a = Just False
@@ -390,12 +254,7 @@ eitherDecodeWith p to s =
390254 L.Done _ v -> case to v of
391255 ISuccess a -> Right a
392256 IError path msg -> Left (path, msg)
393− L.Fail _ ctx msg -> Left ([], buildMsg ctx msg)
394− where
395− buildMsg :: [String] -> String -> String
396− buildMsg [] msg = msg
397− buildMsg (expectation:_) msg =
398− msg ++ ". Expecting " ++ expectation
257+ L.Fail _ _ msg -> Left ([], msg)
399258{-# INLINE eitherDecodeWith #-}
400259
401260eitherDecodeStrictWith :: Parser Value -> (Value -> IResult a) -> B.ByteString
@@ -434,104 +293,3 @@ jsonEOF = json <* skipSpace <* endOfInput
434293-- end-of-input. See also: 'json''.
435294jsonEOF' :: Parser Value
436295jsonEOF' = json' <* skipSpace <* endOfInput
437−
438−-- | The only valid whitespace in a JSON document is space, newline,
439−-- carriage return, and tab.
440−skipSpace :: Parser ()
441−skipSpace = A.skipWhile $ \w -> w == 0x20 || w == 0x0a || w == 0x0d || w == 0x09
442−{-# INLINE skipSpace #-}
443−
444−------------------ Copy-pasted and adapted from attoparsec ------------------
445−
446−-- A strict pair
447−data SP = SP !Integer {-# UNPACK #-}!Int
448−
449−decimal0 :: Parser Integer
450−decimal0 = do
451− let zero = 48
452− digits <- A.takeWhile1 isDigit_w8
453− if B.length digits > 1 && B.unsafeHead digits == zero
454− then fail "leading zero"
455− else return (bsToInteger digits)
456−
457−-- | Parse a JSON number.
458−scientific :: Parser Scientific
459−scientific = do
460− let minus = 45
461− plus = 43
462− sign <- A.peekWord8'
463− let !positive = sign == plus || sign /= minus
464− when (sign == plus || sign == minus) $
465− void A.anyWord8
466−
467− n <- decimal0
468−
469− let f fracDigits = SP (B.foldl' step n fracDigits)
470− (negate $ B.length fracDigits)
471− step a w = a * 10 + fromIntegral (w - 48)
472−
473− dotty <- A.peekWord8
474− -- '.' -> ascii 46
475− SP c e <- case dotty of
476− Just 46 -> A.anyWord8 *> (f <$> A.takeWhile1 isDigit_w8)
477− _ -> pure (SP n 0)
478−
479− let !signedCoeff | positive = c
480− | otherwise = -c
481−
482− let littleE = 101
483− bigE = 69
484− (A.satisfy (\ex -> ex == littleE || ex == bigE) *>
485− fmap (Sci.scientific signedCoeff . (e +)) (signed decimal)) <|>
486− return (Sci.scientific signedCoeff e)
487−{-# INLINE scientific #-}
488−
489−------------------ Copy-pasted and adapted from base ------------------------
490−
491−bsToInteger :: B.ByteString -> Integer
492−bsToInteger bs
493− | l > 40 = valInteger 10 l [ fromIntegral (w - 48) | w <- B.unpack bs ]
494− | otherwise = bsToIntegerSimple bs
495− where
496− l = B.length bs
497−
498−bsToIntegerSimple :: B.ByteString -> Integer
499−bsToIntegerSimple = B.foldl' step 0 where
500− step a b = a * 10 + fromIntegral (b - 48) -- 48 = '0'
501−
502−-- A sub-quadratic algorithm for Integer. Pairs of adjacent radix b
503−-- digits are combined into a single radix b^2 digit. This process is
504−-- repeated until we are left with a single digit. This algorithm
505−-- performs well only on large inputs, so we use the simple algorithm
506−-- for smaller inputs.
507−valInteger :: Integer -> Int -> [Integer] -> Integer
508−valInteger = go
509− where
510− go :: Integer -> Int -> [Integer] -> Integer
511− go _ _ [] = 0
512− go _ _ [d] = d
513− go b l ds
514− | l > 40 = b' `seq` go b' l' (combine b ds')
515− | otherwise = valSimple b ds
516− where
517− -- ensure that we have an even number of digits
518− -- before we call combine:
519− ds' = if even l then ds else 0 : ds
520− b' = b * b
521− l' = (l + 1) `quot` 2
522−
523− combine b (d1 : d2 : ds) = d `seq` (d : combine b ds)
524− where
525− d = d1 * b + d2
526− combine _ [] = []
527− combine _ [_] = errorWithoutStackTrace "this should not happen"
528−
529−-- The following algorithm is only linear for types whose Num operations
530−-- are in constant time.
531−valSimple :: Integer -> [Integer] -> Integer
532−valSimple base = go 0
533− where
534− go r [] = r
535− go r (d : ds) = r' `seq` go r' ds
536− where
537− r' = r * base + fromIntegral d
Data/Aeson/Parser/Time.hs+102−19
@@ -1,4 +1,15 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
1+{-# LANGUAGE BangPatterns #-}
2+{-# LANGUAGE ScopedTypeVariables #-}
3+
4+-- |
5+-- Module: Data.Aeson.Parser.Time
6+-- Copyright: (c) 2015-2016 Bryan O'Sullivan
7+-- License: BSD3
8+-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>
9+-- Stability: experimental
10+-- Portability: portable
11+--
12+-- Parsers for parsing dates and times.
213
314module Data.Aeson.Parser.Time
415 (
@@ -11,51 +22,121 @@ module Data.Aeson.Parser.Time
1122 , zonedTime
1223 ) where
1324
25+import Prelude ()
1426import Prelude.Compat
1527
16−import Data.Attoparsec.Text (Parser)
28+import Control.Monad (void, when)
29+import Data.Aeson.Internal.Time (toPico)
30+import Data.Attoparsec.Text as A
31+import Data.Bits ((.&.))
32+import Data.Char (isDigit, ord)
33+import Data.Fixed (Pico)
34+import Data.Int (Int64)
35+import Data.Maybe (fromMaybe)
1736import Data.Text (Text)
18−import Data.Time.Calendar (Day)
37+import Data.Time.Calendar (Day, fromGregorianValid)
1938import Data.Time.Clock (UTCTime(..))
2039import qualified Data.Aeson.Types.Internal as Aeson
21−import qualified Data.Attoparsec.Text as A
22−import qualified Data.Attoparsec.Time as T
40+import qualified Data.Text as T
2341import qualified Data.Time.LocalTime as Local
2442
2543-- | Run an attoparsec parser as an aeson parser.
2644run :: Parser a -> Text -> Aeson.Parser a
27−run p t = case A.parseOnly (p <* A.endOfInput) t of
45+run p t = case A.parseOnly (p <* endOfInput) t of
2846 Left err -> fail $ "could not parse date: " ++ err
2947 Right r -> return r
3048
31−-- | Parse a date of the form @[+,-]YYYY-MM-DD@.
49+-- | Parse a date of the form @YYYY-MM-DD@.
3250day :: Parser Day
33−day = T.day
34−{-# INLINE day #-}
51+day = do
52+ y <- decimal <* char '-'
53+ m <- twoDigits <* char '-'
54+ d <- twoDigits
55+ maybe (fail "invalid date") return (fromGregorianValid y m d)
56+
57+-- | Parse a two-digit integer (e.g. day of month, hour).
58+twoDigits :: Parser Int
59+twoDigits = do
60+ a <- digit
61+ b <- digit
62+ let c2d c = ord c .&. 15
63+ return $! c2d a * 10 + c2d b
3564
3665-- | Parse a time of the form @HH:MM[:SS[.SSS]]@.
3766timeOfDay :: Parser Local.TimeOfDay
38−timeOfDay = T.timeOfDay
39−{-# INLINE timeOfDay #-}
67+timeOfDay = do
68+ h <- twoDigits
69+ m <- char ':' *> twoDigits
70+ s <- option 0 (char ':' *> seconds)
71+ if h < 24 && m < 60 && s < 61
72+ then return (Local.TimeOfDay h m s)
73+ else fail "invalid time"
74+
75+data T = T {-# UNPACK #-} !Int {-# UNPACK #-} !Int64
76+
77+-- | Parse a count of seconds, with the integer part being two digits
78+-- long.
79+seconds :: Parser Pico
80+seconds = do
81+ real <- twoDigits
82+ mc <- peekChar
83+ case mc of
84+ Just '.' -> do
85+ t <- anyChar *> takeWhile1 isDigit
86+ return $! parsePicos real t
87+ _ -> return $! fromIntegral real
88+ where
89+ parsePicos a0 t = toPico (fromIntegral (t' * 10^n))
90+ where T n t' = T.foldl' step (T 12 (fromIntegral a0)) t
91+ step ma@(T m a) c
92+ | m <= 0 = ma
93+ | otherwise = T (m-1) (10 * a + fromIntegral (ord c) .&. 15)
4094
4195-- | Parse a time zone, and return 'Nothing' if the offset from UTC is
4296-- zero. (This makes some speedups possible.)
4397timeZone :: Parser (Maybe Local.TimeZone)
44−timeZone = T.timeZone
45−{-# INLINE timeZone #-}
98+timeZone = do
99+ let maybeSkip c = do ch <- peekChar'; when (ch == c) (void anyChar)
100+ maybeSkip ' '
101+ ch <- satisfy $ \c -> c == 'Z' || c == '+' || c == '-'
102+ if ch == 'Z'
103+ then return Nothing
104+ else do
105+ h <- twoDigits
106+ mm <- peekChar
107+ m <- case mm of
108+ Just ':' -> anyChar *> twoDigits
109+ Just d | isDigit d -> twoDigits
110+ _ -> return 0
111+ let off | ch == '-' = negate off0
112+ | otherwise = off0
113+ off0 = h * 60 + m
114+ case undefined of
115+ _ | off == 0 ->
116+ return Nothing
117+ | off < -720 || off > 840 || m > 59 ->
118+ fail "invalid time zone offset"
119+ | otherwise ->
120+ let !tz = Local.minutesToTimeZone off
121+ in return (Just tz)
46122
47123-- | Parse a date and time, of the form @YYYY-MM-DD HH:MM[:SS[.SSS]]@.
48124-- The space may be replaced with a @T@. The number of seconds is optional
49125-- and may be followed by a fractional component.
50126localTime :: Parser Local.LocalTime
51−localTime = T.localTime
52−{-# INLINE localTime #-}
127+localTime = Local.LocalTime <$> day <* daySep <*> timeOfDay
128+ where daySep = satisfy (\c -> c == 'T' || c == ' ')
53129
54130-- | Behaves as 'zonedTime', but converts any time zone offset into a
55131-- UTC time.
56132utcTime :: Parser UTCTime
57−utcTime = T.utcTime
58−{-# INLINE utcTime #-}
133+utcTime = do
134+ lt@(Local.LocalTime d t) <- localTime
135+ mtz <- timeZone
136+ case mtz of
137+ Nothing -> let !tt = Local.timeOfDayToTime t
138+ in return (UTCTime d tt)
139+ Just tz -> return $! Local.localTimeToUTC tz lt
59140
60141-- | Parse a date with time zone info. Acceptable formats:
61142--
@@ -69,5 +150,7 @@ utcTime = T.utcTime
69150-- two digits are hours, the @:@ is optional and the second two digits
70151-- (also optional) are minutes.
71152zonedTime :: Parser Local.ZonedTime
72−zonedTime = T.zonedTime
73−{-# INLINE zonedTime #-}
153+zonedTime = Local.ZonedTime <$> localTime <*> (fromMaybe utc <$> timeZone)
154+
155+utc :: Local.TimeZone
156+utc = Local.TimeZone 0 False ""
Data/Aeson/Parser/Unescape.hs+51−11
@@ -1,11 +1,51 @@
1−{-# LANGUAGE CPP #-}
2−module Data.Aeson.Parser.Unescape
3− (
4− unescapeText
5− ) where
6−
7−#ifdef CFFI
8−import Data.Aeson.Parser.UnescapeFFI (unescapeText)
9−#else
10−import Data.Aeson.Parser.UnescapePure (unescapeText)
11−#endif
1+{-# LANGUAGE ForeignFunctionInterface #-}
2+{-# LANGUAGE MagicHash #-}
3+{-# LANGUAGE UnliftedFFITypes #-}
4+
5+module Data.Aeson.Parser.Unescape (
6+ unescapeText
7+) where
8+
9+import Control.Exception (evaluate, throw, try)
10+import Control.Monad.ST.Unsafe (unsafeIOToST, unsafeSTToIO)
11+import Data.ByteString as B
12+import Data.ByteString.Internal as B hiding (c2w)
13+import qualified Data.Text.Array as A
14+import Data.Text.Encoding.Error (UnicodeException (..))
15+import Data.Text.Internal (Text (..))
16+import Data.Text.Internal.Private (runText)
17+import Data.Text.Unsafe (unsafeDupablePerformIO)
18+import Data.Word (Word8)
19+import Foreign.C.Types (CInt (..), CSize (..))
20+import Foreign.ForeignPtr (withForeignPtr)
21+import Foreign.Marshal.Utils (with)
22+import Foreign.Ptr (Ptr, plusPtr)
23+import Foreign.Storable (peek)
24+import GHC.Base (MutableByteArray#)
25+
26+foreign import ccall unsafe "_js_decode_string" c_js_decode
27+ :: MutableByteArray# s -> Ptr CSize
28+ -> Ptr Word8 -> Ptr Word8 -> IO CInt
29+
30+unescapeText' :: ByteString -> Text
31+unescapeText' (PS fp off len) = runText $ \done -> do
32+ let go dest = withForeignPtr fp $ \ptr ->
33+ with (0::CSize) $ \destOffPtr -> do
34+ let end = ptr `plusPtr` (off + len)
35+ loop curPtr = do
36+ res <- c_js_decode (A.maBA dest) destOffPtr curPtr end
37+ case res of
38+ 0 -> do
39+ n <- peek destOffPtr
40+ unsafeSTToIO (done dest (fromIntegral n))
41+ _ ->
42+ throw (DecodeError desc Nothing)
43+ loop (ptr `plusPtr` off)
44+ (unsafeIOToST . go) =<< A.new len
45+ where
46+ desc = "Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream"
47+{-# INLINE unescapeText' #-}
48+
49+unescapeText :: ByteString -> Either UnicodeException Text
50+unescapeText = unsafeDupablePerformIO . try . evaluate . unescapeText'
51+{-# INLINE unescapeText #-}
Data/Aeson/QQ/Simple.hsdeleted−25
@@ -1,25 +0,0 @@
1−-- | Like "Data.Aeson.QQ" but without interpolation.
2−module Data.Aeson.QQ.Simple (aesonQQ) where
3−
4−import Data.Aeson
5−import qualified Data.Text as T
6−import qualified Data.Text.Encoding as TE
7−import Language.Haskell.TH
8−import Language.Haskell.TH.Quote
9−import Language.Haskell.TH.Syntax (Lift (..))
10−import Prelude ()
11−import Prelude.Compat
12−
13−aesonQQ :: QuasiQuoter
14−aesonQQ = QuasiQuoter
15− { quoteExp = aesonExp
16− , quotePat = const $ error "No quotePat defined for jsonQQ"
17− , quoteType = const $ error "No quoteType defined for jsonQQ"
18− , quoteDec = const $ error "No quoteDec defined for jsonQQ"
19− }
20−
21−aesonExp :: String -> ExpQ
22−aesonExp txt =
23− case eitherDecodeStrict $ TE.encodeUtf8 $ T.pack txt of
24− Left err -> error $ "Error in aesonExp: " ++ show err
25− Right val -> lift (val :: Value)
Data/Aeson/TH.hs+897−447
@@ -13,7 +13,6 @@
1313{-# LANGUAGE TemplateHaskell #-}
1414#endif
1515
16−#include "incoherent-compat.h"
1716#include "overlapping-compat.h"
1817
1918{-|
@@ -85,6 +84,7 @@ $('deriveJSON' 'defaultOptions' ''(,,,))
8584@
8685
8786-}
87+
8888module Data.Aeson.TH
8989 (
9090 -- * Encoding configuration
@@ -116,42 +116,49 @@ module Data.Aeson.TH
116116 , mkLiftParseJSON2
117117 ) where
118118
119−import Prelude.Compat
119+import Prelude ()
120+import Prelude.Compat hiding (exp)
120121
121122import Control.Applicative ((<|>))
122−import Data.Aeson (Object, (.:), FromJSON(..), FromJSON1(..), FromJSON2(..), ToJSON(..), ToJSON1(..), ToJSON2(..))
123+import Data.Aeson (Object, (.=), (.:), FromJSON(..), FromJSON1(..), FromJSON2(..), ToJSON(..), ToJSON1(..), ToJSON2(..))
123124import Data.Aeson.Types (Options(..), Parser, SumEncoding(..), Value(..), defaultOptions, defaultTaggedObject)
124−import Data.Aeson.Types.Internal ((<?>), JSONPathElement(Key))
125+import Data.Aeson.Types.Internal ((<?>), Pair, JSONPathElement(Key))
125126import Data.Aeson.Types.FromJSON (parseOptionalFieldWith)
126−import Data.Aeson.Types.ToJSON (fromPairs, pair)
127127import Control.Monad (liftM2, unless, when)
128128import Data.Foldable (foldr')
129129#if MIN_VERSION_template_haskell(2,8,0) && !MIN_VERSION_template_haskell(2,10,0)
130130import Data.List (nub)
131131#endif
132−import Data.List (foldl', genericLength, intercalate, partition, union)
132+import Data.List (find, foldl', genericLength , intercalate , intersperse, partition, union)
133133import Data.List.NonEmpty ((<|), NonEmpty((:|)))
134134import Data.Map (Map)
135135import Data.Maybe (catMaybes, fromMaybe, mapMaybe)
136−import qualified Data.Monoid as Monoid
137136import Data.Set (Set)
137+#if MIN_VERSION_template_haskell(2,8,0)
138138import Language.Haskell.TH hiding (Arity)
139−import Language.Haskell.TH.Datatype
139+#else
140+import Language.Haskell.TH
141+#endif
142+import Language.Haskell.TH.Syntax (VarStrictType)
143+#if MIN_VERSION_template_haskell(2,7,0) && !(MIN_VERSION_template_haskell(2,8,0))
144+import Language.Haskell.TH.Lib (starK)
145+#endif
140146#if MIN_VERSION_template_haskell(2,8,0) && !(MIN_VERSION_template_haskell(2,10,0))
141147import Language.Haskell.TH.Syntax (mkNameG_tc)
142148#endif
143149import Text.Printf (printf)
150+import qualified Data.Aeson as A
144151import qualified Data.Aeson.Encoding.Internal as E
145152import qualified Data.Foldable as F (all)
146−import qualified Data.HashMap.Strict as H (difference, fromList, keys, lookup, toList)
147−import qualified Data.List.NonEmpty as NE (length, reverse)
148−import qualified Data.Map as M (fromList, keys, lookup , singleton, size)
149−import qualified Data.Semigroup as Semigroup (Option(..))
153+import qualified Data.HashMap.Strict as H (lookup, toList)
154+import qualified Data.List.NonEmpty as NE (drop, length, reverse, splitAt)
155+import qualified Data.Map as M (fromList, findWithDefault, keys, lookup , singleton, size)
150156import qualified Data.Set as Set (empty, insert, member)
151157import qualified Data.Text as T (Text, pack, unpack)
152−import qualified Data.Vector as V (unsafeIndex, null, length, create, empty)
158+import qualified Data.Vector as V (unsafeIndex, null, length, create, fromList)
153159import qualified Data.Vector.Mutable as VM (unsafeNew, unsafeWrite)
154160
161+
155162--------------------------------------------------------------------------------
156163-- Convenience
157164--------------------------------------------------------------------------------
@@ -245,8 +252,8 @@ deriveToJSONCommon :: JSONClass
245252 -> Name
246253 -- ^ Name of the type for which to generate an instance.
247254 -> Q [Dec]
248−deriveToJSONCommon = deriveJSONClass [ (ToJSON, \jc _ -> consToValue Value jc)
249− , (ToEncoding, \jc _ -> consToValue Encoding jc)
255+deriveToJSONCommon = deriveJSONClass [ (ToJSON, \jc _ -> consToValue jc)
256+ , (ToEncoding, \jc _ -> consToEncoding jc)
250257 ]
251258
252259-- | Generates a lambda expression which encodes the given data type or
@@ -276,7 +283,7 @@ mkToJSONCommon :: JSONClass -- ^ Which class's method is being derived.
276283 -> Options -- ^ Encoding options.
277284 -> Name -- ^ Name of the encoded type.
278285 -> Q Exp
279−mkToJSONCommon = mkFunCommon (\jc _ -> consToValue Value jc)
286+mkToJSONCommon = mkFunCommon (\jc _ -> consToValue jc)
280287
281288-- | Generates a lambda expression which encodes the given data type or
282289-- data family instance constructor as a JSON string.
@@ -305,272 +312,413 @@ mkToEncodingCommon :: JSONClass -- ^ Which class's method is being derived.
305312 -> Options -- ^ Encoding options.
306313 -> Name -- ^ Name of the encoded type.
307314 -> Q Exp
308−mkToEncodingCommon = mkFunCommon (\jc _ -> consToValue Encoding jc)
315+mkToEncodingCommon = mkFunCommon (\jc _ -> consToEncoding jc)
309316
310317-- | Helper function used by both 'deriveToJSON' and 'mkToJSON'. Generates
311−-- code to generate a 'Value' or 'Encoding' of a number of constructors. All
312−-- constructors must be from the same type.
313−consToValue :: ToJSONFun
314− -- ^ The method ('toJSON' or 'toEncoding') being derived.
315− -> JSONClass
318+-- code to generate a 'Value' of a number of constructors. All constructors
319+-- must be from the same type.
320+consToValue :: JSONClass
316321 -- ^ The ToJSON variant being derived.
317322 -> Options
318323 -- ^ Encoding options.
319− -> [Type]
320− -- ^ The types from the data type/data family instance declaration
321− -> [ConstructorInfo]
324+ -> [Con]
322325 -- ^ Constructors for which to generate JSON generating code.
323326 -> Q Exp
324327
325−consToValue _ _ _ _ [] = error $ "Data.Aeson.TH.consToValue: "
326− ++ "Not a single constructor given!"
328+consToValue _ _ [] = error $ "Data.Aeson.TH.consToValue: "
329+ ++ "Not a single constructor given!"
327330
328−consToValue target jc opts instTys cons = do
331+consToValue jc opts cons = do
329332 value <- newName "value"
330333 tjs <- newNameList "_tj" $ arityInt jc
331334 tjls <- newNameList "_tjl" $ arityInt jc
332335 let zippedTJs = zip tjs tjls
333336 interleavedTJs = interleave tjs tjls
334− lastTyVars = map varTToName $ drop (length instTys - arityInt jc) instTys
335− tvMap = M.fromList $ zip lastTyVars zippedTJs
336337 lamE (map varP $ interleavedTJs ++ [value]) $
337− caseE (varE value) (matches tvMap)
338+ caseE (varE value) (matches zippedTJs)
338339 where
339− matches tvMap = case cons of
340+ matches tjs = case cons of
340341 -- A single constructor is directly encoded. The constructor itself may be
341342 -- forgotten.
342− [con] | not (tagSingleConstructors opts) -> [argsToValue target jc tvMap opts False con]
343+ [con] -> [argsToValue jc tjs opts False con]
343344 _ | allNullaryToStringTag opts && all isNullary cons ->
344− [ match (conP conName []) (normalB $ conStr target opts conName) []
345+ [ match (conP conName []) (normalB $ conStr opts conName) []
345346 | con <- cons
346− , let conName = constructorName con
347+ , let conName = getConName con
347348 ]
348− | otherwise -> [argsToValue target jc tvMap opts True con | con <- cons]
349+ | otherwise -> [argsToValue jc tjs opts True con | con <- cons]
349350
350−-- | Name of the constructor as a quoted 'Value' or 'Encoding'.
351−conStr :: ToJSONFun -> Options -> Name -> Q Exp
352−conStr Value opts = appE [|String|] . conTxt opts
353−conStr Encoding opts = appE [|E.text|] . conTxt opts
351+conStr :: Options -> Name -> Q Exp
352+conStr opts = appE [|String|] . conTxt opts
354353
355−-- | Name of the constructor as a quoted 'Text'.
356354conTxt :: Options -> Name -> Q Exp
357−conTxt opts = appE [|T.pack|] . stringE . conString opts
355+conTxt opts = appE [|T.pack|] . conStringE opts
356+
357+conStringE :: Options -> Name -> Q Exp
358+conStringE opts = stringE . constructorTagModifier opts . nameBase
359+
360+-- | Helper function used by both 'deriveToJSON' and 'mkToEncoding'. Generates
361+-- code to write out a value for a number of constructors. All constructors
362+-- must be from the same type.
363+consToEncoding :: JSONClass
364+ -- ^ The ToJSON variant being derived.
365+ -> Options
366+ -- ^ Encoding options.
367+ -> [Con]
368+ -- ^ Constructors for which to generate JSON generating code.
369+ -> Q Exp
370+
371+consToEncoding _ _ [] = error $ "Data.Aeson.TH.consToEncoding: "
372+ ++ "Not a single constructor given!"
373+
374+consToEncoding jc opts cons = do
375+ value <- newName "value"
376+ tes <- newNameList "_te" $ arityInt jc
377+ tels <- newNameList "_tel" $ arityInt jc
378+ let zippedTEs = zip tes tels
379+ interleavedTEs = interleave tes tels
380+ lamE (map varP $ interleavedTEs ++ [value]) $
381+ caseE (varE value) (matches zippedTEs)
382+ where
383+ matches tes = case cons of
384+ -- A single constructor is directly encoded. The constructor itself may be
385+ -- forgotten.
386+ [con] -> [argsToEncoding jc tes opts False con]
387+ -- Encode just the name of the constructor of a sum type iff all the
388+ -- constructors are nullary.
389+ _ | allNullaryToStringTag opts && all isNullary cons ->
390+ [ match (conP conName [])
391+ (normalB $ encStr opts conName) []
392+ | con <- cons
393+ , let conName = getConName con
394+ ]
395+ | otherwise -> [argsToEncoding jc tes opts True con | con <- cons]
358396
359−-- | Name of the constructor.
360−conString :: Options -> Name -> String
361−conString opts = constructorTagModifier opts . nameBase
397+encStr :: Options -> Name -> Q Exp
398+encStr opts = appE [|E.text|] . conTxt opts
362399
363400-- | If constructor is nullary.
364−isNullary :: ConstructorInfo -> Bool
365−isNullary ConstructorInfo { constructorVariant = NormalConstructor
366− , constructorFields = tys } = null tys
401+isNullary :: Con -> Bool
402+isNullary (NormalC _ []) = True
367403isNullary _ = False
368404
369−-- | Wrap fields of a non-record constructor. See 'sumToValue'.
370−opaqueSumToValue :: ToJSONFun -> Options -> Bool -> Bool -> Name -> ExpQ -> ExpQ
371−opaqueSumToValue target opts multiCons nullary conName value =
372− sumToValue target opts multiCons nullary conName
373− value
374− pairs
375− where
376− pairs contentsFieldName = pairE contentsFieldName value
377−
378−-- | Wrap fields of a record constructor. See 'sumToValue'.
379−recordSumToValue :: ToJSONFun -> Options -> Bool -> Bool -> Name -> ExpQ -> ExpQ
380−recordSumToValue target opts multiCons nullary conName pairs =
381− sumToValue target opts multiCons nullary conName
382− (fromPairsE pairs)
383− (const pairs)
384−
385−-- | Wrap fields of a constructor.
386−sumToValue
387− :: ToJSONFun
388− -- ^ The method being derived.
389− -> Options
390− -- ^ Deriving options.
391− -> Bool
392− -- ^ Does this type have multiple constructors.
393− -> Bool
394− -- ^ Is this constructor nullary.
395− -> Name
396− -- ^ Constructor name.
397− -> ExpQ
398− -- ^ Fields of the constructor as a 'Value' or 'Encoding'.
399− -> (String -> ExpQ)
400− -- ^ Representation of an 'Object' fragment used for the 'TaggedObject'
401− -- variant; of type @[(Text,Value)]@ or @[Encoding]@, depending on the method
402− -- being derived.
403− --
404− -- - For non-records, produces a pair @"contentsFieldName":value@,
405− -- given a @contentsFieldName@ as an argument. See 'opaqueSumToValue'.
406− -- - For records, produces the list of pairs corresponding to fields of the
407− -- encoded value (ignores the argument). See 'recordSumToValue'.
408− -> ExpQ
409−sumToValue target opts multiCons nullary conName value pairs
405+sumToValue :: Options -> Bool -> Name -> Q Exp -> Q Exp
406+sumToValue opts multiCons conName exp
410407 | multiCons =
411408 case sumEncoding opts of
412409 TwoElemArray ->
413− array target [conStr target opts conName, value]
410+ [|Array|] `appE` ([|V.fromList|] `appE` listE [conStr opts conName, exp])
414411 TaggedObject{tagFieldName, contentsFieldName} ->
415− -- TODO: Maybe throw an error in case
416− -- tagFieldName overwrites a field in pairs.
417− let tag = pairE tagFieldName (conStr target opts conName)
418− content = pairs contentsFieldName
419− in fromPairsE $
420− if nullary then tag else infixApp tag [|(Monoid.<>)|] content
412+ [|A.object|] `appE` listE
413+ [ infixApp [|T.pack tagFieldName|] [|(.=)|] (conStr opts conName)
414+ , infixApp [|T.pack contentsFieldName|] [|(.=)|] exp
415+ ]
421416 ObjectWithSingleField ->
422− objectE [(conString opts conName, value)]
423− UntaggedValue | nullary -> conStr target opts conName
424− UntaggedValue -> value
425− | otherwise = value
417+ [|A.object|] `appE` listE
418+ [ infixApp (conTxt opts conName) [|(.=)|] exp
419+ ]
420+ UntaggedValue -> exp
421+ | otherwise = exp
422+
423+nullarySumToValue :: Options -> Bool -> Name -> Q Exp
424+nullarySumToValue opts multiCons conName =
425+ case sumEncoding opts of
426+ TaggedObject{tagFieldName} ->
427+ [|A.object|] `appE` listE
428+ [ infixApp [|T.pack tagFieldName|] [|(.=)|] (conStr opts conName)
429+ ]
430+ UntaggedValue -> conStr opts conName
431+ _ -> sumToValue opts multiCons conName [e|toJSON ([] :: [()])|]
426432
427433-- | Generates code to generate the JSON encoding of a single constructor.
428−argsToValue :: ToJSONFun -> JSONClass -> TyVarMap -> Options -> Bool -> ConstructorInfo -> Q Match
434+argsToValue :: JSONClass -> [(Name, Name)] -> Options -> Bool -> Con -> Q Match
435+-- Nullary constructors. Generates code that explicitly matches against the
436+-- constructor even though it doesn't contain data. This is useful to prevent
437+-- type errors.
438+argsToValue jc tjs opts multiCons (NormalC conName []) = do
439+ ([], _) <- reifyConTys jc tjs conName
440+ match (conP conName [])
441+ (normalB (nullarySumToValue opts multiCons conName))
442+ []
429443
430444-- Polyadic constructors with special case for unary constructors.
431−argsToValue target jc tvMap opts multiCons
432− ConstructorInfo { constructorName = conName
433− , constructorVariant = NormalConstructor
434− , constructorFields = argTys } = do
435− argTys' <- mapM resolveTypeSynonyms argTys
436− let len = length argTys'
445+argsToValue jc tjs opts multiCons (NormalC conName ts) = do
446+ (argTys, tvMap) <- reifyConTys jc tjs conName
447+ let len = length ts
437448 args <- newNameList "arg" len
438− let js = case [ dispatchToJSON target jc conName tvMap argTy
439− `appE` varE arg
440− | (arg, argTy) <- zip args argTys'
441− ] of
442− -- Single argument is directly converted.
443− [e] -> e
444− -- Zero and multiple arguments are converted to a JSON array.
445− es -> array target es
446−
449+ js <- case [ dispatchToJSON jc conName tvMap argTy
450+ `appE` varE arg
451+ | (arg, argTy) <- zip args argTys
452+ ] of
453+ -- Single argument is directly converted.
454+ [e] -> return e
455+ -- Multiple arguments are converted to a JSON array.
456+ es -> do
457+ mv <- newName "mv"
458+ let newMV = bindS (varP mv)
459+ ([|VM.unsafeNew|] `appE`
460+ litE (integerL $ fromIntegral len))
461+ stmts = [ noBindS $
462+ [|VM.unsafeWrite|] `appE`
463+ varE mv `appE`
464+ litE (integerL ix) `appE`
465+ e
466+ | (ix, e) <- zip [(0::Integer)..] es
467+ ]
468+ ret = noBindS $ [|return|] `appE` varE mv
469+ return $ [|Array|] `appE`
470+ (varE 'V.create `appE`
471+ doE (newMV:stmts++[ret]))
447472 match (conP conName $ map varP args)
448− (normalB $ opaqueSumToValue target opts multiCons (null argTys') conName js)
473+ (normalB $ sumToValue opts multiCons conName js)
449474 []
450475
451476-- Records.
452−argsToValue target jc tvMap opts multiCons
453− info@ConstructorInfo { constructorName = conName
454− , constructorVariant = RecordConstructor fields
455− , constructorFields = argTys } =
456− case (unwrapUnaryRecords opts, not multiCons, argTys) of
457− (True,True,[_]) -> argsToValue target jc tvMap opts multiCons
458− (info{constructorVariant = NormalConstructor})
459− _ -> do
460− argTys' <- mapM resolveTypeSynonyms argTys
461− args <- newNameList "arg" $ length argTys'
462− let pairs | omitNothingFields opts = infixApp maybeFields
463− [|(Monoid.<>)|]
464− restFields
465− | otherwise = mconcatE (map pureToPair argCons)
466−
467− argCons = zip3 (map varE args) argTys' fields
468−
469− maybeFields = mconcatE (map maybeToPair maybes)
470−
471− restFields = mconcatE (map pureToPair rest)
472−
473− (maybes0, rest0) = partition isMaybe argCons
474− (options, rest) = partition isOption rest0
475− maybes = maybes0 ++ map optionToMaybe options
476−
477− maybeToPair = toPairLifted True
478− pureToPair = toPairLifted False
479−
480− toPairLifted lifted (arg, argTy, field) =
481− let toValue = dispatchToJSON target jc conName tvMap argTy
482− fieldName = fieldLabel opts field
483− e arg' = pairE fieldName (toValue `appE` arg')
484− in if lifted
485− then do
486− x <- newName "x"
487− [|maybe mempty|] `appE` lam1E (varP x) (e (varE x)) `appE` arg
488− else e arg
489−
490− match (conP conName $ map varP args)
491− (normalB $ recordSumToValue target opts multiCons (null argTys) conName pairs)
492− []
477+argsToValue jc tjs opts multiCons (RecC conName ts) = case (unwrapUnaryRecords opts, not multiCons, ts) of
478+ (True,True,[(_,st,ty)]) -> argsToValue jc tjs opts multiCons (NormalC conName [(st,ty)])
479+ _ -> do
480+ (argTys, tvMap) <- reifyConTys jc tjs conName
481+ args <- newNameList "arg" $ length ts
482+ let exp = [|A.object|] `appE` pairs
483+
484+ pairs | omitNothingFields opts = infixApp maybeFields
485+ [|(++)|]
486+ restFields
487+ | otherwise = listE $ map toPair argCons
488+
489+ argCons = zip3 args argTys ts
490+
491+ maybeFields = [|catMaybes|] `appE` listE (map maybeToPair maybes)
492+
493+ restFields = listE $ map toPair rest
494+
495+ (maybes, rest) = partition isMaybe argCons
496+
497+ maybeToPair (arg, argTy, (field, _, _)) =
498+ infixApp ([|keyValuePairWith|]
499+ `appE` dispatchToJSON jc conName tvMap argTy
500+ `appE` toFieldName field)
501+ [|(<$>)|]
502+ (varE arg)
503+
504+ toPair (arg, argTy, (field, _, _)) =
505+ [|keyValuePairWith|]
506+ `appE` dispatchToJSON jc conName tvMap argTy
507+ `appE` toFieldName field
508+ `appE` varE arg
509+
510+ toFieldName field = [|T.pack|] `appE` fieldLabelExp opts field
511+
512+ match (conP conName $ map varP args)
513+ ( normalB
514+ $ if multiCons
515+ then case sumEncoding opts of
516+ TwoElemArray -> [|toJSON|] `appE` tupE [conStr opts conName, exp]
517+ TaggedObject{tagFieldName} ->
518+ [|A.object|] `appE`
519+ -- TODO: Maybe throw an error in case
520+ -- tagFieldName overwrites a field in pairs.
521+ infixApp (infixApp [|T.pack tagFieldName|]
522+ [|(.=)|]
523+ (conStr opts conName))
524+ [|(:)|]
525+ pairs
526+ ObjectWithSingleField ->
527+ [|A.object|] `appE` listE
528+ [ infixApp (conTxt opts conName) [|(.=)|] exp ]
529+ UntaggedValue -> exp
530+ else exp
531+ ) []
493532
494533-- Infix constructors.
495−argsToValue target jc tvMap opts multiCons
496− ConstructorInfo { constructorName = conName
497− , constructorVariant = InfixConstructor
498− , constructorFields = argTys } = do
499− [alTy, arTy] <- mapM resolveTypeSynonyms argTys
534+argsToValue jc tjs opts multiCons (InfixC _ conName _) = do
535+ ([alTy, arTy], tvMap) <- reifyConTys jc tjs conName
500536 al <- newName "argL"
501537 ar <- newName "argR"
502538 match (infixP (varP al) conName (varP ar))
503539 ( normalB
504− $ opaqueSumToValue target opts multiCons False conName
505− $ array target
506− [ dispatchToJSON target jc conName tvMap aTy
507− `appE` varE a
508− | (a, aTy) <- [(al,alTy), (ar,arTy)]
509− ]
540+ $ sumToValue opts multiCons conName
541+ $ [|toJSON|] `appE` listE [ dispatchToJSON jc conName tvMap aTy
542+ `appE` varE a
543+ | (a, aTy) <- [(al,alTy), (ar,arTy)]
544+ ]
510545 )
511546 []
547+-- Existentially quantified constructors.
548+argsToValue jc tjs opts multiCons (ForallC _ _ con) =
549+ argsToValue jc tjs opts multiCons con
512550
513−isMaybe :: (a, Type, b) -> Bool
514−isMaybe (_, AppT (ConT t) _, _) = t == ''Maybe
515−isMaybe _ = False
551+#if MIN_VERSION_template_haskell(2,11,0)
552+-- GADTs.
553+argsToValue jc tjs opts multiCons (GadtC conNames ts _) =
554+ argsToValue jc tjs opts multiCons $ NormalC (head conNames) ts
516555
517−isOption :: (a, Type, b) -> Bool
518−isOption (_, AppT (ConT t) _, _) = t == ''Semigroup.Option
519−isOption _ = False
556+argsToValue jc tjs opts multiCons (RecGadtC conNames ts _) =
557+ argsToValue jc tjs opts multiCons $ RecC (head conNames) ts
558+#endif
520559
521−optionToMaybe :: (ExpQ, b, c) -> (ExpQ, b, c)
522−optionToMaybe (a, b, c) = ([|Semigroup.getOption|] `appE` a, b, c)
560+isMaybe :: (a, b, (c, d, Type)) -> Bool
561+isMaybe (_, _, (_, _, AppT (ConT t) _)) = t == ''Maybe
562+isMaybe _ = False
523563
524564(<^>) :: ExpQ -> ExpQ -> ExpQ
525565(<^>) a b = infixApp a [|(E.><)|] b
526566infixr 6 <^>
527567
568+(<:>) :: ExpQ -> ExpQ -> ExpQ
569+(<:>) a b = a <^> [|E.colon|] <^> b
570+infixr 5 <:>
571+
528572(<%>) :: ExpQ -> ExpQ -> ExpQ
529573(<%>) a b = a <^> [|E.comma|] <^> b
530574infixr 4 <%>
531575
532−-- | Wrap a list of quoted 'Value's in a quoted 'Array' (of type 'Value').
533−array :: ToJSONFun -> [ExpQ] -> ExpQ
534−array Encoding [] = [|E.emptyArray_|]
535−array Value [] = [|Array V.empty|]
536−array Encoding es = [|E.wrapArray|] `appE` foldr1 (<%>) es
537−array Value es = do
538− mv <- newName "mv"
539− let newMV = bindS (varP mv)
540− ([|VM.unsafeNew|] `appE`
541− litE (integerL $ fromIntegral (length es)))
542− stmts = [ noBindS $
543− [|VM.unsafeWrite|] `appE`
544− varE mv `appE`
545− litE (integerL ix) `appE`
546− e
547− | (ix, e) <- zip [(0::Integer)..] es
548− ]
549− ret = noBindS $ [|return|] `appE` varE mv
550− [|Array|] `appE`
551− (varE 'V.create `appE`
552− doE (newMV:stmts++[ret]))
576+array :: ExpQ -> ExpQ
577+array exp = [|E.wrapArray|] `appE` exp
553578
554−-- | Wrap an associative list of keys and quoted values in a quoted 'Object'.
555−objectE :: [(String, ExpQ)] -> ExpQ
556−objectE = fromPairsE . mconcatE . fmap (uncurry pairE)
579+object :: ExpQ -> ExpQ
580+object exp = [|E.wrapObject|] `appE` exp
557581
558−-- | 'mconcat' a list of fixed length.
559−--
560−-- > mconcatE [ [|x|], [|y|], [|z|] ] = [| x <> (y <> z) |]
561−mconcatE :: [ExpQ] -> ExpQ
562−mconcatE [] = [|Monoid.mempty|]
563−mconcatE [x] = x
564−mconcatE (x : xs) = infixApp x [|(Monoid.<>)|] (mconcatE xs)
582+sumToEncoding :: Options -> Bool -> Name -> Q Exp -> Q Exp
583+sumToEncoding opts multiCons conName exp
584+ | multiCons =
585+ let fexp = exp in
586+ case sumEncoding opts of
587+ TwoElemArray ->
588+ array (encStr opts conName <%> fexp)
589+ TaggedObject{tagFieldName, contentsFieldName} ->
590+ object $
591+ ([|E.text (T.pack tagFieldName)|] <:> encStr opts conName) <%>
592+ ([|E.text (T.pack contentsFieldName)|] <:> fexp)
593+ ObjectWithSingleField ->
594+ object (encStr opts conName <:> fexp)
595+ UntaggedValue -> exp
596+ | otherwise = exp
597+
598+nullarySumToEncoding :: Options -> Bool -> Name -> Q Exp
599+nullarySumToEncoding opts multiCons conName =
600+ case sumEncoding opts of
601+ TaggedObject{tagFieldName} ->
602+ object $
603+ [|E.text (T.pack tagFieldName)|] <:> encStr opts conName
604+ UntaggedValue -> encStr opts conName
605+ _ -> sumToEncoding opts multiCons conName [e|toEncoding ([] :: [()])|]
565606
566−fromPairsE :: ExpQ -> ExpQ
567−fromPairsE = ([|fromPairs|] `appE`)
607+-- | Generates code to generate the JSON encoding of a single constructor.
608+argsToEncoding :: JSONClass -> [(Name, Name)] -> Options -> Bool -> Con -> Q Match
609+-- Nullary constructors. Generates code that explicitly matches against the
610+-- constructor even though it doesn't contain data. This is useful to prevent
611+-- type errors.
612+argsToEncoding jc tes opts multiCons (NormalC conName []) = do
613+ ([], _) <- reifyConTys jc tes conName
614+ match (conP conName [])
615+ (normalB (nullarySumToEncoding opts multiCons conName))
616+ []
568617
569−-- | Create (an encoding of) a key-value pair.
570−--
571−-- > pairE "k" [|v|] = [|pair "k" v|]
572−pairE :: String -> ExpQ -> ExpQ
573−pairE k v = [|pair k|] `appE` v
618+-- Polyadic constructors with special case for unary constructors.
619+argsToEncoding jc tes opts multiCons (NormalC conName ts) = do
620+ (argTys, tvMap) <- reifyConTys jc tes conName
621+ let len = length ts
622+ args <- newNameList "arg" len
623+ js <- case zip args argTys of
624+ -- Single argument is directly converted.
625+ [(e,eTy)] -> return (dispatchToEncoding jc conName tvMap eTy
626+ `appE` varE e)
627+ -- Multiple arguments are converted to a JSON array.
628+ es ->
629+ return (array (foldr1 (<%>) [ dispatchToEncoding jc conName tvMap xTy
630+ `appE` varE x
631+ | (x,xTy) <- es
632+ ]))
633+ match (conP conName $ map varP args)
634+ (normalB $ sumToEncoding opts multiCons conName js)
635+ []
636+
637+-- Records.
638+argsToEncoding jc tes opts multiCons (RecC conName ts) = case (unwrapUnaryRecords opts, not multiCons, ts) of
639+ (True,True,[(_,st,ty)]) -> argsToEncoding jc tes opts multiCons (NormalC conName [(st,ty)])
640+ _ -> do
641+ args <- newNameList "arg" $ length ts
642+ (argTys, tvMap) <- reifyConTys jc tes conName
643+ let exp = object objBody
644+
645+ objBody = [|E.econcat|] `appE`
646+ ([|intersperse E.comma|] `appE` pairs)
647+ pairs | omitNothingFields opts = infixApp maybeFields
648+ [|(++)|]
649+ restFields
650+ | otherwise = listE (map toPair argCons)
651+
652+ argCons = zip3 args argTys ts
653+
654+ maybeFields = [|catMaybes|] `appE` listE (map maybeToPair maybes)
655+
656+ restFields = listE (map toPair rest)
657+
658+ (maybes, rest) = partition isMaybe argCons
659+
660+ maybeToPair (arg, argTy, (field, _, _)) =
661+ infixApp
662+ (infixApp
663+ (infixE
664+ (Just $ toFieldName field <^> [|E.colon|])
665+ [|(E.><)|]
666+ Nothing)
667+ [|(.)|]
668+ (dispatchToEncoding jc conName tvMap argTy))
669+ [|(<$>)|]
670+ (varE arg)
671+
672+ toPair (arg, argTy, (field, _, _)) =
673+ toFieldName field
674+ <:> dispatchToEncoding jc conName tvMap argTy
675+ `appE` varE arg
676+
677+ toFieldName field = [|E.text|] `appE`
678+ ([|T.pack|] `appE` fieldLabelExp opts field)
679+
680+ match (conP conName $ map varP args)
681+ ( normalB
682+ $ if multiCons
683+ then case sumEncoding opts of
684+ TwoElemArray -> array $
685+ encStr opts conName <%> exp
686+ TaggedObject{tagFieldName} -> object $
687+ ([|E.text (T.pack tagFieldName)|] <:>
688+ encStr opts conName) <%>
689+ objBody
690+ ObjectWithSingleField -> object $
691+ encStr opts conName <:> exp
692+ UntaggedValue -> exp
693+ else exp
694+ ) []
695+
696+-- Infix constructors.
697+argsToEncoding jc tes opts multiCons (InfixC _ conName _) = do
698+ al <- newName "argL"
699+ ar <- newName "argR"
700+ ([alTy,arTy], tvMap) <- reifyConTys jc tes conName
701+ match (infixP (varP al) conName (varP ar))
702+ ( normalB
703+ $ sumToEncoding opts multiCons conName
704+ $ array (foldr1 (<%>) [ dispatchToEncoding jc conName tvMap aTy
705+ `appE` varE a
706+ | (a,aTy) <- [(al,alTy), (ar,arTy)]
707+ ])
708+ )
709+ []
710+-- Existentially quantified constructors.
711+argsToEncoding jc tes opts multiCons (ForallC _ _ con) =
712+ argsToEncoding jc tes opts multiCons con
713+
714+#if MIN_VERSION_template_haskell(2,11,0)
715+-- GADTs.
716+argsToEncoding jc tes opts multiCons (GadtC conNames ts _) =
717+ argsToEncoding jc tes opts multiCons $ NormalC (head conNames) ts
718+
719+argsToEncoding jc tes opts multiCons (RecGadtC conNames ts _) =
720+ argsToEncoding jc tes opts multiCons $ RecC (head conNames) ts
721+#endif
574722
575723--------------------------------------------------------------------------------
576724-- FromJSON
@@ -654,41 +802,31 @@ consFromJSON :: JSONClass
654802 -- ^ Name of the type to which the constructors belong.
655803 -> Options
656804 -- ^ Encoding options
657− -> [Type]
658− -- ^ The types from the data type/data family instance declaration
659− -> [ConstructorInfo]
805+ -> [Con]
660806 -- ^ Constructors for which to generate JSON parsing code.
661807 -> Q Exp
662808
663−consFromJSON _ _ _ _ [] = error $ "Data.Aeson.TH.consFromJSON: "
664− ++ "Not a single constructor given!"
809+consFromJSON _ _ _ [] = error $ "Data.Aeson.TH.consFromJSON: "
810+ ++ "Not a single constructor given!"
665811
666−consFromJSON jc tName opts instTys cons = do
812+consFromJSON jc tName opts cons = do
667813 value <- newName "value"
668814 pjs <- newNameList "_pj" $ arityInt jc
669815 pjls <- newNameList "_pjl" $ arityInt jc
670816 let zippedPJs = zip pjs pjls
671817 interleavedPJs = interleave pjs pjls
672− lastTyVars = map varTToName $ drop (length instTys - arityInt jc) instTys
673− tvMap = M.fromList $ zip lastTyVars zippedPJs
674− lamE (map varP $ interleavedPJs ++ [value]) $ lamExpr value tvMap
818+ lamE (map varP $ interleavedPJs ++ [value]) $ lamExpr value zippedPJs
675819
676820 where
677− checkExi tvMap con = checkExistentialContext jc tvMap
678− (constructorContext con)
679− (constructorName con)
680−
681− lamExpr value tvMap = case cons of
682− [con]
683− | not (tagSingleConstructors opts)
684− -> checkExi tvMap con $ parseArgs jc tvMap tName opts con (Right value)
821+ lamExpr value pjs = case cons of
822+ [con] -> parseArgs jc pjs tName opts con (Right value)
685823 _ | sumEncoding opts == UntaggedValue
686− -> parseUntaggedValue tvMap cons value
824+ -> parseUntaggedValue pjs cons value
687825 | otherwise
688826 -> caseE (varE value) $
689827 if allNullaryToStringTag opts && all isNullary cons
690828 then allNullaryMatches
691− else mixedMatches tvMap
829+ else mixedMatches pjs
692830
693831 allNullaryMatches =
694832 [ do txt <- newName "txt"
@@ -697,11 +835,12 @@ consFromJSON jc tName opts instTys cons = do
697835 [ liftM2 (,) (normalG $
698836 infixApp (varE txt)
699837 [|(==)|]
700− (conTxt opts conName)
838+ ([|T.pack|] `appE`
839+ conStringE opts conName)
701840 )
702841 ([|pure|] `appE` conE conName)
703842 | con <- cons
704− , let conName = constructorName con
843+ , let conName = getConName con
705844 ]
706845 ++
707846 [ liftM2 (,)
@@ -722,13 +861,13 @@ consFromJSON jc tName opts instTys cons = do
722861 []
723862 ]
724863
725− mixedMatches tvMap =
864+ mixedMatches pjs =
726865 case sumEncoding opts of
727866 TaggedObject {tagFieldName, contentsFieldName} ->
728− parseObject $ parseTaggedObject tvMap tagFieldName contentsFieldName
867+ parseObject $ parseTaggedObject pjs tagFieldName contentsFieldName
729868 UntaggedValue -> error "UntaggedValue: Should be handled already"
730869 ObjectWithSingleField ->
731− parseObject $ parseObjectWithSingleField tvMap
870+ parseObject $ parseObjectWithSingleField pjs
732871 TwoElemArray ->
733872 [ do arr <- newName "array"
734873 match (conP 'Array [varP arr])
@@ -736,7 +875,7 @@ consFromJSON jc tName opts instTys cons = do
736875 [ liftM2 (,) (normalG $ infixApp ([|V.length|] `appE` varE arr)
737876 [|(==)|]
738877 (litE $ integerL 2))
739− (parse2ElemArray tvMap arr)
878+ (parse2ElemArray pjs arr)
740879 , liftM2 (,) (normalG [|otherwise|])
741880 ([|not2ElemArray|]
742881 `appE` litE (stringL $ show tName)
@@ -767,29 +906,25 @@ consFromJSON jc tName opts instTys cons = do
767906 []
768907 ]
769908
770− parseTaggedObject tvMap typFieldName valFieldName obj = do
909+ parseTaggedObject pjs typFieldName valFieldName obj = do
771910 conKey <- newName "conKey"
772911 doE [ bindS (varP conKey)
773912 (infixApp (varE obj)
774913 [|(.:)|]
775914 ([|T.pack|] `appE` stringE typFieldName))
776− , noBindS $ parseContents tvMap conKey (Left (valFieldName, obj)) 'conNotFoundFailTaggedObject
915+ , noBindS $ parseContents pjs conKey (Left (valFieldName, obj)) 'conNotFoundFailTaggedObject
777916 ]
778917
779− parseUntaggedValue tvMap cons' conVal =
918+ parseUntaggedValue pjs cons' conVal =
780919 foldr1 (\e e' -> infixApp e [|(<|>)|] e')
781− (map (\x -> parseValue tvMap x conVal) cons')
920+ (map (\x -> parseValue pjs x conVal) cons')
782921
783− parseValue _tvMap
784− ConstructorInfo { constructorName = conName
785− , constructorVariant = NormalConstructor
786− , constructorFields = [] }
787− conVal = do
922+ parseValue _pjs (NormalC conName []) conVal = do
788923 str <- newName "str"
789924 caseE (varE conVal)
790925 [ match (conP 'String [varP str])
791926 (guardedB
792− [ liftM2 (,) (normalG $ infixApp (varE str) [|(==)|] (conTxt opts conName)
927+ [ liftM2 (,) (normalG $ infixApp (varE str) [|(==)|] ([|T.pack|] `appE` conStringE opts conName)
793928 )
794929 ([|pure|] `appE` conE conName)
795930 ]
@@ -797,11 +932,11 @@ consFromJSON jc tName opts instTys cons = do
797932 []
798933 , matchFailed tName conName "String"
799934 ]
800− parseValue tvMap con conVal =
801− checkExi tvMap con $ parseArgs jc tvMap tName opts con (Right conVal)
935+ parseValue pjs con conVal =
936+ parseArgs jc pjs tName opts con (Right conVal)
802937
803938
804− parse2ElemArray tvMap arr = do
939+ parse2ElemArray pjs arr = do
805940 conKey <- newName "conKey"
806941 conVal <- newName "conVal"
807942 let letIx n ix =
@@ -816,7 +951,7 @@ consFromJSON jc tName opts instTys cons = do
816951 (caseE (varE conKey)
817952 [ do txt <- newName "txt"
818953 match (conP 'String [varP txt])
819− (normalB $ parseContents tvMap
954+ (normalB $ parseContents pjs
820955 txt
821956 (Right conVal)
822957 'conNotFoundFail2ElemArray
@@ -833,12 +968,12 @@ consFromJSON jc tName opts instTys cons = do
833968 ]
834969 )
835970
836− parseObjectWithSingleField tvMap obj = do
971+ parseObjectWithSingleField pjs obj = do
837972 conKey <- newName "conKey"
838973 conVal <- newName "conVal"
839974 caseE ([e|H.toList|] `appE` varE obj)
840975 [ match (listP [tupP [varP conKey, varP conVal]])
841− (normalB $ parseContents tvMap conKey (Right conVal) 'conNotFoundFailObjectSingleField)
976+ (normalB $ parseContents pjs conKey (Right conVal) 'conNotFoundFailObjectSingleField)
842977 []
843978 , do other <- newName "other"
844979 match (varP other)
@@ -849,7 +984,7 @@ consFromJSON jc tName opts instTys cons = do
849984 []
850985 ]
851986
852− parseContents tvMap conKey contents errorFun =
987+ parseContents pjs conKey contents errorFun =
853988 caseE (varE conKey)
854989 [ match wildP
855990 ( guardedB $
@@ -857,8 +992,7 @@ consFromJSON jc tName opts instTys cons = do
857992 [|(==)|]
858993 ([|T.pack|] `appE`
859994 conNameExp opts con)
860− e <- checkExi tvMap con $
861− parseArgs jc tvMap tName opts con contents
995+ e <- parseArgs jc pjs tName opts con contents
862996 return (g, e)
863997 | con <- cons
864998 ]
@@ -871,7 +1005,7 @@ consFromJSON jc tName opts instTys cons = do
8711005 . stringL
8721006 . constructorTagModifier opts
8731007 . nameBase
874− . constructorName
1008+ . getConName
8751009 ) cons
8761010 )
8771011 `appE` ([|T.unpack|] `appE` varE conKey)
@@ -920,42 +1054,22 @@ parseRecord :: JSONClass
9201054 -> Options
9211055 -> Name
9221056 -> Name
923− -> [Name]
1057+ -> [VarStrictType]
9241058 -> Name
925− -> Bool
9261059 -> ExpQ
927−parseRecord jc tvMap argTys opts tName conName fields obj inTaggedObject =
928− (if rejectUnknownFields opts
929− then infixApp checkUnknownRecords [|(>>)|]
930− else id) $
1060+parseRecord jc tvMap argTys opts tName conName ts obj =
9311061 foldl' (\a b -> infixApp a [|(<*>)|] b)
9321062 (infixApp (conE conName) [|(<$>)|] x)
9331063 xs
9341064 where
935− tagFieldNameAppender =
936− if inTaggedObject then (tagFieldName (sumEncoding opts) :) else id
937− knownFields = appE [|H.fromList|] $ listE $
938− map (\knownName -> tupE [appE [|T.pack|] $ litE $ stringL knownName, [|()|]]) $
939− tagFieldNameAppender $ map nameBase fields
940− checkUnknownRecords =
941− caseE (appE [|H.keys|] $ infixApp (varE obj) [|H.difference|] knownFields)
942− [ match (listP []) (normalB [|return ()|]) []
943− , newName "unknownFields" >>=
944− \unknownFields -> match (varP unknownFields)
945− (normalB $ appE [|fail|] $ infixApp
946− (litE (stringL "Unknown fields: "))
947− [|(++)|]
948− (appE [|show|] (varE unknownFields)))
949− []
950− ]
9511065 x:xs = [ [|lookupField|]
9521066 `appE` dispatchParseJSON jc conName tvMap argTy
9531067 `appE` litE (stringL $ show tName)
9541068 `appE` litE (stringL $ constructorTagModifier opts $ nameBase conName)
9551069 `appE` varE obj
956− `appE` ( [|T.pack|] `appE` stringE (fieldLabel opts field)
1070+ `appE` ( [|T.pack|] `appE` fieldLabelExp opts field
9571071 )
958− | (field, argTy) <- zip fields argTys
1072+ | ((field, _, _), argTy) <- zip ts argTys
9591073 ]
9601074
9611075getValField :: Name -> String -> [MatchQ] -> Q Exp
@@ -974,82 +1088,67 @@ matchCases (Right valName) = caseE (varE valName)
9741088
9751089-- | Generates code to parse the JSON encoding of a single constructor.
9761090parseArgs :: JSONClass -- ^ The FromJSON variant being derived.
977− -> TyVarMap -- ^ Maps the last type variables to their decoding
978− -- function arguments.
1091+ -> [(Name, Name)] -- ^ The names of the encoding/decoding function arguments.
9791092 -> Name -- ^ Name of the type to which the constructor belongs.
9801093 -> Options -- ^ Encoding options.
981− -> ConstructorInfo -- ^ Constructor for which to generate JSON parsing code.
1094+ -> Con -- ^ Constructor for which to generate JSON parsing code.
9821095 -> Either (String, Name) Name -- ^ Left (valFieldName, objName) or
9831096 -- Right valName
9841097 -> Q Exp
9851098-- Nullary constructors.
986−parseArgs _ _ _ _
987− ConstructorInfo { constructorName = conName
988− , constructorVariant = NormalConstructor
989− , constructorFields = [] }
990− (Left _) =
991− [|pure|] `appE` conE conName
992−parseArgs _ _ tName _
993− ConstructorInfo { constructorName = conName
994− , constructorVariant = NormalConstructor
995− , constructorFields = [] }
996− (Right valName) =
997− caseE (varE valName) $ parseNullaryMatches tName conName
1099+parseArgs jc pjs _ _ (NormalC conName []) (Left _) = do
1100+ ([], _) <- reifyConTys jc pjs conName
1101+ [|pure|] `appE` conE conName
1102+parseArgs jc pjs tName _ (NormalC conName []) (Right valName) = do
1103+ ([], _) <- reifyConTys jc pjs conName
1104+ caseE (varE valName) $ parseNullaryMatches tName conName
9981105
9991106-- Unary constructors.
1000−parseArgs jc tvMap _ _
1001− ConstructorInfo { constructorName = conName
1002− , constructorVariant = NormalConstructor
1003− , constructorFields = [argTy] }
1004− contents = do
1005− argTy' <- resolveTypeSynonyms argTy
1006− matchCases contents $ parseUnaryMatches jc tvMap argTy' conName
1107+parseArgs jc pjs _ _ (NormalC conName [_]) contents = do
1108+ ([argTy], tvMap) <- reifyConTys jc pjs conName
1109+ matchCases contents $ parseUnaryMatches jc tvMap argTy conName
10071110
10081111-- Polyadic constructors.
1009−parseArgs jc tvMap tName _
1010− ConstructorInfo { constructorName = conName
1011− , constructorVariant = NormalConstructor
1012− , constructorFields = argTys }
1013− contents = do
1014− argTys' <- mapM resolveTypeSynonyms argTys
1015− let len = genericLength argTys'
1016− matchCases contents $ parseProduct jc tvMap argTys' tName conName len
1112+parseArgs jc pjs tName _ (NormalC conName ts) contents = do
1113+ (argTys, tvMap) <- reifyConTys jc pjs conName
1114+ let len = genericLength ts
1115+ matchCases contents $ parseProduct jc tvMap argTys tName conName len
10171116
10181117-- Records.
1019−parseArgs jc tvMap tName opts
1020− ConstructorInfo { constructorName = conName
1021− , constructorVariant = RecordConstructor fields
1022− , constructorFields = argTys }
1023− (Left (_, obj)) = do
1024− argTys' <- mapM resolveTypeSynonyms argTys
1025− parseRecord jc tvMap argTys' opts tName conName fields obj True
1026−parseArgs jc tvMap tName opts
1027− info@ConstructorInfo { constructorName = conName
1028− , constructorVariant = RecordConstructor fields
1029− , constructorFields = argTys }
1030− (Right valName) =
1031− case (unwrapUnaryRecords opts,argTys) of
1032− (True,[_])-> parseArgs jc tvMap tName opts
1033− (info{constructorVariant = NormalConstructor})
1034− (Right valName)
1035− _ -> do
1036− obj <- newName "recObj"
1037− argTys' <- mapM resolveTypeSynonyms argTys
1038− caseE (varE valName)
1039− [ match (conP 'Object [varP obj]) (normalB $
1040− parseRecord jc tvMap argTys' opts tName conName fields obj False) []
1041− , matchFailed tName conName "Object"
1042− ]
1118+parseArgs jc pjs tName opts (RecC conName ts) (Left (_, obj)) = do
1119+ (argTys, tvMap) <- reifyConTys jc pjs conName
1120+ parseRecord jc tvMap argTys opts tName conName ts obj
1121+parseArgs jc pjs tName opts (RecC conName ts) (Right valName) = case (unwrapUnaryRecords opts,ts) of
1122+ (True,[(_,st,ty)])-> parseArgs jc pjs tName opts (NormalC conName [(st,ty)]) (Right valName)
1123+ _ -> do
1124+ obj <- newName "recObj"
1125+ (argTys, tvMap) <- reifyConTys jc pjs conName
1126+ caseE (varE valName)
1127+ [ match (conP 'Object [varP obj]) (normalB $
1128+ parseRecord jc tvMap argTys opts tName conName ts obj) []
1129+ , matchFailed tName conName "Object"
1130+ ]
10431131
10441132-- Infix constructors. Apart from syntax these are the same as
10451133-- polyadic constructors.
1046−parseArgs jc tvMap tName _
1047− ConstructorInfo { constructorName = conName
1048− , constructorVariant = InfixConstructor
1049− , constructorFields = argTys }
1050− contents = do
1051− argTys' <- mapM resolveTypeSynonyms argTys
1052− matchCases contents $ parseProduct jc tvMap argTys' tName conName 2
1134+parseArgs jc pjs tName _ (InfixC _ conName _) contents = do
1135+ (argTys, tvMap) <- reifyConTys jc pjs conName
1136+ matchCases contents $ parseProduct jc tvMap argTys tName conName 2
1137+
1138+-- Existentially quantified constructors. We ignore the quantifiers
1139+-- and proceed with the contained constructor.
1140+parseArgs jc pjs tName opts (ForallC _ _ con) contents =
1141+ parseArgs jc pjs tName opts con contents
1142+
1143+#if MIN_VERSION_template_haskell(2,11,0)
1144+-- GADTs. We ignore the refined return type and proceed as if it were a
1145+-- NormalC or RecC.
1146+parseArgs jc pjs tName opts (GadtC conNames ts _) contents =
1147+ parseArgs jc pjs tName opts (NormalC (head conNames) ts) contents
1148+
1149+parseArgs jc pjs tName opts (RecGadtC conNames ts _) contents =
1150+ parseArgs jc pjs tName opts (RecC (head conNames) ts) contents
1151+#endif
10531152
10541153-- | Generates code to parse the JSON encoding of an n-ary
10551154-- constructor.
@@ -1123,14 +1222,9 @@ class LookupField a where
11231222instance OVERLAPPABLE_ LookupField a where
11241223 lookupField = lookupFieldWith
11251224
1126−instance INCOHERENT_ LookupField (Maybe a) where
1225+instance LookupField (Maybe a) where
11271226 lookupField pj _ _ = parseOptionalFieldWith pj
11281227
1129−instance INCOHERENT_ LookupField (Semigroup.Option a) where
1130− lookupField pj tName rec obj key =
1131− fmap Semigroup.Option
1132− (lookupField (fmap Semigroup.getOption . pj) tName rec obj key)
1133−
11341228lookupFieldWith :: (Value -> Parser a) -> String -> String
11351229 -> Object -> T.Text -> Parser a
11361230lookupFieldWith pj tName rec obj key =
@@ -1138,6 +1232,9 @@ lookupFieldWith pj tName rec obj key =
11381232 Nothing -> unknownFieldFail tName rec (T.unpack key)
11391233 Just v -> pj v <?> Key key
11401234
1235+keyValuePairWith :: (v -> Value) -> T.Text -> v -> Pair
1236+keyValuePairWith tj name value = (name, tj value)
1237+
11411238unknownFieldFail :: String -> String -> String -> Parser fail
11421239unknownFieldFail tName rec key =
11431240 fail $ printf "When parsing the record %s of type %s the key %s was not present."
@@ -1206,8 +1303,7 @@ deriveJSONBoth dtj dfj opts name =
12061303 liftM2 (++) (dtj opts name) (dfj opts name)
12071304
12081305-- | Functionality common to @deriveToJSON(1)(2)@ and @deriveFromJSON(1)(2)@.
1209−deriveJSONClass :: [(JSONFun, JSONClass -> Name -> Options -> [Type]
1210− -> [ConstructorInfo] -> Q Exp)]
1306+deriveJSONClass :: [(JSONFun, JSONClass -> Name -> Options -> [Con] -> Q Exp)]
12111307 -- ^ The class methods and the functions which derive them.
12121308 -> JSONClass
12131309 -- ^ The class for which to generate an instance.
@@ -1217,34 +1313,27 @@ deriveJSONClass :: [(JSONFun, JSONClass -> Name -> Options -> [Type]
12171313 -- ^ Name of the type for which to generate a class instance
12181314 -- declaration.
12191315 -> Q [Dec]
1220−deriveJSONClass consFuns jc opts name = do
1221− info <- reifyDatatype name
1222− case info of
1223− DatatypeInfo { datatypeContext = ctxt
1224− , datatypeName = parentName
1225−#if MIN_VERSION_th_abstraction(0,3,0)
1226− , datatypeInstTypes = instTys
1227−#else
1228− , datatypeVars = instTys
1229−#endif
1230− , datatypeVariant = variant
1231− , datatypeCons = cons
1232− } -> do
1233− (instanceCxt, instanceType)
1234− <- buildTypeInstance parentName jc ctxt instTys variant
1235− (:[]) <$> instanceD (return instanceCxt)
1236− (return instanceType)
1237− (methodDecs parentName instTys cons)
1316+deriveJSONClass consFuns jc opts name =
1317+ withType name $ \name' ctxt tvbs cons mbTys ->
1318+ (:[]) <$> fromCons name' ctxt tvbs cons mbTys
12381319 where
1239− methodDecs :: Name -> [Type] -> [ConstructorInfo] -> [Q Dec]
1240− methodDecs parentName instTys cons = flip map consFuns $ \(jf, jfMaker) ->
1320+ fromCons :: Name -> Cxt -> [TyVarBndr] -> [Con] -> Maybe [Type] -> Q Dec
1321+ fromCons name' ctxt tvbs cons mbTys = do
1322+ (instanceCxt, instanceType)
1323+ <- buildTypeInstance name' jc ctxt tvbs mbTys
1324+ instanceD (return instanceCxt)
1325+ (return instanceType)
1326+ (methodDecs name' cons)
1327+
1328+ methodDecs :: Name -> [Con] -> [Q Dec]
1329+ methodDecs name' cons = flip map consFuns $ \(jf, jfMaker) ->
12411330 funD (jsonFunValName jf (arity jc))
12421331 [ clause []
1243− (normalB $ jfMaker jc parentName opts instTys cons)
1332+ (normalB $ jfMaker jc name' opts cons)
12441333 []
12451334 ]
12461335
1247−mkFunCommon :: (JSONClass -> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)
1336+mkFunCommon :: (JSONClass -> Name -> Options -> [Con] -> Q Exp)
12481337 -- ^ The function which derives the expression.
12491338 -> JSONClass
12501339 -- ^ Which class's method is being derived.
@@ -1253,24 +1342,15 @@ mkFunCommon :: (JSONClass -> Name -> Options -> [Type] -> [ConstructorInfo] -> Q
12531342 -> Name
12541343 -- ^ Name of the encoded type.
12551344 -> Q Exp
1256−mkFunCommon consFun jc opts name = do
1257− info <- reifyDatatype name
1258− case info of
1259− DatatypeInfo { datatypeContext = ctxt
1260− , datatypeName = parentName
1261−#if MIN_VERSION_th_abstraction(0,3,0)
1262− , datatypeInstTypes = instTys
1263−#else
1264− , datatypeVars = instTys
1265−#endif
1266− , datatypeVariant = variant
1267− , datatypeCons = cons
1268− } -> do
1269− -- We force buildTypeInstance here since it performs some checks for whether
1270− -- or not the provided datatype's kind matches the derived method's
1271− -- typeclass, and produces errors if it can't.
1272− !_ <- buildTypeInstance parentName jc ctxt instTys variant
1273− consFun jc parentName opts instTys cons
1345+mkFunCommon consFun jc opts name = withType name fromCons
1346+ where
1347+ fromCons :: Name -> Cxt -> [TyVarBndr] -> [Con] -> Maybe [Type] -> Q Exp
1348+ fromCons name' ctxt tvbs cons mbTys = do
1349+ -- We force buildTypeInstance here since it performs some checks for whether
1350+ -- or not the provided datatype's kind matches the derived method's
1351+ -- typeclass, and produces errors if it can't.
1352+ !_ <- buildTypeInstance name' jc ctxt tvbs mbTys
1353+ consFun jc name' opts cons
12741354
12751355dispatchFunByType :: JSONClass
12761356 -> JSONFun
@@ -1315,37 +1395,200 @@ dispatchFunByType jc jf conName tvMap list ty = do
13151395 (interleave rhsArgs rhsArgs)
13161396 else varE $ jsonFunValOrListName list jf Arity0
13171397
1318−dispatchToJSON
1319− :: ToJSONFun -> JSONClass -> Name -> TyVarMap -> Type -> Q Exp
1320−dispatchToJSON target jc n tvMap =
1321− dispatchFunByType jc (targetToJSONFun target) n tvMap False
1322−
1323−dispatchParseJSON
1398+dispatchToJSON, dispatchToEncoding, dispatchParseJSON
13241399 :: JSONClass -> Name -> TyVarMap -> Type -> Q Exp
1400+dispatchToJSON jc n tvMap = dispatchFunByType jc ToJSON n tvMap False
1401+dispatchToEncoding jc n tvMap = dispatchFunByType jc ToEncoding n tvMap False
13251402dispatchParseJSON jc n tvMap = dispatchFunByType jc ParseJSON n tvMap False
13261403
13271404--------------------------------------------------------------------------------
13281405-- Utility functions
13291406--------------------------------------------------------------------------------
13301407
1331−-- For the given Types, generate an instance context and head.
1408+-- | Boilerplate for top level splices.
1409+--
1410+-- The given 'Name' must meet one of two criteria:
1411+--
1412+-- 1. It must be the name of a type constructor of a plain data type or newtype.
1413+-- 2. It must be the name of a data family instance or newtype instance constructor.
1414+
1415+-- Any other value will result in an exception.
1416+withType :: Name
1417+ -> (Name -> Cxt -> [TyVarBndr] -> [Con] -> Maybe [Type] -> Q a)
1418+ -- ^ Function that generates the actual code. Will be applied
1419+ -- to the datatype/data family 'Name', datatype context, type
1420+ -- variable binders and constructors extracted from the given
1421+ -- 'Name'. If the 'Name' is from a data family instance
1422+ -- constructor, it will also have its instantiated types;
1423+ -- otherwise, it will be 'Nothing'.
1424+ -> Q a
1425+ -- ^ Resulting value in the 'Q'uasi monad.
1426+withType name f = do
1427+ info <- reify name
1428+ case info of
1429+ TyConI dec ->
1430+ case dec of
1431+#if MIN_VERSION_template_haskell(2,11,0)
1432+ DataD ctxt _ tvbs _ cons _ -> f name ctxt tvbs cons Nothing
1433+ NewtypeD ctxt _ tvbs _ con _ -> f name ctxt tvbs [con] Nothing
1434+#else
1435+ DataD ctxt _ tvbs cons _ -> f name ctxt tvbs cons Nothing
1436+ NewtypeD ctxt _ tvbs con _ -> f name ctxt tvbs [con] Nothing
1437+#endif
1438+ other -> fail $ ns ++ "Unsupported type: " ++ show other
1439+#if MIN_VERSION_template_haskell(2,11,0)
1440+ DataConI _ _ parentName -> do
1441+#else
1442+ DataConI _ _ parentName _ -> do
1443+#endif
1444+ parentInfo <- reify parentName
1445+ case parentInfo of
1446+#if MIN_VERSION_template_haskell(2,11,0)
1447+ FamilyI (DataFamilyD _ tvbs _) decs ->
1448+#else
1449+ FamilyI (FamilyD DataFam _ tvbs _) decs ->
1450+#endif
1451+ let instDec = flip find decs $ \dec -> case dec of
1452+#if MIN_VERSION_template_haskell(2,11,0)
1453+ DataInstD _ _ _ _ cons _ -> any ((name ==) . getConName) cons
1454+ NewtypeInstD _ _ _ _ con _ -> name == getConName con
1455+#else
1456+ DataInstD _ _ _ cons _ -> any ((name ==) . getConName) cons
1457+ NewtypeInstD _ _ _ con _ -> name == getConName con
1458+#endif
1459+ _ -> error $ ns ++ "Must be a data or newtype instance."
1460+ in case instDec of
1461+#if MIN_VERSION_template_haskell(2,11,0)
1462+ Just (DataInstD ctxt _ instTys _ cons _) -> f parentName ctxt tvbs cons $ Just instTys
1463+ Just (NewtypeInstD ctxt _ instTys _ con _) -> f parentName ctxt tvbs [con] $ Just instTys
1464+#else
1465+ Just (DataInstD ctxt _ instTys cons _) -> f parentName ctxt tvbs cons $ Just instTys
1466+ Just (NewtypeInstD ctxt _ instTys con _) -> f parentName ctxt tvbs [con] $ Just instTys
1467+#endif
1468+ _ -> fail $ ns ++
1469+ "Could not find data or newtype instance constructor."
1470+ _ -> fail $ ns ++ "Data constructor " ++ show name ++
1471+ " is not from a data family instance constructor."
1472+#if MIN_VERSION_template_haskell(2,11,0)
1473+ FamilyI DataFamilyD{} _ ->
1474+#else
1475+ FamilyI (FamilyD DataFam _ _ _) _ ->
1476+#endif
1477+ fail $ ns ++
1478+ "Cannot use a data family name. Use a data family instance constructor instead."
1479+ _ -> fail $ ns ++ "I need the name of a plain data type constructor, "
1480+ ++ "or a data family instance constructor."
1481+ where
1482+ ns :: String
1483+ ns = "Data.Aeson.TH.withType: "
1484+
1485+-- | Infer the context and instance head needed for a FromJSON or ToJSON instance.
13321486buildTypeInstance :: Name
13331487 -- ^ The type constructor or data family name
13341488 -> JSONClass
13351489 -- ^ The typeclass to derive
13361490 -> Cxt
13371491 -- ^ The datatype context
1338− -> [Type]
1339− -- ^ The types to instantiate the instance with
1340− -> DatatypeVariant
1341− -- ^ Are we dealing with a data family instance or not
1492+ -> [TyVarBndr]
1493+ -- ^ The type variables from the data type/data family declaration
1494+ -> Maybe [Type]
1495+ -- ^ 'Just' the types used to instantiate a data family instance,
1496+ -- or 'Nothing' if it's a plain data type
13421497 -> Q (Cxt, Type)
1343−buildTypeInstance tyConName jc dataCxt varTysOrig variant = do
1498+ -- ^ The resulting 'Cxt' and 'Type' to use in a class instance
1499+-- Plain data type/newtype case
1500+buildTypeInstance tyConName jc dataCxt tvbs Nothing =
1501+ let varTys :: [Type]
1502+ varTys = map tvbToType tvbs
1503+ in buildTypeInstanceFromTys tyConName jc dataCxt varTys False
1504+-- Data family instance case
1505+--
1506+-- The CPP is present to work around a couple of annoying old GHC bugs.
1507+-- See Note [Polykinded data families in Template Haskell]
1508+buildTypeInstance dataFamName jc dataCxt tvbs (Just instTysAndKinds) = do
1509+#if !(MIN_VERSION_template_haskell(2,8,0)) || MIN_VERSION_template_haskell(2,10,0)
1510+ let instTys :: [Type]
1511+ instTys = zipWith stealKindForType tvbs instTysAndKinds
1512+#else
1513+ let kindVarNames :: [Name]
1514+ kindVarNames = nub $ concatMap (tyVarNamesOfType . tvbKind) tvbs
1515+
1516+ numKindVars :: Int
1517+ numKindVars = length kindVarNames
1518+
1519+ givenKinds, givenKinds' :: [Kind]
1520+ givenTys :: [Type]
1521+ (givenKinds, givenTys) = splitAt numKindVars instTysAndKinds
1522+ givenKinds' = map sanitizeStars givenKinds
1523+
1524+ -- A GHC 7.6-specific bug requires us to replace all occurrences of
1525+ -- (ConT GHC.Prim.*) with StarT, or else Template Haskell will reject it.
1526+ -- Luckily, (ConT GHC.Prim.*) only seems to occur in this one spot.
1527+ sanitizeStars :: Kind -> Kind
1528+ sanitizeStars = go
1529+ where
1530+ go :: Kind -> Kind
1531+ go (AppT t1 t2) = AppT (go t1) (go t2)
1532+ go (SigT t k) = SigT (go t) (go k)
1533+ go (ConT n) | n == starKindName = StarT
1534+ go t = t
1535+
1536+ -- It's quite awkward to import * from GHC.Prim, so we'll just
1537+ -- hack our way around it.
1538+ starKindName :: Name
1539+ starKindName = mkNameG_tc "ghc-prim" "GHC.Prim" "*"
1540+
1541+ -- If we run this code with GHC 7.8, we might have to generate extra type
1542+ -- variables to compensate for any type variables that Template Haskell
1543+ -- eta-reduced away.
1544+ -- See Note [Polykinded data families in Template Haskell]
1545+ xTypeNames <- newNameList "tExtra" (length tvbs - length givenTys)
1546+
1547+ let xTys :: [Type]
1548+ xTys = map VarT xTypeNames
1549+ -- ^ Because these type variables were eta-reduced away, we can only
1550+ -- determine their kind by using stealKindForType. Therefore, we mark
1551+ -- them as VarT to ensure they will be given an explicit kind annotation
1552+ -- (and so the kind inference machinery has the right information).
1553+
1554+ substNamesWithKinds :: [(Name, Kind)] -> Type -> Type
1555+ substNamesWithKinds nks t = foldr' (uncurry substNameWithKind) t nks
1556+
1557+ -- The types from the data family instance might not have explicit kind
1558+ -- annotations, which the kind machinery needs to work correctly. To
1559+ -- compensate, we use stealKindForType to explicitly annotate any
1560+ -- types without kind annotations.
1561+ instTys :: [Type]
1562+ instTys = map (substNamesWithKinds (zip kindVarNames givenKinds'))
1563+ -- Note that due to a GHC 7.8-specific bug
1564+ -- (see Note [Polykinded data families in Template Haskell]),
1565+ -- there may be more kind variable names than there are kinds
1566+ -- to substitute. But this is OK! If a kind is eta-reduced, it
1567+ -- means that is was not instantiated to something more specific,
1568+ -- so we need not substitute it. Using stealKindForType will
1569+ -- grab the correct kind.
1570+ $ zipWith stealKindForType tvbs (givenTys ++ xTys)
1571+#endif
1572+ buildTypeInstanceFromTys dataFamName jc dataCxt instTys True
1573+
1574+-- For the given Types, generate an instance context and head.
1575+buildTypeInstanceFromTys :: Name
1576+ -- ^ The type constructor or data family name
1577+ -> JSONClass
1578+ -- ^ The typeclass to derive
1579+ -> Cxt
1580+ -- ^ The datatype context
1581+ -> [Type]
1582+ -- ^ The types to instantiate the instance with
1583+ -> Bool
1584+ -- ^ True if it's a data family, False otherwise
1585+ -> Q (Cxt, Type)
1586+buildTypeInstanceFromTys tyConName jc dataCxt varTysOrig isDataFamily = do
13441587 -- Make sure to expand through type/kind synonyms! Otherwise, the
13451588 -- eta-reduction check might get tripped up over type variables in a
13461589 -- synonym that are actually dropped.
13471590 -- (See GHC Trac #11416 for a scenario where this actually happened.)
1348− varTysExp <- mapM resolveTypeSynonyms varTysOrig
1591+ varTysExp <- mapM expandSyn varTysOrig
13491592
13501593 let remainingLength :: Int
13511594 remainingLength = length varTysOrig - arityInt jc
@@ -1375,7 +1618,7 @@ buildTypeInstance tyConName jc dataCxt varTysOrig variant = do
13751618 -- All of the type variables mentioned in the dropped types
13761619 -- (post-synonym expansion)
13771620 droppedTyVarNames :: [Name]
1378− droppedTyVarNames = freeVariables droppedTysExpSubst
1621+ droppedTyVarNames = concatMap tyVarNamesOfType droppedTysExpSubst
13791622
13801623 -- If any of the dropped types were polykinded, ensure that they are of kind *
13811624 -- after substituting * for the dropped kind variables. If not, throw an error.
@@ -1413,16 +1656,9 @@ buildTypeInstance tyConName jc dataCxt varTysOrig variant = do
14131656 -- instance C (Fam [Char])
14141657 remainingTysOrigSubst :: [Type]
14151658 remainingTysOrigSubst =
1416− map (substNamesWithKindStar (droppedKindVarNames `union` kvNames'))
1659+ map (substNamesWithKindStar (union droppedKindVarNames kvNames'))
14171660 $ take remainingLength varTysOrig
14181661
1419− isDataFamily :: Bool
1420− isDataFamily = case variant of
1421− Datatype -> False
1422− Newtype -> False
1423− DataInstance -> True
1424− NewtypeInstance -> True
1425−
14261662 remainingTysOrigSubst' :: [Type]
14271663 -- See Note [Kind signatures in derived instances] for an explanation
14281664 -- of the isDataFamily check.
@@ -1476,6 +1712,55 @@ deriveConstraint jc t
14761712 jcConstraint = jsonClassName . JSONClass (direction jc)
14771713
14781714{-
1715+Note [Polykinded data families in Template Haskell]
1716+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1717+
1718+In order to come up with the correct instance context and head for an instance, e.g.,
1719+
1720+ instance C a => C (Data a) where ...
1721+
1722+We need to know the exact types and kinds used to instantiate the instance. For
1723+plain old datatypes, this is simple: every type must be a type variable, and
1724+Template Haskell reliably tells us the type variables and their kinds.
1725+
1726+Doing the same for data families proves to be much harder for three reasons:
1727+
1728+1. On any version of Template Haskell, it may not tell you what an instantiated
1729+ type's kind is. For instance, in the following data family instance:
1730+
1731+ data family Fam (f :: * -> *) (a :: *)
1732+ data instance Fam f a
1733+
1734+ Then if we use TH's reify function, it would tell us the TyVarBndrs of the
1735+ data family declaration are:
1736+
1737+ [KindedTV f (AppT (AppT ArrowT StarT) StarT),KindedTV a StarT]
1738+
1739+ and the instantiated types of the data family instance are:
1740+
1741+ [VarT f1,VarT a1]
1742+
1743+ We can't just pass [VarT f1,VarT a1] to buildTypeInstanceFromTys, since we
1744+ have no way of knowing their kinds. Luckily, the TyVarBndrs tell us what the
1745+ kind is in case an instantiated type isn't a SigT, so we use the stealKindForType
1746+ function to ensure all of the instantiated types are SigTs before passing them
1747+ to buildTypeInstanceFromTys.
1748+2. On GHC 7.6 and 7.8, a bug is present in which Template Haskell lists all of
1749+ the specified kinds of a data family instance efore any of the instantiated
1750+ types. Fortunately, this is easy to deal with: you simply count the number of
1751+ distinct kind variables in the data family declaration, take that many elements
1752+ from the front of the Types list of the data family instance, substitute the
1753+ kind variables with their respective instantiated kinds (which you took earlier),
1754+ and proceed as normal.
1755+3. On GHC 7.8, an even uglier bug is present (GHC Trac #9692) in which Template
1756+ Haskell might not even list all of the Types of a data family instance, since
1757+ they are eta-reduced away! And yes, kinds can be eta-reduced too.
1758+
1759+ The simplest workaround is to count how many instantiated types are missing from
1760+ the list and generate extra type variables to use in their place. Luckily, we
1761+ needn't worry much if its kind was eta-reduced away, since using stealKindForType
1762+ will get it back.
1763+
14791764Note [Kind signatures in derived instances]
14801765~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14811766
@@ -1553,14 +1838,50 @@ things we can do to make instance contexts that work for 80% of use cases:
15531838 and perform kind substitution as in the other cases.
15541839-}
15551840
1556−checkExistentialContext :: JSONClass -> TyVarMap -> Cxt -> Name
1557− -> Q a -> Q a
1558−checkExistentialContext jc tvMap ctxt conName q =
1559− if (any (`predMentionsName` M.keys tvMap) ctxt
1560− || M.size tvMap < arityInt jc)
1561− && not (allowExQuant jc)
1562− then existentialContextError conName
1563− else q
1841+-- Determines the types of a constructor's arguments as well as the last type
1842+-- parameters (mapped to their encoding/decoding functions), expanding through
1843+-- any type synonyms.
1844+--
1845+-- The type parameters are determined on a constructor-by-constructor basis since
1846+-- they may be refined to be particular types in a GADT.
1847+reifyConTys :: JSONClass
1848+ -> [(Name, Name)]
1849+ -> Name
1850+ -> Q ([Type], TyVarMap)
1851+reifyConTys jc tpjs conName = do
1852+ info <- reify conName
1853+ (ctxt, uncTy) <- case info of
1854+ DataConI _ ty _
1855+#if !(MIN_VERSION_template_haskell(2,11,0))
1856+ _
1857+#endif
1858+ -> fmap uncurryTy (expandSyn ty)
1859+ _ -> error "Must be a data constructor"
1860+ let (argTys, [resTy]) = NE.splitAt (NE.length uncTy - 1) uncTy
1861+ unapResTy = unapplyTy resTy
1862+ -- If one of the last type variables is refined to a particular type
1863+ -- (i.e., not truly polymorphic), we mark it with Nothing and filter
1864+ -- it out later, since we only apply encoding/decoding functions to
1865+ -- arguments of a type that it (1) one of the last type variables,
1866+ -- and (2) of a truly polymorphic type.
1867+ jArity = arityInt jc
1868+ mbTvNames = map varTToNameMaybe $
1869+ NE.drop (NE.length unapResTy - jArity) unapResTy
1870+ -- We use M.fromList to ensure that if there are any duplicate type
1871+ -- variables (as can happen in a GADT), the rightmost type variable gets
1872+ -- associated with the show function.
1873+ --
1874+ -- See Note [Matching functions with GADT type variables]
1875+ tvMap = M.fromList
1876+ . catMaybes -- Drop refined types
1877+ $ zipWith (\mbTvName tpj ->
1878+ fmap (\tvName -> (tvName, tpj)) mbTvName)
1879+ mbTvNames tpjs
1880+ if (any (`predMentionsName` M.keys tvMap) ctxt
1881+ || M.size tvMap < jArity)
1882+ && not (allowExQuant jc)
1883+ then existentialContextError conName
1884+ else return (argTys, tvMap)
15641885
15651886{-
15661887Note [Matching functions with GADT type variables]
@@ -1600,22 +1921,69 @@ Both.
16001921-- are the function arguments of types (b -> Value) and ([b] -> Value).
16011922type TyVarMap = Map Name (Name, Name)
16021923
1924+-- | If a VarT is missing an explicit kind signature, steal it from a TyVarBndr.
1925+stealKindForType :: TyVarBndr -> Type -> Type
1926+stealKindForType tvb t@VarT{} = SigT t (tvbKind tvb)
1927+stealKindForType _ t = t
1928+
1929+-- | Extracts the kind from a type variable binder.
1930+tvbKind :: TyVarBndr -> Kind
1931+#if MIN_VERSION_template_haskell(2,8,0)
1932+tvbKind (PlainTV _ ) = StarT
1933+#else
1934+tvbKind (PlainTV _ ) = StarK
1935+#endif
1936+tvbKind (KindedTV _ k) = k
1937+
1938+tvbToType :: TyVarBndr -> Type
1939+tvbToType (PlainTV n) = VarT n
1940+tvbToType (KindedTV n k) = SigT (VarT n) k
1941+
16031942-- | Returns True if a Type has kind *.
16041943hasKindStar :: Type -> Bool
16051944hasKindStar VarT{} = True
1945+#if MIN_VERSION_template_haskell(2,8,0)
16061946hasKindStar (SigT _ StarT) = True
1947+#else
1948+hasKindStar (SigT _ StarK) = True
1949+#endif
16071950hasKindStar _ = False
16081951
16091952-- Returns True is a kind is equal to *, or if it is a kind variable.
16101953isStarOrVar :: Kind -> Bool
1954+#if MIN_VERSION_template_haskell(2,8,0)
16111955isStarOrVar StarT = True
16121956isStarOrVar VarT{} = True
1957+#else
1958+isStarOrVar StarK = True
1959+#endif
16131960isStarOrVar _ = False
16141961
16151962-- Generate a list of fresh names with a common prefix, and numbered suffixes.
16161963newNameList :: String -> Int -> Q [Name]
16171964newNameList prefix len = mapM newName [prefix ++ show n | n <- [1..len]]
16181965
1966+-- Gets all of the type/kind variable names mentioned somewhere in a Type.
1967+tyVarNamesOfType :: Type -> [Name]
1968+tyVarNamesOfType = go
1969+ where
1970+ go :: Type -> [Name]
1971+ go (AppT t1 t2) = go t1 ++ go t2
1972+ go (SigT t _k) = go t
1973+#if MIN_VERSION_template_haskell(2,8,0)
1974+ ++ go _k
1975+#endif
1976+ go (VarT n) = [n]
1977+ go _ = []
1978+
1979+-- | Gets all of the type/kind variable names mentioned somewhere in a Kind.
1980+tyVarNamesOfKind :: Kind -> [Name]
1981+#if MIN_VERSION_template_haskell(2,8,0)
1982+tyVarNamesOfKind = tyVarNamesOfType
1983+#else
1984+tyVarNamesOfKind _ = [] -- There are no kind variables
1985+#endif
1986+
16191987-- | @hasKindVarChain n kind@ Checks if @kind@ is of the form
16201988-- k_0 -> k_1 -> ... -> k_(n-1), where k0, k1, ..., and k_(n-1) can be * or
16211989-- kind variables.
@@ -1623,7 +1991,7 @@ hasKindVarChain :: Int -> Type -> Maybe [Name]
16231991hasKindVarChain kindArrows t =
16241992 let uk = uncurryKind (tyKind t)
16251993 in if (NE.length uk - 1 == kindArrows) && F.all isStarOrVar uk
1626− then Just (concatMap freeVariables uk)
1994+ then Just (concatMap tyVarNamesOfKind uk)
16271995 else Nothing
16281996
16291997-- | If a Type is a SigT, returns its kind signature. Otherwise, return *.
@@ -1643,6 +2011,17 @@ varTToNameMaybe _ = Nothing
16432011varTToName :: Type -> Name
16442012varTToName = fromMaybe (error "Not a type variable!") . varTToNameMaybe
16452013
2014+-- | Extracts the name from a constructor.
2015+getConName :: Con -> Name
2016+getConName (NormalC name _) = name
2017+getConName (RecC name _) = name
2018+getConName (InfixC _ name _) = name
2019+getConName (ForallC _ _ con) = getConName con
2020+#if MIN_VERSION_template_haskell(2,11,0)
2021+getConName (GadtC names _ _) = head names
2022+getConName (RecGadtC names _ _) = head names
2023+#endif
2024+
16462025interleave :: [a] -> [a] -> [a]
16472026interleave (a1:a1s) (a2:a2s) = a1:a2:interleave a1s a2s
16482027interleave _ _ = []
@@ -1667,7 +2046,9 @@ isTyFamily (ConT n) = do
16672046#else
16682047 FamilyI (FamilyD TypeFam _ _ _) _ -> True
16692048#endif
2049+#if MIN_VERSION_template_haskell(2,9,0)
16702050 FamilyI ClosedTypeFamilyD{} _ -> True
2051+#endif
16712052 _ -> False
16722053isTyFamily _ = return False
16732054
@@ -1695,7 +2076,9 @@ mentionsName = go
16952076 go :: Type -> [Name] -> Bool
16962077 go (AppT t1 t2) names = go t1 names || go t2 names
16972078 go (SigT t _k) names = go t names
2079+#if MIN_VERSION_template_haskell(2,8,0)
16982080 || go _k names
2081+#endif
16992082 go (VarT n) names = n `elem` names
17002083 go _ _ = False
17012084
@@ -1751,28 +2134,37 @@ uncurryTy t = ([], t :| [])
17512134
17522135-- | Like uncurryType, except on a kind level.
17532136uncurryKind :: Kind -> NonEmpty Kind
2137+#if MIN_VERSION_template_haskell(2,8,0)
17542138uncurryKind = snd . uncurryTy
2139+#else
2140+uncurryKind (ArrowK k1 k2) = k1 <| uncurryKind k2
2141+uncurryKind k = k :| []
2142+#endif
17552143
17562144createKindChain :: Int -> Kind
17572145createKindChain = go starK
17582146 where
17592147 go :: Kind -> Int -> Kind
1760− go k 0 = k
2148+ go k !0 = k
2149+#if MIN_VERSION_template_haskell(2,8,0)
17612150 go k !n = go (AppT (AppT ArrowT StarT) k) (n - 1)
2151+#else
2152+ go k !n = go (ArrowK StarK k) (n - 1)
2153+#endif
17622154
17632155-- | Makes a string literal expression from a constructor's name.
1764−conNameExp :: Options -> ConstructorInfo -> Q Exp
2156+conNameExp :: Options -> Con -> Q Exp
17652157conNameExp opts = litE
17662158 . stringL
17672159 . constructorTagModifier opts
17682160 . nameBase
1769− . constructorName
2161+ . getConName
17702162
1771−-- | Extracts a record field label.
1772−fieldLabel :: Options -- ^ Encoding options
1773− -> Name
1774− -> String
1775−fieldLabel opts = fieldLabelModifier opts . nameBase
2163+-- | Creates a string literal expression from a record field label.
2164+fieldLabelExp :: Options -- ^ Encoding options
2165+ -> Name
2166+ -> Q Exp
2167+fieldLabelExp opts = litE . stringL . fieldLabelModifier opts . nameBase
17762168
17772169-- | The name of the outermost 'Value' constructor.
17782170valueConName :: Value -> String
@@ -1811,14 +2203,76 @@ canEtaReduce remaining dropped =
18112203-- Expanding type synonyms
18122204-------------------------------------------------------------------------------
18132205
1814−applySubstitutionKind :: Map Name Kind -> Type -> Type
1815−applySubstitutionKind = applySubstitution
2206+-- | Expands all type synonyms in a type. Written by Dan Rosén in the
2207+-- @genifunctors@ package (licensed under BSD3).
2208+expandSyn :: Type -> Q Type
2209+expandSyn (ForallT tvs ctx t) = ForallT tvs ctx <$> expandSyn t
2210+expandSyn t@AppT{} = expandSynApp t []
2211+expandSyn t@ConT{} = expandSynApp t []
2212+expandSyn (SigT t k) = do t' <- expandSyn t
2213+ k' <- expandSynKind k
2214+ return (SigT t' k')
2215+expandSyn t = return t
2216+
2217+expandSynKind :: Kind -> Q Kind
2218+#if MIN_VERSION_template_haskell(2,8,0)
2219+expandSynKind = expandSyn
2220+#else
2221+expandSynKind = return -- There are no kind synonyms to deal with
2222+#endif
2223+
2224+expandSynApp :: Type -> [Type] -> Q Type
2225+expandSynApp (AppT t1 t2) ts = do
2226+ t2' <- expandSyn t2
2227+ expandSynApp t1 (t2':ts)
2228+expandSynApp (ConT n) ts | nameBase n == "[]" = return $ foldl' AppT ListT ts
2229+expandSynApp t@(ConT n) ts = do
2230+ info <- reify n
2231+ case info of
2232+ TyConI (TySynD _ tvs rhs) ->
2233+ let (ts', ts'') = splitAt (length tvs) ts
2234+ subs = mkSubst tvs ts'
2235+ rhs' = substType subs rhs
2236+ in expandSynApp rhs' ts''
2237+ _ -> return $ foldl' AppT t ts
2238+expandSynApp t ts = do
2239+ t' <- expandSyn t
2240+ return $ foldl' AppT t' ts
2241+
2242+type TypeSubst = Map Name Type
2243+type KindSubst = Map Name Kind
2244+
2245+mkSubst :: [TyVarBndr] -> [Type] -> TypeSubst
2246+mkSubst vs ts =
2247+ let vs' = map un vs
2248+ un (PlainTV v) = v
2249+ un (KindedTV v _) = v
2250+ in M.fromList $ zip vs' ts
2251+
2252+substType :: TypeSubst -> Type -> Type
2253+substType subs (ForallT v c t) = ForallT v c $ substType subs t
2254+substType subs t@(VarT n) = M.findWithDefault t n subs
2255+substType subs (AppT t1 t2) = AppT (substType subs t1) (substType subs t2)
2256+substType subs (SigT t k) = SigT (substType subs t)
2257+#if MIN_VERSION_template_haskell(2,8,0)
2258+ (substType subs k)
2259+#else
2260+ k
2261+#endif
2262+substType _ t = t
2263+
2264+substKind :: KindSubst -> Type -> Type
2265+#if MIN_VERSION_template_haskell(2,8,0)
2266+substKind = substType
2267+#else
2268+substKind _ t = t -- There are no kind variables!
2269+#endif
18162270
18172271substNameWithKind :: Name -> Kind -> Type -> Type
1818−substNameWithKind n k = applySubstitutionKind (M.singleton n k)
2272+substNameWithKind n k = substKind (M.singleton n k)
18192273
18202274substNamesWithKindStar :: [Name] -> Type -> Type
1821−substNamesWithKindStar ns t = foldr' (`substNameWithKind` starK) t ns
2275+substNamesWithKindStar ns t = foldr' (flip substNameWithKind starK) t ns
18222276
18232277-------------------------------------------------------------------------------
18242278-- Error messages
@@ -1901,13 +2355,6 @@ data Direction = To | From
19012355-- | A representation of which typeclass method is being spliced in.
19022356data JSONFun = ToJSON | ToEncoding | ParseJSON
19032357
1904−-- | A refinement of JSONFun to [ToJSON, ToEncoding].
1905−data ToJSONFun = Value | Encoding
1906−
1907−targetToJSONFun :: ToJSONFun -> JSONFun
1908−targetToJSONFun Value = ToJSON
1909−targetToJSONFun Encoding = ToEncoding
1910−
19112358-- | A representation of which typeclass is being derived.
19122359data JSONClass = JSONClass { direction :: Direction, arity :: Arity }
19132360
@@ -1974,10 +2421,13 @@ data StarKindStatus = NotKindStar
19742421
19752422-- | Does a Type have kind * or k (for some kind variable k)?
19762423canRealizeKindStar :: Type -> StarKindStatus
1977−canRealizeKindStar t = case t of
1978− _ | hasKindStar t -> KindStar
1979− SigT _ (VarT k) -> IsKindVar k
1980− _ -> NotKindStar
2424+canRealizeKindStar t
2425+ | hasKindStar t = KindStar
2426+ | otherwise = case t of
2427+#if MIN_VERSION_template_haskell(2,8,0)
2428+ SigT _ (VarT k) -> IsKindVar k
2429+#endif
2430+ _ -> NotKindStar
19812431
19822432-- | Returns 'Just' the kind variable 'Name' of a 'StarKindStatus' if it exists.
19832433-- Otherwise, returns 'Nothing'.
Data/Aeson/Text.hs+4−5
@@ -1,5 +1,4 @@
11{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
32{-# LANGUAGE OverloadedStrings #-}
43-- |
54-- Module: Data.Aeson.Text
@@ -15,18 +14,18 @@
1514--
1615-- You can use the conversions to 'Builder's when embedding JSON messages as
1716-- parts of a protocol.
18−
1917module Data.Aeson.Text
2018 (
2119 encodeToLazyText
2220 , encodeToTextBuilder
2321 ) where
2422
23+import Prelude ()
2524import Prelude.Compat
2625
2726import Data.Aeson.Types (Value(..), ToJSON(..))
2827import Data.Aeson.Encoding (encodingToLazyByteString)
29−import Data.Semigroup ((<>))
28+import Data.Monoid ((<>))
3029import Data.Scientific (FPFormat(..), Scientific, base10Exponent)
3130import Data.Text.Lazy.Builder
3231import Data.Text.Lazy.Builder.Scientific (formatScientificBuilder)
@@ -47,8 +46,8 @@ encodeToLazyText = LT.decodeUtf8 . encodingToLazyByteString . toEncoding
4746-- embedded efficiently in a text-based protocol.
4847--
4948-- If you are going to immediately encode straight to a
50−-- 'L.ByteString', it is more efficient to use 'encode' (lazy ByteString)
51−-- or @'fromEncoding' . 'toEncoding'@ (ByteString.Builder) instead.
49+-- 'L.ByteString', it is more efficient to use 'encodeToBuilder'
50+-- instead.
5251--
5352-- /Note:/ Uses 'toJSON'
5453encodeToTextBuilder :: ToJSON a => a -> Builder
Data/Aeson/Types.hs+5−49
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21-- |
32-- Module: Data.Aeson.Types
43-- Copyright: (c) 2011-2016 Bryan O'Sullivan
@@ -26,7 +25,6 @@ module Data.Aeson.Types
2625 -- * Convenience types and functions
2726 , DotNetTime(..)
2827 , typeMismatch
29− , unexpected
3028 -- * Type conversion
3129 , Parser
3230 , Result(..)
@@ -38,9 +36,6 @@ module Data.Aeson.Types
3836 , ToJSON(..)
3937 , KeyValue(..)
4038 , modifyFailure
41− , prependFailure
42− , parserThrowError
43− , parserCatchError
4439
4540 -- ** Keys for maps
4641 , ToJSONKey(..)
@@ -53,12 +48,6 @@ module Data.Aeson.Types
5348 , coerceFromJSONKeyFunction
5449 , mapFromJSONKeyFunction
5550
56− -- *** Generic keys
57− , GToJSONKey()
58− , genericToJSONKey
59− , GFromJSONKey()
60− , genericFromJSONKey
61−
6251 -- ** Liftings to unary and binary type constructors
6352 , FromJSON1(..)
6453 , parseJSON1
@@ -74,8 +63,8 @@ module Data.Aeson.Types
7463 -- ** Generic JSON classes
7564 , GFromJSON(..)
7665 , FromArgs(..)
77− , GToJSON
78− , GToEncoding
66+ , GToJSON(..)
67+ , GToEncoding(..)
7968 , ToArgs(..)
8069 , Zero
8170 , One
@@ -90,9 +79,9 @@ module Data.Aeson.Types
9079 , withObject
9180 , withText
9281 , withArray
82+ , withNumber
9383 , withScientific
9484 , withBool
95− , withEmbeddedJSON
9685
9786 , pairs
9887 , foldable
@@ -101,51 +90,21 @@ module Data.Aeson.Types
10190 , (.:!)
10291 , (.!=)
10392 , object
104− , parseField
105− , parseFieldMaybe
106− , parseFieldMaybe'
107− , explicitParseField
108− , explicitParseFieldMaybe
109− , explicitParseFieldMaybe'
11093
11194 , listEncoding
11295 , listValue
11396 , listParser
11497
11598 -- * Generic and TH encoding configuration
116− , Options
117−
118− -- ** Options fields
119− -- $optionsFields
120− , fieldLabelModifier
121− , constructorTagModifier
122− , allNullaryToStringTag
123− , omitNothingFields
124− , sumEncoding
125− , unwrapUnaryRecords
126− , tagSingleConstructors
127− , rejectUnknownFields
128−
129− -- ** Options utilities
99+ , Options(..)
130100 , SumEncoding(..)
131101 , camelTo
132102 , camelTo2
133103 , defaultOptions
134104 , defaultTaggedObject
135−
136− -- ** Options for object keys
137− , JSONKeyOptions
138− , keyModifier
139− , defaultJSONKeyOptions
140−
141− -- * Parsing context
142− , (<?>)
143− , JSONPath
144− , JSONPathElement(..)
145− , formatPath
146− , formatRelativePath
147105 ) where
148106
107+import Prelude ()
149108import Prelude.Compat
150109
151110import Data.Aeson.Encoding (Encoding, unsafeToEncoding, fromEncoding, Series, pairs)
@@ -157,6 +116,3 @@ import Data.Foldable (toList)
157116foldable :: (Foldable t, ToJSON a) => t a -> Encoding
158117foldable = toEncoding . toList
159118{-# INLINE foldable #-}
160−
161−-- $optionsFields
162−-- The functions here are in fact record fields of the 'Options' type.
Data/Aeson/Types/Class.hs+7−26
@@ -1,11 +1,10 @@
11{-# LANGUAGE CPP #-}
2−{-# LANGUAGE ConstraintKinds #-}
32{-# LANGUAGE FlexibleContexts #-}
43{-# LANGUAGE FlexibleInstances #-}
54{-# LANGUAGE GADTs #-}
65{-# LANGUAGE MultiParamTypeClasses #-}
7−{-# LANGUAGE NoImplicitPrelude #-}
86{-# LANGUAGE ScopedTypeVariables #-}
7+{-# LANGUAGE TypeSynonymInstances #-}
98
109-- |
1110-- Module: Data.Aeson.Types.Class
@@ -37,8 +36,8 @@ module Data.Aeson.Types.Class
3736 -- * Generic JSON classes
3837 , GFromJSON(..)
3938 , FromArgs(..)
40− , GToJSON
41− , GToEncoding
39+ , GToJSON(..)
40+ , GToEncoding(..)
4241 , ToArgs(..)
4342 , Zero
4443 , One
@@ -58,11 +57,6 @@ module Data.Aeson.Types.Class
5857 , fromJSONKeyCoerce
5958 , coerceFromJSONKeyFunction
6059 , mapFromJSONKeyFunction
61− -- ** Generic keys
62− , GToJSONKey()
63− , genericToJSONKey
64− , GFromJSONKey()
65− , genericFromJSONKey
6660 -- * Object key-value pairs
6761 , KeyValue(..)
6862
@@ -75,35 +69,22 @@ module Data.Aeson.Types.Class
7569 , withObject
7670 , withText
7771 , withArray
72+ , withNumber
7873 , withScientific
7974 , withBool
80− , withEmbeddedJSON
8175
8276 -- * Functions
8377 , fromJSON
8478 , ifromJSON
85− , typeMismatch
86− , unexpected
87− , parseField
88− , parseFieldMaybe
89− , parseFieldMaybe'
90− , explicitParseField
91− , explicitParseFieldMaybe
92− , explicitParseFieldMaybe'
93− -- ** Operators
9479 , (.:)
9580 , (.:?)
9681 , (.:!)
9782 , (.!=)
83+ , typeMismatch
9884 ) where
9985
86+import Prelude ()
10087
10188import Data.Aeson.Types.FromJSON
10289import Data.Aeson.Types.Generic (One, Zero)
103−import Data.Aeson.Types.ToJSON hiding (GToJSON)
104−import qualified Data.Aeson.Types.ToJSON as ToJSON
105−import Data.Aeson.Types.Internal (Value)
106−import Data.Aeson.Encoding (Encoding)
107−
108−type GToJSON = ToJSON.GToJSON Value
109−type GToEncoding = ToJSON.GToJSON Encoding
90+import Data.Aeson.Types.ToJSON
Data/Aeson/Types/FromJSON.hs+457−983
@@ -5,17 +5,19 @@
55{-# LANGUAGE FlexibleInstances #-}
66{-# LANGUAGE GADTs #-}
77{-# LANGUAGE MultiParamTypeClasses #-}
8−{-# LANGUAGE NoImplicitPrelude #-}
8+{-# LANGUAGE NamedFieldPuns #-}
99{-# LANGUAGE OverloadedStrings #-}
10−{-# LANGUAGE PolyKinds #-}
1110{-# LANGUAGE RecordWildCards #-}
1211{-# LANGUAGE ScopedTypeVariables #-}
1312{-# LANGUAGE TypeOperators #-}
14−{-# LANGUAGE TupleSections #-}
13+{-# LANGUAGE TypeSynonymInstances #-}
1514{-# LANGUAGE UndecidableInstances #-}
1615{-# LANGUAGE ViewPatterns #-}
1716
18−#include "incoherent-compat.h"
17+#if __GLASGOW_HASKELL__ >= 706
18+{-# LANGUAGE PolyKinds #-}
19+#endif
20+
1921#include "overlapping-compat.h"
2022
2123-- TODO: Drop this when we remove support for Data.Attoparsec.Number
@@ -42,9 +44,6 @@ module Data.Aeson.Types.FromJSON
4244 , coerceFromJSONKeyFunction
4345 , mapFromJSONKeyFunction
4446
45− , GFromJSONKey()
46− , genericFromJSONKey
47−
4847 -- * List functions
4948 , listParser
5049
@@ -52,42 +51,34 @@ module Data.Aeson.Types.FromJSON
5251 , withObject
5352 , withText
5453 , withArray
54+ , withNumber
5555 , withScientific
5656 , withBool
57− , withEmbeddedJSON
5857
5958 -- * Functions
6059 , fromJSON
6160 , ifromJSON
62− , typeMismatch
63− , unexpected
64− , parseField
65− , parseFieldMaybe
66− , parseFieldMaybe'
67− , explicitParseField
68− , explicitParseFieldMaybe
69− , explicitParseFieldMaybe'
70− , parseIndexedJSON
71− -- ** Operators
7261 , (.:)
7362 , (.:?)
7463 , (.:!)
7564 , (.!=)
65+ , typeMismatch
7666
7767 -- * Internal
7868 , parseOptionalFieldWith
7969 ) where
8070
71+import Prelude ()
8172import Prelude.Compat
8273
83−import Control.Applicative ((<|>), Const(..), liftA2)
84−import Control.Monad (zipWithM)
74+import Control.Applicative ((<|>), Const(..))
75+import Control.Monad ((<=<), zipWithM)
8576import Data.Aeson.Internal.Functions (mapKey)
86−import Data.Aeson.Parser.Internal (eitherDecodeWith, jsonEOF)
8777import Data.Aeson.Types.Generic
8878import Data.Aeson.Types.Internal
79+import Data.Attoparsec.Number (Number(..))
8980import Data.Bits (unsafeShiftR)
90−import Data.Fixed (Fixed, HasResolution (resolution), Nano)
81+import Data.Fixed (Fixed, HasResolution)
9182import Data.Functor.Compose (Compose(..))
9283import Data.Functor.Identity (Identity(..))
9384import Data.Functor.Product (Product(..))
@@ -96,31 +87,25 @@ import Data.Hashable (Hashable(..))
9687import Data.Int (Int16, Int32, Int64, Int8)
9788import Data.List.NonEmpty (NonEmpty(..))
9889import Data.Maybe (fromMaybe)
99−import Data.Semigroup ((<>))
90+import Data.Monoid ((<>))
10091import Data.Proxy (Proxy(..))
10192import Data.Ratio ((%), Ratio)
102−import Data.Scientific (Scientific, base10Exponent)
93+import Data.Scientific (Scientific)
10394import Data.Tagged (Tagged(..))
10495import Data.Text (Text, pack, unpack)
105−import Data.Time (Day, DiffTime, LocalTime, NominalDiffTime, TimeOfDay, UTCTime, ZonedTime)
106−import Data.Time.Calendar.Compat (CalendarDiffDays (..), DayOfWeek (..))
107−import Data.Time.LocalTime.Compat (CalendarDiffTime (..))
108−import Data.Time.Clock.System.Compat (SystemTime (..))
109−import Data.Time.Format.Compat (parseTimeM, defaultTimeLocale)
96+import Data.Time (Day, LocalTime, NominalDiffTime, TimeOfDay, UTCTime, ZonedTime)
97+import Data.Time.Format (parseTime)
98+import Data.Time.Locale.Compat (defaultTimeLocale)
11099import Data.Traversable as Tr (sequence)
111100import Data.Vector (Vector)
112101import Data.Version (Version, parseVersion)
113−import Data.Void (Void)
114102import Data.Word (Word16, Word32, Word64, Word8)
115103import Foreign.Storable (Storable)
116−import Foreign.C.Types (CTime (..))
117104import GHC.Generics
118105import Numeric.Natural (Natural)
119106import Text.ParserCombinators.ReadP (readP_to_S)
120−import Unsafe.Coerce (unsafeCoerce)
121107import qualified Data.Aeson.Parser.Time as Time
122108import qualified Data.Attoparsec.ByteString.Char8 as A (endOfInput, parseOnly, scientific)
123−import qualified Data.ByteString.Lazy as L
124109import qualified Data.DList as DList
125110import qualified Data.HashMap.Strict as H
126111import qualified Data.HashSet as HashSet
@@ -136,27 +121,26 @@ import qualified Data.Text as T
136121import qualified Data.Text.Encoding as T
137122import qualified Data.Text.Lazy as LT
138123import qualified Data.Tree as Tree
139−import qualified Data.UUID.Types as UUID
140124import qualified Data.Vector as V
141125import qualified Data.Vector.Generic as VG
142126import qualified Data.Vector.Primitive as VP
143127import qualified Data.Vector.Storable as VS
144128import qualified Data.Vector.Unboxed as VU
145129
146−import qualified GHC.Exts as Exts
147−import qualified Data.Primitive.Array as PM
148−import qualified Data.Primitive.SmallArray as PM
149−import qualified Data.Primitive.Types as PM
130+import Unsafe.Coerce (unsafeCoerce)
150131
151−#if MIN_VERSION_primitive(0,6,4)
152−#if !MIN_VERSION_primitive(0,7,0)
153−import qualified Data.Primitive.UnliftedArray as PM
154−#endif
155−import qualified Data.Primitive.PrimArray as PM
132+#ifndef HAS_COERCIBLE
133+#define HAS_COERCIBLE (__GLASGOW_HASKELL__ >= 707)
156134#endif
157135
158−
136+#if HAS_COERCIBLE
159137import Data.Coerce (Coercible, coerce)
138+coerce' :: Coercible a b => a -> b
139+coerce' = coerce
140+#else
141+coerce' :: a -> b
142+coerce' = unsafeCoerce
143+#endif
160144
161145parseIndexedJSON :: (Value -> Parser a) -> Int -> Value -> Parser a
162146parseIndexedJSON p idx value = p value <?> Index idx
@@ -165,7 +149,7 @@ parseIndexedJSON p idx value = p value <?> Index idx
165149parseIndexedJSONPair :: (Value -> Parser a) -> (Value -> Parser b) -> Int -> Value -> Parser (a, b)
166150parseIndexedJSONPair keyParser valParser idx value = p value <?> Index idx
167151 where
168− p = withArray "(k, v)" $ \ab ->
152+ p = withArray "(k,v)" $ \ab ->
169153 let n = V.length ab
170154 in if n == 2
171155 then (,) <$> parseJSONElemAtIndex keyParser 0 ab
@@ -177,34 +161,43 @@ parseIndexedJSONPair keyParser valParser idx value = p value <?> Index idx
177161parseJSONElemAtIndex :: (Value -> Parser a) -> Int -> V.Vector Value -> Parser a
178162parseJSONElemAtIndex p idx ary = p (V.unsafeIndex ary idx) <?> Index idx
179163
164+scientificToNumber :: Scientific -> Number
165+scientificToNumber s
166+ | e < 0 = D $ Scientific.toRealFloat s
167+ | otherwise = I $ c * 10 ^ e
168+ where
169+ e = Scientific.base10Exponent s
170+ c = Scientific.coefficient s
171+{-# INLINE scientificToNumber #-}
172+
180173parseRealFloat :: RealFloat a => String -> Value -> Parser a
181−parseRealFloat _ (Number s) = pure $ Scientific.toRealFloat s
182−parseRealFloat _ Null = pure (0/0)
183−parseRealFloat name v = prependContext name (unexpected v)
174+parseRealFloat _ (Number s) = pure $ Scientific.toRealFloat s
175+parseRealFloat _ Null = pure (0/0)
176+parseRealFloat expected v = typeMismatch expected v
184177{-# INLINE parseRealFloat #-}
185178
186−parseIntegralFromScientific :: forall a. Integral a => Scientific -> Parser a
187−parseIntegralFromScientific s =
179+parseIntegralFromScientific :: forall a. Integral a => String -> Scientific -> Parser a
180+parseIntegralFromScientific expected s =
188181 case Scientific.floatingOrInteger s :: Either Double a of
189182 Right x -> pure x
190− Left _ -> fail $ "unexpected floating number " ++ show s
183+ Left _ -> fail $ "Floating number specified for " ++ expected ++ ": " ++ show s
191184{-# INLINE parseIntegralFromScientific #-}
192185
193186parseIntegral :: Integral a => String -> Value -> Parser a
194−parseIntegral name =
195− prependContext name . withBoundedScientific' parseIntegralFromScientific
187+parseIntegral expected =
188+ withScientific expected $ parseIntegralFromScientific expected
196189{-# INLINE parseIntegral #-}
197190
198−parseBoundedIntegralFromScientific :: (Bounded a, Integral a) => Scientific -> Parser a
199−parseBoundedIntegralFromScientific s = maybe
200− (fail $ "value is either floating or will cause over or underflow " ++ show s)
191+parseBoundedIntegralFromScientific :: (Bounded a, Integral a) => String -> Scientific -> Parser a
192+parseBoundedIntegralFromScientific expected s = maybe
193+ (fail $ expected ++ " is either floating or will cause over or underflow: " ++ show s)
201194 pure
202195 (Scientific.toBoundedInteger s)
203196{-# INLINE parseBoundedIntegralFromScientific #-}
204197
205198parseBoundedIntegral :: (Bounded a, Integral a) => String -> Value -> Parser a
206−parseBoundedIntegral name =
207− prependContext name . withScientific' parseBoundedIntegralFromScientific
199+parseBoundedIntegral expected =
200+ withScientific expected $ parseBoundedIntegralFromScientific expected
208201{-# INLINE parseBoundedIntegral #-}
209202
210203parseScientificText :: Text -> Parser Scientific
@@ -214,20 +207,13 @@ parseScientificText
214207 . T.encodeUtf8
215208
216209parseIntegralText :: Integral a => String -> Text -> Parser a
217−parseIntegralText name t =
218− prependContext name $
219− parseScientificText t
220− >>= rejectLargeExponent
221− >>= parseIntegralFromScientific
222− where
223− rejectLargeExponent :: Scientific -> Parser Scientific
224− rejectLargeExponent s = withBoundedScientific' pure (Number s)
210+parseIntegralText expected t =
211+ parseScientificText t >>= parseIntegralFromScientific expected
225212{-# INLINE parseIntegralText #-}
226213
227214parseBoundedIntegralText :: (Bounded a, Integral a) => String -> Text -> Parser a
228−parseBoundedIntegralText name t =
229− prependContext name $
230− parseScientificText t >>= parseBoundedIntegralFromScientific
215+parseBoundedIntegralText expected t =
216+ parseScientificText t >>= parseBoundedIntegralFromScientific expected
231217
232218parseOptionalFieldWith :: (Value -> Parser (Maybe a))
233219 -> Object -> Text -> Parser (Maybe a)
@@ -287,21 +273,14 @@ genericLiftParseJSON opts pj pjl = fmap to1 . gParseJSON opts (From1Args pj pjl)
287273--
288274-- The basic ways to signal a failed conversion are as follows:
289275--
290−-- * 'fail' yields a custom error message: it is the recommended way of
291−-- reporting a failure;
276+-- * 'empty' and 'mzero' work, but are terse and uninformative
292277--
293−-- * 'Control.Applicative.empty' (or 'Control.Monad.mzero') is uninformative:
294−-- use it when the error is meant to be caught by some @('<|>')@;
278+-- * 'fail' yields a custom error message
295279--
296−-- * 'typeMismatch' can be used to report a failure when the encountered value
297−-- is not of the expected JSON type; 'unexpected' is an appropriate alternative
298−-- when more than one type may be expected, or to keep the expected type
299−-- implicit.
280+-- * 'typeMismatch' produces an informative message for cases when the
281+-- value encountered is not of the expected type
300282--
301−-- 'prependFailure' (or 'modifyFailure') add more information to a parser's
302−-- error messages.
303−--
304−-- An example type and instance using 'typeMismatch' and 'prependFailure':
283+-- An example type and instance:
305284--
306285-- @
307286-- \-- Allow ourselves to write 'Text' literals.
@@ -309,30 +288,15 @@ genericLiftParseJSON opts pj pjl = fmap to1 . gParseJSON opts (From1Args pj pjl)
309288--
310289-- data Coord = Coord { x :: Double, y :: Double }
311290--
312−-- instance 'FromJSON' Coord where
313−-- 'parseJSON' ('Object' v) = Coord
314−-- '<$>' v '.:' \"x\"
315−-- '<*>' v '.:' \"y\"
291+-- instance FromJSON Coord where
292+-- parseJSON ('Object' v) = Coord '<$>'
293+-- v '.:' \"x\" '<*>'
294+-- v '.:' \"y\"
316295--
317−-- \-- We do not expect a non-'Object' value here.
318−-- \-- We could use 'Control.Applicative.empty' to fail, but 'typeMismatch'
319−-- \-- gives a much more informative error message.
320−-- 'parseJSON' invalid =
321−-- 'prependFailure' "parsing Coord failed, "
322−-- ('typeMismatch' \"Object\" invalid)
323−-- @
324−--
325−-- For this common case of only being concerned with a single
326−-- type of JSON value, the functions 'withObject', 'withScientific', etc.
327−-- are provided. Their use is to be preferred when possible, since
328−-- they are more terse. Using 'withObject', we can rewrite the above instance
329−-- (assuming the same language extension and data type) as:
330−--
331−-- @
332−-- instance 'FromJSON' Coord where
333−-- 'parseJSON' = 'withObject' \"Coord\" $ \\v -> Coord
334−-- '<$>' v '.:' \"x\"
335−-- '<*>' v '.:' \"y\"
296+-- \-- We do not expect a non-'Object' value here.
297+-- \-- We could use 'mzero' to fail, but 'typeMismatch'
298+-- \-- gives a much more informative error message.
299+-- parseJSON invalid = 'typeMismatch' \"Coord\" invalid
336300-- @
337301--
338302-- Instead of manually writing your 'FromJSON' instance, there are two options
@@ -340,7 +304,7 @@ genericLiftParseJSON opts pj pjl = fmap to1 . gParseJSON opts (From1Args pj pjl)
340304--
341305-- * "Data.Aeson.TH" provides Template Haskell functions which will derive an
342306-- instance at compile time. The generated instance is optimized for your type
343−-- so it will probably be more efficient than the following option.
307+-- so will probably be more efficient than the following two options:
344308--
345309-- * The compiler can provide a default generic implementation for
346310-- 'parseJSON'.
@@ -358,21 +322,18 @@ genericLiftParseJSON opts pj pjl = fmap to1 . gParseJSON opts (From1Args pj pjl)
358322--
359323-- data Coord = Coord { x :: Double, y :: Double } deriving 'Generic'
360324--
361−-- instance 'FromJSON' Coord
325+-- instance FromJSON Coord
362326-- @
363327--
364−-- The default implementation will be equivalent to
365−-- @parseJSON = 'genericParseJSON' 'defaultOptions'@; if you need different
366−-- options, you can customize the generic decoding by defining:
328+-- If @DefaultSignatures@ doesn't give exactly the results you want,
329+-- you can customize the generic decoding with only a tiny amount of
330+-- effort, using 'genericParseJSON' with your preferred 'Options':
367331--
368332-- @
369−-- customOptions = 'defaultOptions'
370−-- { 'fieldLabelModifier' = 'map' 'Data.Char.toUpper'
371−-- }
372−--
373−-- instance 'FromJSON' Coord where
374−-- 'parseJSON' = 'genericParseJSON' customOptions
333+-- instance FromJSON Coord where
334+-- parseJSON = 'genericParseJSON' 'defaultOptions'
375335-- @
336+
376337class FromJSON a where
377338 parseJSON :: Value -> Parser a
378339
@@ -380,11 +341,13 @@ class FromJSON a where
380341 parseJSON = genericParseJSON defaultOptions
381342
382343 parseJSONList :: Value -> Parser [a]
383− parseJSONList = withArray "[]" $ \a ->
384− zipWithM (parseIndexedJSON parseJSON) [0..]
344+ parseJSONList (Array a)
345+ = zipWithM (parseIndexedJSON parseJSON) [0..]
385346 . V.toList
386347 $ a
387348
349+ parseJSONList v = typeMismatch "[a]" v
350+
388351-------------------------------------------------------------------------------
389352-- Classes and types for map keys
390353-------------------------------------------------------------------------------
@@ -396,16 +359,6 @@ class FromJSON a where
396359-- > newtype SomeId = SomeId { getSomeId :: Text }
397360-- > deriving (Eq,Ord,Hashable,FromJSONKey)
398361--
399−-- If you have a sum of nullary constructors, you may use the generic
400−-- implementation:
401−--
402−-- @
403−-- data Color = Red | Green | Blue
404−-- deriving Generic
405−--
406−-- instance 'FromJSONKey' Color where
407−-- 'fromJSONKey' = 'genericFromJSONKey' 'defaultJSONKeyOptions'
408−-- @
409362class FromJSONKey a where
410363 -- | Strategy for parsing the key of a map-like container.
411364 fromJSONKey :: FromJSONKeyFunction a
@@ -428,7 +381,11 @@ class FromJSONKey a where
428381-- At the moment this type is intentionally not exported. 'FromJSONKeyFunction'
429382-- can be inspected, but cannot be constructed.
430383data CoerceText a where
384+#if HAS_COERCIBLE
431385 CoerceText :: Coercible Text a => CoerceText a
386+#else
387+ CoerceText :: CoerceText a
388+#endif
432389
433390-- | This type is related to 'ToJSONKeyFunction'. If 'FromJSONKeyValue' is used in the
434391-- 'FromJSONKey' instance, then 'ToJSONKeyValue' should be used in the 'ToJSONKey'
@@ -448,7 +405,7 @@ data FromJSONKeyFunction a
448405
449406-- | Only law abiding up to interpretation
450407instance Functor FromJSONKeyFunction where
451− fmap h (FromJSONKeyCoerce CoerceText) = FromJSONKeyText (h . coerce)
408+ fmap h (FromJSONKeyCoerce CoerceText) = FromJSONKeyText (h . coerce')
452409 fmap h (FromJSONKeyText f) = FromJSONKeyText (h . f)
453410 fmap h (FromJSONKeyTextParser f) = FromJSONKeyTextParser (fmap h . f)
454411 fmap h (FromJSONKeyValue f) = FromJSONKeyValue (fmap h . f)
@@ -462,7 +419,9 @@ instance Functor FromJSONKeyFunction where
462419--
463420-- On pre GHC 7.8 this is unconstrainted function.
464421fromJSONKeyCoerce ::
422+#if HAS_COERCIBLE
465423 Coercible Text a =>
424+#endif
466425 FromJSONKeyFunction a
467426fromJSONKeyCoerce = FromJSONKeyCoerce CoerceText
468427
@@ -470,91 +429,60 @@ fromJSONKeyCoerce = FromJSONKeyCoerce CoerceText
470429--
471430-- See note on 'fromJSONKeyCoerce'.
472431coerceFromJSONKeyFunction ::
432+#if HAS_COERCIBLE
473433 Coercible a b =>
434+#endif
474435 FromJSONKeyFunction a -> FromJSONKeyFunction b
436+#if HAS_COERCIBLE
475437coerceFromJSONKeyFunction = coerce
438+#else
439+coerceFromJSONKeyFunction (FromJSONKeyCoerce CoerceText) = FromJSONKeyCoerce CoerceText
440+coerceFromJSONKeyFunction (FromJSONKeyText f) = FromJSONKeyText (coerce' . f)
441+coerceFromJSONKeyFunction (FromJSONKeyTextParser f) = FromJSONKeyTextParser (fmap coerce' . f)
442+coerceFromJSONKeyFunction (FromJSONKeyValue f) = FromJSONKeyValue (fmap coerce' . f)
443+#endif
476444
477445{-# RULES
478446 "FromJSONKeyCoerce: fmap id" forall (x :: FromJSONKeyFunction a).
479447 fmap id x = x
480448 #-}
449+#if HAS_COERCIBLE
481450{-# RULES
482451 "FromJSONKeyCoerce: fmap coerce" forall x .
483452 fmap coerce x = coerceFromJSONKeyFunction x
484453 #-}
454+#endif
485455
486456-- | Same as 'fmap'. Provided for the consistency with 'ToJSONKeyFunction'.
487457mapFromJSONKeyFunction :: (a -> b) -> FromJSONKeyFunction a -> FromJSONKeyFunction b
488458mapFromJSONKeyFunction = fmap
489459
490−-- | 'fromJSONKey' for 'Generic' types.
491−-- These types must be sums of nullary constructors, whose names will be used
492−-- as keys for JSON objects.
493−--
494−-- See also 'genericToJSONKey'.
495−--
496−-- === __Example__
497−--
498−-- @
499−-- data Color = Red | Green | Blue
500−-- deriving 'Generic'
501−--
502−-- instance 'FromJSONKey' Color where
503−-- 'fromJSONKey' = 'genericFromJSONKey' 'defaultJSONKeyOptions'
504−-- @
505−genericFromJSONKey :: forall a. (Generic a, GFromJSONKey (Rep a))
506− => JSONKeyOptions
507− -> FromJSONKeyFunction a
508−genericFromJSONKey opts = FromJSONKeyTextParser $ \t ->
509− case parseSumFromString (keyModifier opts) t of
510− Nothing -> fail $
511− "invalid key " ++ show t ++ ", expected one of " ++ show cnames
512− Just k -> pure (to k)
513− where
514− cnames = unTagged2 (constructorTags (keyModifier opts) :: Tagged2 (Rep a) [String])
515−
516−class (ConstructorNames f, SumFromString f) => GFromJSONKey f where
517−instance (ConstructorNames f, SumFromString f) => GFromJSONKey f where
518−
519460-------------------------------------------------------------------------------
520461-- Functions needed for documentation
521462-------------------------------------------------------------------------------
522463
523464-- | Fail parsing due to a type mismatch, with a descriptive message.
524465--
525−-- The following wrappers should generally be prefered:
526−-- 'withObject', 'withArray', 'withText', 'withBool'.
527−--
528−-- ==== Error message example
466+-- Example usage:
529467--
530−-- > typeMismatch "Object" (String "oops")
531−-- > -- Error: "expected Object, but encountered String"
532−typeMismatch :: String -- ^ The name of the JSON type being parsed
533− -- (@\"Object\"@, @\"Array\"@, @\"String\"@, @\"Number\"@,
534− -- @\"Boolean\"@, or @\"Null\"@).
468+-- @
469+-- instance FromJSON Coord where
470+-- parseJSON ('Object' v) = {- type matches, life is good -}
471+-- parseJSON wat = 'typeMismatch' \"Coord\" wat
472+-- @
473+typeMismatch :: String -- ^ The name of the type you are trying to parse.
535474 -> Value -- ^ The actual value encountered.
536475 -> Parser a
537476typeMismatch expected actual =
538− fail $ "expected " ++ expected ++ ", but encountered " ++ typeOf actual
539−
540−-- | Fail parsing due to a type mismatch, when the expected types are implicit.
541−--
542−-- ==== Error message example
543−--
544−-- > unexpected (String "oops")
545−-- > -- Error: "unexpected String"
546−unexpected :: Value -> Parser a
547−unexpected actual = fail $ "unexpected " ++ typeOf actual
548−
549−-- | JSON type of a value, name of the head constructor.
550−typeOf :: Value -> String
551−typeOf v = case v of
552− Object _ -> "Object"
553− Array _ -> "Array"
554− String _ -> "String"
555− Number _ -> "Number"
556− Bool _ -> "Boolean"
557− Null -> "Null"
477+ fail $ "expected " ++ expected ++ ", encountered " ++ name
478+ where
479+ name = case actual of
480+ Object _ -> "Object"
481+ Array _ -> "Array"
482+ String _ -> "String"
483+ Number _ -> "Number"
484+ Bool _ -> "Boolean"
485+ Null -> "Null"
558486
559487-------------------------------------------------------------------------------
560488-- Lifings of FromJSON and ToJSON to unary and binary type constructors
@@ -567,7 +495,7 @@ typeOf v = case v of
567495--
568496-- * "Data.Aeson.TH" provides Template Haskell functions which will derive an
569497-- instance at compile time. The generated instance is optimized for your type
570−-- so it will probably be more efficient than the following option.
498+-- so will probably be more efficient than the following two options:
571499--
572500-- * The compiler can provide a default generic implementation for
573501-- 'liftParseJSON'.
@@ -585,20 +513,16 @@ typeOf v = case v of
585513--
586514-- data Pair a b = Pair { pairFst :: a, pairSnd :: b } deriving 'Generic1'
587515--
588−-- instance 'FromJSON' a => 'FromJSON1' (Pair a)
516+-- instance FromJSON a => FromJSON1 (Pair a)
589517-- @
590518--
591−-- If the default implementation doesn't give exactly the results you want,
519+-- If @DefaultSignatures@ doesn't give exactly the results you want,
592520-- you can customize the generic decoding with only a tiny amount of
593521-- effort, using 'genericLiftParseJSON' with your preferred 'Options':
594522--
595523-- @
596−-- customOptions = 'defaultOptions'
597−-- { 'fieldLabelModifier' = 'map' 'Data.Char.toUpper'
598−-- }
599−--
600−-- instance 'FromJSON' a => 'FromJSON1' (Pair a) where
601−-- 'liftParseJSON' = 'genericLiftParseJSON' customOptions
524+-- instance FromJSON a => FromJSON1 (Pair a) where
525+-- liftParseJSON = 'genericLiftParseJSON' 'defaultOptions'
602526-- @
603527class FromJSON1 f where
604528 liftParseJSON :: (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser (f a)
@@ -635,8 +559,9 @@ class FromJSON2 f where
635559 -> (Value -> Parser b)
636560 -> (Value -> Parser [b])
637561 -> Value -> Parser [f a b]
638− liftParseJSONList2 fa ga fb gb = withArray "[]" $ \vals ->
639− fmap V.toList (V.mapM (liftParseJSON2 fa ga fb gb) vals)
562+ liftParseJSONList2 fa ga fb gb v = case v of
563+ Array vals -> fmap V.toList (V.mapM (liftParseJSON2 fa ga fb gb) vals)
564+ _ -> typeMismatch "[a]" v
640565
641566-- | Lift the standard 'parseJSON' function through the type constructor.
642567parseJSON2 :: (FromJSON2 f, FromJSON a, FromJSON b) => Value -> Parser (f a b)
@@ -650,7 +575,7 @@ parseJSON2 = liftParseJSON2 parseJSON parseJSONList parseJSON parseJSONList
650575-- | Helper function to use with 'liftParseJSON'. See 'Data.Aeson.ToJSON.listEncoding'.
651576listParser :: (Value -> Parser a) -> Value -> Parser [a]
652577listParser f (Array xs) = fmap V.toList (V.mapM f xs)
653−listParser _ v = typeMismatch "Array" v
578+listParser _ v = typeMismatch "[a]" v
654579{-# INLINE listParser #-}
655580
656581-------------------------------------------------------------------------------
@@ -668,139 +593,48 @@ instance (FromJSON a) => FromJSON [a] where
668593-- Functions
669594-------------------------------------------------------------------------------
670595
671−-- | Add context to a failure message, indicating the name of the structure
672−-- being parsed.
673−--
674−-- > prependContext "MyType" (fail "[error message]")
675−-- > -- Error: "parsing MyType failed, [error message]"
676−prependContext :: String -> Parser a -> Parser a
677−prependContext name = prependFailure ("parsing " ++ name ++ " failed, ")
678−
679−-- | @'withObject' name f value@ applies @f@ to the 'Object' when @value@
680−-- is an 'Data.Aeson.Object' and fails otherwise.
681−--
682−-- ==== Error message example
683−--
684−-- > withObject "MyType" f (String "oops")
685−-- > -- Error: "parsing MyType failed, expected Object, but encountered String"
596+-- | @withObject expected f value@ applies @f@ to the 'Object' when @value@ is an @Object@
597+-- and fails using @'typeMismatch' expected@ otherwise.
686598withObject :: String -> (Object -> Parser a) -> Value -> Parser a
687−withObject _ f (Object obj) = f obj
688−withObject name _ v = prependContext name (typeMismatch "Object" v)
599+withObject _ f (Object obj) = f obj
600+withObject expected _ v = typeMismatch expected v
689601{-# INLINE withObject #-}
690602
691−-- | @'withText' name f value@ applies @f@ to the 'Text' when @value@ is a
692−-- 'Data.Aeson.String' and fails otherwise.
693−--
694−-- ==== Error message example
695−--
696−-- > withText "MyType" f Null
697−-- > -- Error: "parsing MyType failed, expected String, but encountered Null"
603+-- | @withText expected f value@ applies @f@ to the 'Text' when @value@ is a @String@
604+-- and fails using @'typeMismatch' expected@ otherwise.
698605withText :: String -> (Text -> Parser a) -> Value -> Parser a
699−withText _ f (String txt) = f txt
700−withText name _ v = prependContext name (typeMismatch "String" v)
606+withText _ f (String txt) = f txt
607+withText expected _ v = typeMismatch expected v
701608{-# INLINE withText #-}
702609
703−-- | @'withArray' expected f value@ applies @f@ to the 'Array' when @value@ is
704−-- an 'Data.Aeson.Array' and fails otherwise.
705−--
706−-- ==== Error message example
707−--
708−-- > withArray "MyType" f (String "oops")
709−-- > -- Error: "parsing MyType failed, expected Array, but encountered String"
610+-- | @withArray expected f value@ applies @f@ to the 'Array' when @value@ is an @Array@
611+-- and fails using @'typeMismatch' expected@ otherwise.
710612withArray :: String -> (Array -> Parser a) -> Value -> Parser a
711−withArray _ f (Array arr) = f arr
712−withArray name _ v = prependContext name (typeMismatch "Array" v)
613+withArray _ f (Array arr) = f arr
614+withArray expected _ v = typeMismatch expected v
713615{-# INLINE withArray #-}
714616
715−-- | @'withScientific' name f value@ applies @f@ to the 'Scientific' number
716−-- when @value@ is a 'Data.Aeson.Number' and fails using 'typeMismatch'
717−-- otherwise.
718−--
719−-- /Warning/: If you are converting from a scientific to an unbounded
720−-- type such as 'Integer' you may want to add a restriction on the
721−-- size of the exponent (see 'withBoundedScientific') to prevent
722−-- malicious input from filling up the memory of the target system.
723−--
724−-- ==== Error message example
725−--
726−-- > withScientific "MyType" f (String "oops")
727−-- > -- Error: "parsing MyType failed, expected Number, but encountered String"
617+-- | @withNumber expected f value@ applies @f@ to the 'Number' when @value@ is a 'Number'.
618+-- and fails using @'typeMismatch' expected@ otherwise.
619+withNumber :: String -> (Number -> Parser a) -> Value -> Parser a
620+withNumber expected f = withScientific expected (f . scientificToNumber)
621+{-# INLINE withNumber #-}
622+{-# DEPRECATED withNumber "Use withScientific instead" #-}
623+
624+-- | @withScientific expected f value@ applies @f@ to the 'Scientific' number when @value@ is a 'Number'.
625+-- and fails using @'typeMismatch' expected@ otherwise.
728626withScientific :: String -> (Scientific -> Parser a) -> Value -> Parser a
729−withScientific _ f (Number scientific) = f scientific
730−withScientific name _ v = prependContext name (typeMismatch "Number" v)
627+withScientific _ f (Number scientific) = f scientific
628+withScientific expected _ v = typeMismatch expected v
731629{-# INLINE withScientific #-}
732630
733−-- | A variant of 'withScientific' which doesn't use 'prependContext', so that
734−-- such context can be added separately in a way that also applies when the
735−-- continuation @f :: Scientific -> Parser a@ fails.
736−--
737−-- /Warning/: If you are converting from a scientific to an unbounded
738−-- type such as 'Integer' you may want to add a restriction on the
739−-- size of the exponent (see 'withBoundedScientific') to prevent
740−-- malicious input from filling up the memory of the target system.
741−--
742−-- ==== Error message examples
743−--
744−-- > withScientific' f (String "oops")
745−-- > -- Error: "unexpected String"
746−-- >
747−-- > prependContext "MyType" (withScientific' f (String "oops"))
748−-- > -- Error: "parsing MyType failed, unexpected String"
749−withScientific' :: (Scientific -> Parser a) -> Value -> Parser a
750−withScientific' f v = case v of
751− Number n -> f n
752− _ -> typeMismatch "Number" v
753−{-# INLINE withScientific' #-}
754−
755−-- | @'withBoundedScientific' name f value@ applies @f@ to the 'Scientific' number
756−-- when @value@ is a 'Number' with exponent less than or equal to 1024.
757−withBoundedScientific :: String -> (Scientific -> Parser a) -> Value -> Parser a
758−withBoundedScientific name f v = withBoundedScientific_ (prependContext name) f v
759−{-# INLINE withBoundedScientific #-}
760−
761−-- | A variant of 'withBoundedScientific' which doesn't use 'prependContext',
762−-- so that such context can be added separately in a way that also applies
763−-- when the continuation @f :: Scientific -> Parser a@ fails.
764−withBoundedScientific' :: (Scientific -> Parser a) -> Value -> Parser a
765−withBoundedScientific' f v = withBoundedScientific_ id f v
766−{-# INLINE withBoundedScientific' #-}
767−
768−-- | A variant of 'withBoundedScientific_' parameterized by a function to apply
769−-- to the 'Parser' in case of failure.
770−withBoundedScientific_ :: (Parser a -> Parser a) -> (Scientific -> Parser a) -> Value -> Parser a
771−withBoundedScientific_ whenFail f (Number scientific) =
772− if exp10 > 1024
773− then whenFail (fail msg)
774− else f scientific
775− where
776− exp10 = base10Exponent scientific
777− msg = "found a number with exponent " ++ show exp10 ++ ", but it must not be greater than 1024"
778−withBoundedScientific_ whenFail _ v =
779− whenFail (typeMismatch "Number" v)
780−{-# INLINE withBoundedScientific_ #-}
781−
782−-- | @'withBool' expected f value@ applies @f@ to the 'Bool' when @value@ is a
783−-- 'Boolean' and fails otherwise.
784−--
785−-- ==== Error message example
786−--
787−-- > withBool "MyType" f (String "oops")
788−-- > -- Error: "parsing MyType failed, expected Boolean, but encountered String"
631+-- | @withBool expected f value@ applies @f@ to the 'Bool' when @value@ is a @Bool@
632+-- and fails using @'typeMismatch' expected@ otherwise.
789633withBool :: String -> (Bool -> Parser a) -> Value -> Parser a
790−withBool _ f (Bool arr) = f arr
791−withBool name _ v = prependContext name (typeMismatch "Boolean" v)
634+withBool _ f (Bool arr) = f arr
635+withBool expected _ v = typeMismatch expected v
792636{-# INLINE withBool #-}
793637
794−-- | Decode a nested JSON-encoded string.
795−withEmbeddedJSON :: String -> (Value -> Parser a) -> Value -> Parser a
796−withEmbeddedJSON _ innerParser (String txt) =
797− either fail innerParser $ eitherDecode (L.fromStrict $ T.encodeUtf8 txt)
798− where
799− eitherDecode = eitherFormatError . eitherDecodeWith jsonEOF ifromJSON
800− eitherFormatError = either (Left . uncurry formatError) Right
801−withEmbeddedJSON name _ v = prependContext name (typeMismatch "String" v)
802−{-# INLINE withEmbeddedJSON #-}
803−
804638-- | Convert a value from JSON, failing if the types do not match.
805639fromJSON :: (FromJSON a) => Value -> Result a
806640fromJSON = parse parseJSON
@@ -819,68 +653,32 @@ ifromJSON = iparse parseJSON
819653-- in an object for it to be valid. If the key and value are
820654-- optional, use '.:?' instead.
821655(.:) :: (FromJSON a) => Object -> Text -> Parser a
822−(.:) = explicitParseField parseJSON
656+obj .: key = case H.lookup key obj of
657+ Nothing -> fail $ "key " ++ show key ++ " not present"
658+ Just v -> parseJSON v <?> Key key
823659{-# INLINE (.:) #-}
824660
825−-- | Retrieve the value associated with the given key of an 'Object'. The
826−-- result is 'Nothing' if the key is not present or if its value is 'Null',
827−-- or 'empty' if the value cannot be converted to the desired type.
661+-- | Retrieve the value associated with the given key of an 'Object'. The
662+-- result is 'Nothing' if the key is not present or value is 'Null', or 'empty'
663+-- if the value cannot be converted to the desired type.
828664--
829665-- This accessor is most useful if the key and value can be absent
830666-- from an object without affecting its validity. If the key and
831667-- value are mandatory, use '.:' instead.
832668(.:?) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
833−(.:?) = explicitParseFieldMaybe parseJSON
669+obj .:? key = case H.lookup key obj of
670+ Nothing -> pure Nothing
671+ Just v -> parseJSON v <?> Key key
834672{-# INLINE (.:?) #-}
835673
836−-- | Retrieve the value associated with the given key of an 'Object'.
837−-- The result is 'Nothing' if the key is not present or 'empty' if the
838−-- value cannot be converted to the desired type.
839−--
840−-- This differs from '.:?' by attempting to parse 'Null' the same as any
841−-- other JSON value, instead of interpreting it as 'Nothing'.
674+-- | Like '.:?', but the resulting parser will fail,
675+-- if the key is present but is 'Null'.
842676(.:!) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
843−(.:!) = explicitParseFieldMaybe' parseJSON
677+obj .:! key = case H.lookup key obj of
678+ Nothing -> pure Nothing
679+ Just v -> Just <$> parseJSON v <?> Key key
844680{-# INLINE (.:!) #-}
845681
846−-- | Function variant of '.:'.
847−parseField :: (FromJSON a) => Object -> Text -> Parser a
848−parseField = (.:)
849−{-# INLINE parseField #-}
850−
851−-- | Function variant of '.:?'.
852−parseFieldMaybe :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
853−parseFieldMaybe = (.:?)
854−{-# INLINE parseFieldMaybe #-}
855−
856−-- | Function variant of '.:!'.
857−parseFieldMaybe' :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
858−parseFieldMaybe' = (.:!)
859−{-# INLINE parseFieldMaybe' #-}
860−
861−-- | Variant of '.:' with explicit parser function.
862−--
863−-- E.g. @'explicitParseField' 'parseJSON1' :: ('FromJSON1' f, 'FromJSON' a) -> 'Object' -> 'Text' -> 'Parser' (f a)@
864−explicitParseField :: (Value -> Parser a) -> Object -> Text -> Parser a
865−explicitParseField p obj key = case H.lookup key obj of
866− Nothing -> fail $ "key " ++ show key ++ " not found"
867− Just v -> p v <?> Key key
868−{-# INLINE explicitParseField #-}
869−
870−-- | Variant of '.:?' with explicit parser function.
871−explicitParseFieldMaybe :: (Value -> Parser a) -> Object -> Text -> Parser (Maybe a)
872−explicitParseFieldMaybe p obj key = case H.lookup key obj of
873− Nothing -> pure Nothing
874− Just v -> liftParseJSON p (listParser p) v <?> Key key -- listParser isn't used by maybe instance.
875−{-# INLINE explicitParseFieldMaybe #-}
876−
877−-- | Variant of '.:!' with explicit parser function.
878−explicitParseFieldMaybe' :: (Value -> Parser a) -> Object -> Text -> Parser (Maybe a)
879−explicitParseFieldMaybe' p obj key = case H.lookup key obj of
880− Nothing -> pure Nothing
881− Just v -> Just <$> p v <?> Key key
882−{-# INLINE explicitParseFieldMaybe' #-}
883−
884682-- | Helper for use in combination with '.:?' to provide default
885683-- values for optional JSON object fields.
886684--
@@ -903,47 +701,11 @@ pmval .!= val = fromMaybe val <$> pmval
903701-- Generic parseJSON
904702-------------------------------------------------------------------------------
905703
906−instance GFromJSON arity V1 where
907− -- Whereof we cannot format, thereof we cannot parse:
908− gParseJSON _ _ _ = fail "Attempted to parse empty type"
909−
910−
911704instance OVERLAPPABLE_ (GFromJSON arity a) => GFromJSON arity (M1 i c a) where
912705 -- Meta-information, which is not handled elsewhere, is just added to the
913706 -- parsed value:
914707 gParseJSON opts fargs = fmap M1 . gParseJSON opts fargs
915708
916−-- Information for error messages
917−
918−type TypeName = String
919−type ConName = String
920−
921−-- | Add the name of the type being parsed to a parser's error messages.
922−contextType :: TypeName -> Parser a -> Parser a
923−contextType = prependContext
924−
925−-- | Add the tagKey that will be looked up while building an ADT
926−-- | Produce the error equivalent to
927−-- | Left "Error in $: parsing T failed, expected an object with keys "tag" and
928−-- | "contents", where "tag" i-- |s associated to one of ["Foo", "Bar"],
929−-- | The parser returned error was: could not find key "tag"
930−contextTag :: Text -> [String] -> Parser a -> Parser a
931−contextTag tagKey cnames = prependFailure
932− ("expected Object with key \"" ++ unpack tagKey ++ "\"" ++
933− " containing one of " ++ show cnames ++ ", ")
934−
935−-- | Add the name of the constructor being parsed to a parser's error messages.
936−contextCons :: ConName -> TypeName -> Parser a -> Parser a
937−contextCons cname tname = prependContext (showCons cname tname)
938−
939−-- | Render a constructor as @\"MyType(MyConstructor)\"@.
940−showCons :: ConName -> TypeName -> String
941−showCons cname tname = tname ++ "(" ++ cname ++ ")"
942−
943−--------------------------------------------------------------------------------
944−
945−-- Parsing single fields
946−
947709instance (FromJSON a) => GFromJSON arity (K1 i a) where
948710 -- Constant values are decoded using their FromJSON instance:
949711 gParseJSON _opts _ = fmap K1 . parseJSON
@@ -958,499 +720,327 @@ instance (FromJSON1 f) => GFromJSON One (Rec1 f) where
958720 -- FromJSON1 instance:
959721 gParseJSON _opts (From1Args pj pjl) = fmap Rec1 . liftParseJSON pj pjl
960722
723+instance GFromJSON arity U1 where
724+ -- Empty constructors are expected to be encoded as an empty array:
725+ gParseJSON _opts _ v
726+ | isEmptyArray v = pure U1
727+ | otherwise = typeMismatch "unit constructor (U1)" v
728+
729+instance (ConsFromJSON arity a) => GFromJSON arity (C1 c a) where
730+ -- Constructors need to be decoded differently depending on whether they're
731+ -- a record or not. This distinction is made by consParseJSON:
732+ gParseJSON opts fargs = fmap M1 . consParseJSON opts fargs
733+
734+instance ( FromProduct arity a, FromProduct arity b
735+ , ProductSize a, ProductSize b
736+ ) => GFromJSON arity (a :*: b) where
737+ -- Products are expected to be encoded to an array. Here we check whether we
738+ -- got an array of the same size as the product, then parse each of the
739+ -- product's elements using parseProduct:
740+ gParseJSON opts fargs = withArray "product (:*:)" $ \arr ->
741+ let lenArray = V.length arr
742+ lenProduct = (unTagged2 :: Tagged2 (a :*: b) Int -> Int)
743+ productSize in
744+ if lenArray == lenProduct
745+ then parseProduct opts fargs arr 0 lenProduct
746+ else fail $ "When expecting a product of " ++ show lenProduct ++
747+ " values, encountered an Array of " ++ show lenArray ++
748+ " elements instead"
749+
750+instance ( AllNullary (a :+: b) allNullary
751+ , ParseSum arity (a :+: b) allNullary
752+ ) => GFromJSON arity (a :+: b) where
753+ -- If all constructors of a sum datatype are nullary and the
754+ -- 'allNullaryToStringTag' option is set they are expected to be
755+ -- encoded as strings. This distinction is made by 'parseSum':
756+ gParseJSON opts fargs =
757+ (unTagged :: Tagged allNullary (Parser ((a :+: b) d)) ->
758+ Parser ((a :+: b) d))
759+ . parseSum opts fargs
760+
961761instance (FromJSON1 f, GFromJSON One g) => GFromJSON One (f :.: g) where
962762 -- If an occurrence of the last type parameter is nested inside two
963763 -- composed types, it is decoded by using the outermost type's FromJSON1
964764 -- instance to generically decode the innermost type:
965765 gParseJSON opts fargs =
966− let gpj = gParseJSON opts fargs in
967− fmap Comp1 . liftParseJSON gpj (listParser gpj)
968−
969−--------------------------------------------------------------------------------
970−
971−instance (GFromJSON' arity a, Datatype d) => GFromJSON arity (D1 d a) where
972− -- Meta-information, which is not handled elsewhere, is just added to the
973− -- parsed value:
974− gParseJSON opts fargs = fmap M1 . gParseJSON' (tname :* opts :* fargs)
975− where
976− tname = moduleName proxy ++ "." ++ datatypeName proxy
977− proxy = undefined :: M1 _i d _f _p
978−
979−-- | 'GFromJSON', after unwrapping the 'D1' constructor, now carrying the data
980−-- type's name.
981−class GFromJSON' arity f where
982− gParseJSON' :: TypeName :* Options :* FromArgs arity a
983− -> Value
984− -> Parser (f a)
985−
986−-- | Single constructor.
987−instance ( ConsFromJSON arity a
988− , AllNullary (C1 c a) allNullary
989− , ParseSum arity (C1 c a) allNullary
990− , Constructor c
991− ) => GFromJSON' arity (C1 c a) where
992− -- The option 'tagSingleConstructors' determines whether to wrap
993− -- a single-constructor type.
994− gParseJSON' p@(_ :* opts :* _)
995− | tagSingleConstructors opts
996− = (unTagged :: Tagged allNullary (Parser (C1 c a p)) -> Parser (C1 c a p))
997− . parseSum p
998− | otherwise = fmap M1 . consParseJSON (cname :* p)
999− where
1000− cname = conName (undefined :: M1 _i c _f _p)
1001−
1002−-- | Multiple constructors.
1003−instance ( AllNullary (a :+: b) allNullary
1004− , ParseSum arity (a :+: b) allNullary
1005− ) => GFromJSON' arity (a :+: b) where
1006− -- If all constructors of a sum datatype are nullary and the
1007− -- 'allNullaryToStringTag' option is set they are expected to be
1008− -- encoded as strings. This distinction is made by 'parseSum':
1009− gParseJSON' p =
1010− (unTagged :: Tagged allNullary (Parser ((a :+: b) _d)) ->
1011− Parser ((a :+: b) _d))
1012− . parseSum p
766+ let gpj = gParseJSON opts fargs in
767+ fmap Comp1 . liftParseJSON gpj (listParser gpj)
1013768
1014769--------------------------------------------------------------------------------
1015770
1016771class ParseSum arity f allNullary where
1017− parseSum :: TypeName :* Options :* FromArgs arity a
1018− -> Value
1019− -> Tagged allNullary (Parser (f a))
1020−
1021−instance ( ConstructorNames f
1022− , SumFromString f
1023− , FromPair arity f
1024− , FromTaggedObject arity f
1025− , FromUntaggedValue arity f
1026− ) => ParseSum arity f True where
1027− parseSum p@(tname :* opts :* _)
1028− | allNullaryToStringTag opts = Tagged . parseAllNullarySum tname opts
1029− | otherwise = Tagged . parseNonAllNullarySum p
1030−
1031−instance ( ConstructorNames f
1032− , FromPair arity f
1033− , FromTaggedObject arity f
1034− , FromUntaggedValue arity f
1035− ) => ParseSum arity f False where
1036− parseSum p = Tagged . parseNonAllNullarySum p
772+ parseSum :: Options -> FromArgs arity a
773+ -> Value -> Tagged allNullary (Parser (f a))
774+
775+instance ( SumFromString (a :+: b)
776+ , FromPair arity (a :+: b)
777+ , FromTaggedObject arity (a :+: b)
778+ , FromUntaggedValue arity (a :+: b)
779+ ) => ParseSum arity (a :+: b) True where
780+ parseSum opts fargs
781+ | allNullaryToStringTag opts = Tagged . parseAllNullarySum opts
782+ | otherwise = Tagged . parseNonAllNullarySum opts fargs
783+
784+instance ( FromPair arity (a :+: b)
785+ , FromTaggedObject arity (a :+: b)
786+ , FromUntaggedValue arity (a :+: b)
787+ ) => ParseSum arity (a :+: b) False where
788+ parseSum opts fargs = Tagged . parseNonAllNullarySum opts fargs
1037789
1038790--------------------------------------------------------------------------------
1039791
1040−parseAllNullarySum :: (SumFromString f, ConstructorNames f)
1041− => TypeName -> Options -> Value -> Parser (f a)
1042−parseAllNullarySum tname opts =
1043− withText tname $ \tag ->
1044− maybe (badTag tag) return $
1045− parseSumFromString modifier tag
1046− where
1047− badTag tag = failWithCTags tname modifier $ \cnames ->
1048− "expected one of the tags " ++ show cnames ++
1049− ", but found tag " ++ show tag
1050− modifier = constructorTagModifier opts
1051−
1052−-- | Fail with an informative error message about a mismatched tag.
1053−-- The error message is parameterized by the list of expected tags,
1054−-- to be inferred from the result type of the parser.
1055−failWithCTags
1056− :: forall f a t. ConstructorNames f
1057− => TypeName -> (String -> t) -> ([t] -> String) -> Parser (f a)
1058−failWithCTags tname modifier f =
1059− contextType tname . fail $ f cnames
1060− where
1061− cnames = unTagged2 (constructorTags modifier :: Tagged2 f [t])
792+parseAllNullarySum :: SumFromString f => Options -> Value -> Parser (f a)
793+parseAllNullarySum opts = withText "Text" $ \key ->
794+ maybe (notFound key) return $
795+ parseSumFromString opts key
1062796
1063797class SumFromString f where
1064− parseSumFromString :: (String -> String) -> Text -> Maybe (f a)
798+ parseSumFromString :: Options -> Text -> Maybe (f a)
1065799
1066800instance (SumFromString a, SumFromString b) => SumFromString (a :+: b) where
1067801 parseSumFromString opts key = (L1 <$> parseSumFromString opts key) <|>
1068802 (R1 <$> parseSumFromString opts key)
1069803
1070804instance (Constructor c) => SumFromString (C1 c U1) where
1071− parseSumFromString modifier key
1072− | key == name = Just $ M1 U1
1073− | otherwise = Nothing
1074− where
1075− name = pack $ modifier $ conName (undefined :: M1 _i c _f _p)
1076−
1077−-- For genericFromJSONKey
1078−instance SumFromString a => SumFromString (D1 d a) where
1079− parseSumFromString modifier key = M1 <$> parseSumFromString modifier key
1080−
1081−-- | List of all constructor tags.
1082−constructorTags :: ConstructorNames a => (String -> t) -> Tagged2 a [t]
1083−constructorTags modifier =
1084− fmap DList.toList (constructorNames' modifier)
1085−
1086−-- | List of all constructor names of an ADT, after a given conversion
1087−-- function. (Better inlining.)
1088−class ConstructorNames a where
1089− constructorNames' :: (String -> t) -> Tagged2 a (DList.DList t)
1090−
1091−instance (ConstructorNames a, ConstructorNames b) => ConstructorNames (a :+: b) where
1092− constructorNames' = liftA2 append constructorNames' constructorNames'
1093− where
1094− append
1095− :: Tagged2 a (DList.DList t)
1096− -> Tagged2 b (DList.DList t)
1097− -> Tagged2 (a :+: b) (DList.DList t)
1098− append (Tagged2 xs) (Tagged2 ys) = Tagged2 (DList.append xs ys)
1099−
1100−instance Constructor c => ConstructorNames (C1 c a) where
1101− constructorNames' f = Tagged2 (pure (f cname))
1102− where
1103− cname = conName (undefined :: M1 _i c _f _p)
1104−
1105−-- For genericFromJSONKey
1106−instance ConstructorNames a => ConstructorNames (D1 d a) where
1107− constructorNames' = retag . constructorNames'
1108− where
1109− retag :: Tagged2 a u -> Tagged2 (D1 d a) u
1110− retag (Tagged2 x) = Tagged2 x
805+ parseSumFromString opts key | key == name = Just $ M1 U1
806+ | otherwise = Nothing
807+ where
808+ name = pack $ constructorTagModifier opts $
809+ conName (undefined :: t c U1 p)
1111810
1112811--------------------------------------------------------------------------------
1113−parseNonAllNullarySum :: forall f c arity.
1114− ( FromPair arity f
1115− , FromTaggedObject arity f
1116− , FromUntaggedValue arity f
1117− , ConstructorNames f
1118− ) => TypeName :* Options :* FromArgs arity c
1119− -> Value -> Parser (f c)
1120−parseNonAllNullarySum p@(tname :* opts :* _) =
812+
813+parseNonAllNullarySum :: ( FromPair arity (a :+: b)
814+ , FromTaggedObject arity (a :+: b)
815+ , FromUntaggedValue arity (a :+: b)
816+ ) => Options -> FromArgs arity c
817+ -> Value -> Parser ((a :+: b) c)
818+parseNonAllNullarySum opts fargs =
1121819 case sumEncoding opts of
1122820 TaggedObject{..} ->
1123− withObject tname $ \obj -> do
1124− tag <- contextType tname . contextTag tagKey cnames_ $ obj .: tagKey
1125− fromMaybe (badTag tag <?> Key tagKey) $
1126− parseFromTaggedObject (tag :* contentsFieldName :* p) obj
1127− where
1128− tagKey = pack tagFieldName
1129− badTag tag = failWith_ $ \cnames ->
1130− "expected tag field to be one of " ++ show cnames ++
1131− ", but found tag " ++ show tag
1132− cnames_ = unTagged2 (constructorTags (constructorTagModifier opts) :: Tagged2 f [String])
821+ withObject "Object" $ \obj -> do
822+ tag <- obj .: pack tagFieldName
823+ fromMaybe (notFound tag) $
824+ parseFromTaggedObject opts fargs contentsFieldName obj tag
1133825
1134826 ObjectWithSingleField ->
1135− withObject tname $ \obj -> case H.toList obj of
1136− [(tag, v)] -> maybe (badTag tag) (<?> Key tag) $
1137− parsePair (tag :* p) v
1138− _ -> contextType tname . fail $
1139− "expected an Object with a single pair, but found " ++
1140− show (H.size obj) ++ " pairs"
1141− where
1142− badTag tag = failWith_ $ \cnames ->
1143− "expected an Object with a single pair where the tag is one of " ++
1144− show cnames ++ ", but found tag " ++ show tag
827+ withObject "Object" $ \obj ->
828+ case H.toList obj of
829+ [pair@(tag, _)] -> fromMaybe (notFound tag) $
830+ parsePair opts fargs pair
831+ _ -> fail "Object doesn't have a single field"
1145832
1146833 TwoElemArray ->
1147− withArray tname $ \arr -> case V.length arr of
1148− 2 | String tag <- V.unsafeIndex arr 0 ->
1149− maybe (badTag tag <?> Index 0) (<?> Index 1) $
1150− parsePair (tag :* p) (V.unsafeIndex arr 1)
1151− | otherwise ->
1152− contextType tname $
1153− fail "tag element is not a String" <?> Index 0
1154− len -> contextType tname . fail $
1155− "expected a 2-element Array, but encountered an Array of length " ++
1156− show len
1157− where
1158− badTag tag = failWith_ $ \cnames ->
1159− "expected tag of the 2-element Array to be one of " ++
1160− show cnames ++ ", but found tag " ++ show tag
834+ withArray "Array" $ \arr ->
835+ if V.length arr == 2
836+ then case V.unsafeIndex arr 0 of
837+ String tag -> fromMaybe (notFound tag) $
838+ parsePair opts fargs (tag, V.unsafeIndex arr 1)
839+ _ -> fail "First element is not a String"
840+ else fail "Array doesn't have 2 elements"
1161841
1162− UntaggedValue -> parseUntaggedValue p
1163− where
1164− failWith_ = failWithCTags tname (constructorTagModifier opts)
842+ UntaggedValue -> parseUntaggedValue opts fargs
1165843
1166844--------------------------------------------------------------------------------
1167845
1168846class FromTaggedObject arity f where
1169− -- The first two components of the parameter tuple are: the constructor tag
1170− -- to match against, and the contents field name.
1171− parseFromTaggedObject
1172− :: Text :* String :* TypeName :* Options :* FromArgs arity a
1173− -> Object
1174− -> Maybe (Parser (f a))
847+ parseFromTaggedObject :: Options -> FromArgs arity a
848+ -> String -> Object
849+ -> Text -> Maybe (Parser (f a))
1175850
1176851instance ( FromTaggedObject arity a, FromTaggedObject arity b) =>
1177852 FromTaggedObject arity (a :+: b) where
1178− parseFromTaggedObject p obj =
1179− (fmap L1 <$> parseFromTaggedObject p obj) <|>
1180− (fmap R1 <$> parseFromTaggedObject p obj)
853+ parseFromTaggedObject opts fargs contentsFieldName obj tag =
854+ (fmap L1 <$> parseFromTaggedObject opts fargs contentsFieldName obj tag) <|>
855+ (fmap R1 <$> parseFromTaggedObject opts fargs contentsFieldName obj tag)
1181856
1182−instance ( IsRecord f isRecord
1183− , FromTaggedObject' arity f isRecord
857+instance ( FromTaggedObject' arity f
1184858 , Constructor c
1185859 ) => FromTaggedObject arity (C1 c f) where
1186− parseFromTaggedObject (tag :* contentsFieldName :* p@(_ :* opts :* _))
1187− | tag == tag'
1188− = Just . fmap M1 .
1189− (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a)) .
1190− parseFromTaggedObject' (contentsFieldName :* cname :* p)
1191− | otherwise = const Nothing
1192− where
1193− tag' = pack $ constructorTagModifier opts cname
1194− cname = conName (undefined :: M1 _i c _f _p)
860+ parseFromTaggedObject opts fargs contentsFieldName obj tag
861+ | tag == name = Just $ M1 <$> parseFromTaggedObject'
862+ opts fargs contentsFieldName obj
863+ | otherwise = Nothing
864+ where
865+ name = pack $ constructorTagModifier opts $
866+ conName (undefined :: t c f p)
1195867
1196868--------------------------------------------------------------------------------
1197869
1198−class FromTaggedObject' arity f isRecord where
1199− -- The first component of the parameter tuple is the contents field name.
1200− parseFromTaggedObject'
1201− :: String :* ConName :* TypeName :* Options :* FromArgs arity a
1202− -> Object -> Tagged isRecord (Parser (f a))
1203−
1204−instance (RecordFromJSON arity f, FieldNames f) => FromTaggedObject' arity f True where
1205− -- Records are unpacked in the tagged object
1206− parseFromTaggedObject' (_ :* p) = Tagged . recordParseJSON (True :* p)
1207−
1208−instance (ConsFromJSON arity f) => FromTaggedObject' arity f False where
1209− -- Nonnullary nonrecords are encoded in the contents field
1210− parseFromTaggedObject' p obj = Tagged $ do
1211− contents <- contextCons cname tname (obj .: key)
1212− consParseJSON p' contents <?> Key key
1213− where
1214− key = pack contentsFieldName
1215− contentsFieldName :* p'@(cname :* tname :* _) = p
870+class FromTaggedObject' arity f where
871+ parseFromTaggedObject' :: Options -> FromArgs arity a -> String
872+ -> Object -> Parser (f a)
1216873
1217−instance OVERLAPPING_ FromTaggedObject' arity U1 False where
1218− -- Nullary constructors don't need a contents field
1219− parseFromTaggedObject' _ _ = Tagged (pure U1)
874+class FromTaggedObject'' arity f isRecord where
875+ parseFromTaggedObject'' :: Options -> FromArgs arity a -> String
876+ -> Object -> Tagged isRecord (Parser (f a))
877+
878+instance ( IsRecord f isRecord
879+ , FromTaggedObject'' arity f isRecord
880+ ) => FromTaggedObject' arity f where
881+ parseFromTaggedObject' opts fargs contentsFieldName =
882+ (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a)) .
883+ parseFromTaggedObject'' opts fargs contentsFieldName
884+
885+instance (FromRecord arity f) => FromTaggedObject'' arity f True where
886+ parseFromTaggedObject'' opts fargs _ =
887+ Tagged . parseRecord opts fargs Nothing
888+
889+instance (GFromJSON arity f) => FromTaggedObject'' arity f False where
890+ parseFromTaggedObject'' opts fargs contentsFieldName = Tagged .
891+ (gParseJSON opts fargs <=< (.: pack contentsFieldName))
892+
893+instance OVERLAPPING_ FromTaggedObject'' arity U1 False where
894+ parseFromTaggedObject'' _ _ _ _ = Tagged (pure U1)
1220895
1221896--------------------------------------------------------------------------------
1222897
1223−-- | Constructors need to be decoded differently depending on whether they're
1224−-- a record or not. This distinction is made by 'ConsParseJSON'.
1225898class ConsFromJSON arity f where
1226− consParseJSON
1227− :: ConName :* TypeName :* Options :* FromArgs arity a
1228− -> Value -> Parser (f a)
899+ consParseJSON :: Options -> FromArgs arity a
900+ -> Value -> Parser (f a)
1229901
1230902class ConsFromJSON' arity f isRecord where
1231− consParseJSON'
1232− :: ConName :* TypeName :* Options :* FromArgs arity a
1233− -> Value -> Tagged isRecord (Parser (f a))
903+ consParseJSON' :: Options -> FromArgs arity a
904+ -> Maybe Text -- ^ A dummy label
905+ -- (Nothing to use proper label)
906+ -> Value -> Tagged isRecord (Parser (f a))
1234907
1235908instance ( IsRecord f isRecord
1236909 , ConsFromJSON' arity f isRecord
1237910 ) => ConsFromJSON arity f where
1238− consParseJSON p =
1239− (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))
1240− . consParseJSON' p
911+ consParseJSON opts fargs v = let
912+ (v2,lab) = case (unwrapUnaryRecords opts,isUnary (undefined :: f a)) of
913+ -- use a dummy object with a dummy label
914+ (True,True) -> (object [(pack "dummy",v)], Just $ pack "dummy")
915+ _ ->(v,Nothing)
916+ in (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))
917+ $ consParseJSON' opts fargs lab v2
1241918
1242−instance OVERLAPPING_
1243− ( GFromJSON arity a, RecordFromJSON arity (S1 s a)
1244− ) => ConsFromJSON' arity (S1 s a) True where
1245− consParseJSON' p@(cname :* tname :* opts :* fargs)
1246− | unwrapUnaryRecords opts = Tagged . fmap M1 . gParseJSON opts fargs
1247− | otherwise = Tagged . withObject (showCons cname tname) (recordParseJSON (False :* p))
1248919
1249−instance RecordFromJSON arity f => ConsFromJSON' arity f True where
1250− consParseJSON' p@(cname :* tname :* _) =
1251− Tagged . withObject (showCons cname tname) (recordParseJSON (False :* p))
920+instance (FromRecord arity f) => ConsFromJSON' arity f True where
921+ consParseJSON' opts fargs mlab = Tagged . withObject "record (:*:)"
922+ (parseRecord opts fargs mlab)
1252923
1253−instance OVERLAPPING_
1254− ConsFromJSON' arity U1 False where
1255− -- Empty constructors are expected to be encoded as an empty array:
1256− consParseJSON' (cname :* tname :* _) v =
1257− Tagged . contextCons cname tname $ case v of
1258− Array a | V.null a -> pure U1
1259− | otherwise -> fail_ a
1260− _ -> typeMismatch "Array" v
1261− where
1262− fail_ a = fail $
1263− "expected an empty Array, but encountered an Array of length " ++
1264− show (V.length a)
1265−
1266−instance OVERLAPPING_
1267− GFromJSON arity f => ConsFromJSON' arity (S1 s f) False where
1268− consParseJSON' (_ :* _ :* opts :* fargs) =
1269− Tagged . fmap M1 . gParseJSON opts fargs
1270−
1271−instance (ProductFromJSON arity f, ProductSize f
1272− ) => ConsFromJSON' arity f False where
1273− consParseJSON' p = Tagged . productParseJSON0 p
924+instance (GFromJSON arity f) => ConsFromJSON' arity f False where
925+ consParseJSON' opts fargs _ = Tagged . gParseJSON opts fargs
1274926
1275927--------------------------------------------------------------------------------
1276928
1277−class FieldNames f where
1278− fieldNames :: f a -> [Text] -> [Text]
1279−
1280−instance (FieldNames a, FieldNames b) => FieldNames (a :*: b) where
1281− fieldNames _ =
1282− fieldNames (undefined :: a x) .
1283− fieldNames (undefined :: b y)
1284−
1285−instance (Selector s) => FieldNames (S1 s f) where
1286− fieldNames _ = (pack (selName (undefined :: M1 _i s _f _p)) :)
1287−
1288−class RecordFromJSON arity f where
1289− recordParseJSON
1290− :: Bool :* ConName :* TypeName :* Options :* FromArgs arity a
1291− -> Object -> Parser (f a)
1292−
1293−instance ( FieldNames f
1294− , RecordFromJSON' arity f
1295− ) => RecordFromJSON arity f where
1296− recordParseJSON (fromTaggedSum :* p@(cname :* tname :* opts :* _)) =
1297− \obj -> checkUnknown obj >> recordParseJSON' p obj
929+class FromRecord arity f where
930+ parseRecord :: Options -> FromArgs arity a
931+ -> Maybe Text -- ^ A dummy label
932+ -- (Nothing to use proper label)
933+ -> Object -> Parser (f a)
934+
935+instance ( FromRecord arity a
936+ , FromRecord arity b
937+ ) => FromRecord arity (a :*: b) where
938+ parseRecord opts fargs _ obj =
939+ (:*:) <$> parseRecord opts fargs Nothing obj
940+ <*> parseRecord opts fargs Nothing obj
941+
942+instance ( Selector s
943+ , GFromJSON arity a
944+ ) => FromRecord arity (S1 s a) where
945+ parseRecord opts fargs lab =
946+ (<?> Key label) . gParseJSON opts fargs <=< (.: label)
1298947 where
1299− knownFields :: H.HashMap Text ()
1300− knownFields = H.fromList $ map (,()) $
1301− fieldNames (undefined :: f a)
1302− [pack (tagFieldName (sumEncoding opts)) | fromTaggedSum]
1303− checkUnknown =
1304− if not (rejectUnknownFields opts)
1305− then \_ -> return ()
1306− else \obj -> case H.keys (H.difference obj knownFields) of
1307− [] -> return ()
1308− unknownFields -> contextCons cname tname $
1309− fail ("unknown fields: " ++ show unknownFields)
1310−
1311−class RecordFromJSON' arity f where
1312− recordParseJSON'
1313− :: ConName :* TypeName :* Options :* FromArgs arity a
1314− -> Object -> Parser (f a)
1315−
1316−instance ( RecordFromJSON' arity a
1317− , RecordFromJSON' arity b
1318− ) => RecordFromJSON' arity (a :*: b) where
1319− recordParseJSON' p obj =
1320− (:*:) <$> recordParseJSON' p obj
1321− <*> recordParseJSON' p obj
1322−
1323−instance OVERLAPPABLE_ (Selector s, GFromJSON arity a) =>
1324− RecordFromJSON' arity (S1 s a) where
1325− recordParseJSON' (cname :* tname :* opts :* fargs) obj = do
1326− fv <- contextCons cname tname (obj .: label)
1327− M1 <$> gParseJSON opts fargs fv <?> Key label
1328− where
1329− label = pack $ fieldLabelModifier opts sname
1330− sname = selName (undefined :: M1 _i s _f _p)
1331−
1332−instance INCOHERENT_ (Selector s, FromJSON a) =>
1333− RecordFromJSON' arity (S1 s (K1 i (Maybe a))) where
1334− recordParseJSON' (_ :* _ :* opts :* _) obj = M1 . K1 <$> obj .:? pack label
1335− where
1336− label = fieldLabelModifier opts sname
1337− sname = selName (undefined :: M1 _i s _f _p)
1338−
1339−-- Parse an Option like a Maybe.
1340−instance INCOHERENT_ (Selector s, FromJSON a) =>
1341− RecordFromJSON' arity (S1 s (K1 i (Semigroup.Option a))) where
1342− recordParseJSON' p obj = wrap <$> recordParseJSON' p obj
1343− where
1344− wrap :: S1 s (K1 i (Maybe a)) p -> S1 s (K1 i (Semigroup.Option a)) p
1345− wrap (M1 (K1 a)) = M1 (K1 (Semigroup.Option a))
948+ label = fromMaybe defLabel lab
949+ defLabel = pack . fieldLabelModifier opts $
950+ selName (undefined :: t s a p)
951+
952+instance OVERLAPPING_ (Selector s, FromJSON a) =>
953+ FromRecord arity (S1 s (K1 i (Maybe a))) where
954+ parseRecord _ _ (Just lab) obj = (M1 . K1) <$> obj .:? lab
955+ parseRecord opts _ Nothing obj = (M1 . K1) <$> obj .:? pack label
956+ where
957+ label = fieldLabelModifier opts $
958+ selName (undefined :: t s (K1 i (Maybe a)) p)
1346959
1347960--------------------------------------------------------------------------------
1348961
1349−productParseJSON0
1350− :: forall f arity a. (ProductFromJSON arity f, ProductSize f)
1351− => ConName :* TypeName :* Options :* FromArgs arity a
1352− -> Value -> Parser (f a)
1353− -- Products are expected to be encoded to an array. Here we check whether we
1354− -- got an array of the same size as the product, then parse each of the
1355− -- product's elements using productParseJSON:
1356−productParseJSON0 p@(cname :* tname :* _ :* _) =
1357− withArray (showCons cname tname) $ \arr ->
1358− let lenArray = V.length arr
1359− lenProduct = (unTagged2 :: Tagged2 f Int -> Int)
1360− productSize in
1361− if lenArray == lenProduct
1362− then productParseJSON p arr 0 lenProduct
1363− else contextCons cname tname $
1364− fail $ "expected an Array of length " ++ show lenProduct ++
1365− ", but encountered an Array of length " ++ show lenArray
1366−
1367−--
1368−
1369−class ProductFromJSON arity f where
1370− productParseJSON :: ConName :* TypeName :* Options :* FromArgs arity a
962+class FromProduct arity f where
963+ parseProduct :: Options -> FromArgs arity a
1371964 -> Array -> Int -> Int
1372965 -> Parser (f a)
1373966
1374−instance ( ProductFromJSON arity a
1375− , ProductFromJSON arity b
1376− ) => ProductFromJSON arity (a :*: b) where
1377− productParseJSON p arr ix len =
1378− (:*:) <$> productParseJSON p arr ix lenL
1379− <*> productParseJSON p arr ixR lenR
967+instance ( FromProduct arity a
968+ , FromProduct arity b
969+ ) => FromProduct arity (a :*: b) where
970+ parseProduct opts fargs arr ix len =
971+ (:*:) <$> parseProduct opts fargs arr ix lenL
972+ <*> parseProduct opts fargs arr ixR lenR
1380973 where
1381974 lenL = len `unsafeShiftR` 1
1382975 ixR = ix + lenL
1383976 lenR = len - lenL
1384977
1385−instance (GFromJSON arity a) => ProductFromJSON arity (S1 s a) where
1386− productParseJSON (_ :* _ :* opts :* fargs) arr ix _ =
1387− M1 <$> gParseJSON opts fargs (V.unsafeIndex arr ix) <?> Index ix
978+instance (GFromJSON arity a) => FromProduct arity (S1 s a) where
979+ parseProduct opts fargs arr ix _ =
980+ gParseJSON opts fargs $ V.unsafeIndex arr ix
1388981
1389982--------------------------------------------------------------------------------
1390983
1391984class FromPair arity f where
1392− -- The first component of the parameter tuple is the tag to match.
1393− parsePair :: Text :* TypeName :* Options :* FromArgs arity a
1394− -> Value
1395− -> Maybe (Parser (f a))
985+ parsePair :: Options -> FromArgs arity a
986+ -> Pair -> Maybe (Parser (f a))
1396987
1397988instance ( FromPair arity a
1398989 , FromPair arity b
1399990 ) => FromPair arity (a :+: b) where
1400− parsePair p pair =
1401− (fmap L1 <$> parsePair p pair) <|>
1402− (fmap R1 <$> parsePair p pair)
991+ parsePair opts fargs pair = (fmap L1 <$> parsePair opts fargs pair) <|>
992+ (fmap R1 <$> parsePair opts fargs pair)
1403993
1404994instance ( Constructor c
995+ , GFromJSON arity a
1405996 , ConsFromJSON arity a
1406997 ) => FromPair arity (C1 c a) where
1407− parsePair (tag :* p@(_ :* opts :* _)) v
1408− | tag == tag' = Just $ M1 <$> consParseJSON (cname :* p) v
998+ parsePair opts fargs (tag, value)
999+ | tag == tag' = Just $ gParseJSON opts fargs value
14091000 | otherwise = Nothing
1410− where
1411− tag' = pack $ constructorTagModifier opts cname
1412− cname = conName (undefined :: M1 _i c _a _p)
1001+ where
1002+ tag' = pack $ constructorTagModifier opts $
1003+ conName (undefined :: t c a p)
14131004
14141005--------------------------------------------------------------------------------
14151006
14161007class FromUntaggedValue arity f where
1417− parseUntaggedValue :: TypeName :* Options :* FromArgs arity a
1418− -> Value
1419− -> Parser (f a)
1008+ parseUntaggedValue :: Options -> FromArgs arity a
1009+ -> Value -> Parser (f a)
14201010
14211011instance
14221012 ( FromUntaggedValue arity a
14231013 , FromUntaggedValue arity b
14241014 ) => FromUntaggedValue arity (a :+: b)
14251015 where
1426− parseUntaggedValue p value =
1427− L1 <$> parseUntaggedValue p value <|>
1428− R1 <$> parseUntaggedValue p value
1016+ parseUntaggedValue opts fargs value =
1017+ L1 <$> parseUntaggedValue opts fargs value <|>
1018+ R1 <$> parseUntaggedValue opts fargs value
14291019
14301020instance OVERLAPPABLE_
1431− ( ConsFromJSON arity a
1432− , Constructor c
1021+ ( GFromJSON arity a
1022+ , ConsFromJSON arity a
14331023 ) => FromUntaggedValue arity (C1 c a)
14341024 where
1435− parseUntaggedValue p = fmap M1 . consParseJSON (cname :* p)
1436− where
1437− cname = conName (undefined :: M1 _i c _f _p)
1025+ parseUntaggedValue = gParseJSON
14381026
14391027instance OVERLAPPING_
14401028 ( Constructor c )
14411029 => FromUntaggedValue arity (C1 c U1)
14421030 where
1443− parseUntaggedValue (tname :* opts :* _) v =
1444− contextCons cname tname $ case v of
1445− String tag
1446− | tag == tag' -> pure $ M1 U1
1447− | otherwise -> fail_ tag
1448− _ -> typeMismatch "String" v
1449− where
1450− tag' = pack $ constructorTagModifier opts cname
1451− cname = conName (undefined :: M1 _i c _f _p)
1452− fail_ tag = fail $
1453− "expected tag " ++ show tag' ++ ", but found tag " ++ show tag
1031+ parseUntaggedValue opts _ (String s)
1032+ | s == pack (constructorTagModifier opts (conName (undefined :: t c U1 p))) =
1033+ pure $ M1 U1
1034+ | otherwise =
1035+ fail $ "Invalid tag: " ++ unpack s
1036+ parseUntaggedValue _ _ v = typeMismatch (conName (undefined :: t c U1 p)) v
1037+
1038+
1039+--------------------------------------------------------------------------------
1040+
1041+notFound :: Text -> Parser a
1042+notFound key = fail $ "The key \"" ++ unpack key ++ "\" was not found"
1043+{-# INLINE notFound #-}
14541044
14551045-------------------------------------------------------------------------------
14561046-- Instances
@@ -1508,20 +1098,17 @@ instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
15081098 parseJSON = parseJSON2
15091099 {-# INLINE parseJSON #-}
15101100
1511−instance FromJSON Void where
1512− parseJSON _ = fail "Cannot parse Void"
1513− {-# INLINE parseJSON #-}
1101+
15141102
15151103instance FromJSON Bool where
1516− parseJSON (Bool b) = pure b
1517− parseJSON v = typeMismatch "Bool" v
1104+ parseJSON = withBool "Bool" pure
15181105 {-# INLINE parseJSON #-}
15191106
15201107instance FromJSONKey Bool where
15211108 fromJSONKey = FromJSONKeyTextParser $ \t -> case t of
15221109 "true" -> pure True
15231110 "false" -> pure False
1524− _ -> fail $ "cannot parse key " ++ show t ++ " into Bool"
1111+ _ -> fail $ "Cannot parse key into Bool: " ++ T.unpack t
15251112
15261113instance FromJSON Ordering where
15271114 parseJSON = withText "Ordering" $ \s ->
@@ -1529,30 +1116,25 @@ instance FromJSON Ordering where
15291116 "LT" -> return LT
15301117 "EQ" -> return EQ
15311118 "GT" -> return GT
1532− _ -> fail $ "parsing Ordering failed, unexpected " ++ show s ++
1533− " (expected \"LT\", \"EQ\", or \"GT\")"
1119+ _ -> fail "Parsing Ordering value failed: expected \"LT\", \"EQ\", or \"GT\""
15341120
15351121instance FromJSON () where
15361122 parseJSON = withArray "()" $ \v ->
15371123 if V.null v
15381124 then pure ()
1539− else prependContext "()" $ fail "expected an empty array"
1125+ else fail "Expected an empty array"
15401126 {-# INLINE parseJSON #-}
15411127
15421128instance FromJSON Char where
1543− parseJSON = withText "Char" parseChar
1129+ parseJSON = withText "Char" $ \t ->
1130+ if T.compareLength t 1 == EQ
1131+ then pure $ T.head t
1132+ else fail "Expected a string of length 1"
15441133 {-# INLINE parseJSON #-}
15451134
1546− parseJSONList (String s) = pure (T.unpack s)
1547− parseJSONList v = typeMismatch "String" v
1135+ parseJSONList = withText "String" $ pure . T.unpack
15481136 {-# INLINE parseJSONList #-}
15491137
1550−parseChar :: Text -> Parser Char
1551−parseChar t =
1552− if T.compareLength t 1 == EQ
1553− then pure $ T.head t
1554− else prependContext "Char" $ fail "expected a string of length 1"
1555−
15561138instance FromJSON Double where
15571139 parseJSON = parseRealFloat "Double"
15581140 {-# INLINE parseJSON #-}
@@ -1564,6 +1146,12 @@ instance FromJSONKey Double where
15641146 "-Infinity" -> pure (negate 1/0)
15651147 _ -> Scientific.toRealFloat <$> parseScientificText t
15661148
1149+instance FromJSON Number where
1150+ parseJSON (Number s) = pure $ scientificToNumber s
1151+ parseJSON Null = pure (D (0/0))
1152+ parseJSON v = typeMismatch "Number" v
1153+ {-# INLINE parseJSON #-}
1154+
15671155instance FromJSON Float where
15681156 parseJSON = parseRealFloat "Float"
15691157 {-# INLINE parseJSON #-}
@@ -1576,30 +1164,17 @@ instance FromJSONKey Float where
15761164 _ -> Scientific.toRealFloat <$> parseScientificText t
15771165
15781166instance (FromJSON a, Integral a) => FromJSON (Ratio a) where
1579− parseJSON (Number x)
1580− | exp10 <= 1024
1581− , exp10 >= -1024 = return $! realToFrac x
1582− | otherwise = prependContext "Ratio" $ fail msg
1583− where
1584− exp10 = base10Exponent x
1585− msg = "found a number with exponent " ++ show exp10
1586− ++ ", but it must not be greater than 1024 or less than -1024"
1587− parseJSON o = objParser o
1588− where
1589− objParser = withObject "Rational" $ \obj -> do
1590− numerator <- obj .: "numerator"
1591− denominator <- obj .: "denominator"
1592− if denominator == 0
1593− then fail "Ratio denominator was 0"
1594− else pure $ numerator % denominator
1595− {-# INLINE parseJSON #-}
1596−
1597−-- | This instance includes a bounds check to prevent maliciously
1598−-- large inputs to fill up the memory of the target system. You can
1599−-- newtype 'Scientific' and provide your own instance using
1600−-- 'withScientific' if you want to allow larger inputs.
1167+ parseJSON = withObject "Rational" $ \obj ->
1168+ (%) <$> obj .: "numerator"
1169+ <*> obj .: "denominator"
1170+ {-# INLINE parseJSON #-}
1171+
1172+-- | /WARNING:/ Only parse fixed-precision numbers from trusted input
1173+-- since an attacker could easily fill up the memory of the target
1174+-- system by specifying a scientific number with a big exponent like
1175+-- @1e1000000000@.
16011176instance HasResolution a => FromJSON (Fixed a) where
1602− parseJSON = prependContext "Fixed" . withBoundedScientific' (pure . realToFrac)
1177+ parseJSON = withScientific "Fixed" $ pure . realToFrac
16031178 {-# INLINE parseJSON #-}
16041179
16051180instance FromJSON Int where
@@ -1609,10 +1184,10 @@ instance FromJSON Int where
16091184instance FromJSONKey Int where
16101185 fromJSONKey = FromJSONKeyTextParser $ parseBoundedIntegralText "Int"
16111186
1612−-- | This instance includes a bounds check to prevent maliciously
1613−-- large inputs to fill up the memory of the target system. You can
1614−-- newtype 'Scientific' and provide your own instance using
1615−-- 'withScientific' if you want to allow larger inputs.
1187+-- | /WARNING:/ Only parse Integers from trusted input since an
1188+-- attacker could easily fill up the memory of the target system by
1189+-- specifying a scientific number with a big exponent like
1190+-- @1e1000000000@.
16161191instance FromJSON Integer where
16171192 parseJSON = parseIntegral "Integer"
16181193 {-# INLINE parseJSON #-}
@@ -1621,21 +1196,16 @@ instance FromJSONKey Integer where
16211196 fromJSONKey = FromJSONKeyTextParser $ parseIntegralText "Integer"
16221197
16231198instance FromJSON Natural where
1624− parseJSON value = do
1625− integer <- parseIntegral "Natural" value
1626− parseNatural integer
1199+ parseJSON = withScientific "Natural" $ \s ->
1200+ if Scientific.coefficient s < 0
1201+ then fail $ "Expected a Natural number but got the negative number: " <> show s
1202+ else pure $ truncate s
16271203
16281204instance FromJSONKey Natural where
1629− fromJSONKey = FromJSONKeyTextParser $ \text -> do
1630− integer <- parseIntegralText "Natural" text
1631− parseNatural integer
1632−
1633−parseNatural :: Integer -> Parser Natural
1634−parseNatural integer =
1635− if integer < 0 then
1636− fail $ "parsing Natural failed, unexpected negative number " <> show integer
1637− else
1638− pure $ fromIntegral integer
1205+ fromJSONKey = FromJSONKeyTextParser $ \t -> parseScientificText t >>= \s ->
1206+ if Scientific.coefficient s < 0
1207+ then fail $ "Expected a Natural number but got the negative number: " <> show s
1208+ else pure $ truncate s
16391209
16401210instance FromJSON Int8 where
16411211 parseJSON = parseBoundedIntegral "Int8"
@@ -1700,9 +1270,6 @@ instance FromJSON Word64 where
17001270instance FromJSONKey Word64 where
17011271 fromJSONKey = FromJSONKeyTextParser $ parseBoundedIntegralText "Word64"
17021272
1703−instance FromJSON CTime where
1704− parseJSON = fmap CTime . parseJSON
1705− {-# INLINE parseJSON #-}
17061273
17071274instance FromJSON Text where
17081275 parseJSON = withText "Text" pure
@@ -1732,17 +1299,17 @@ parseVersionText = go . readP_to_S parseVersion . unpack
17321299 where
17331300 go [(v,[])] = return v
17341301 go (_ : xs) = go xs
1735− go _ = fail "parsing Version failed"
1302+ go _ = fail "could not parse Version"
17361303
17371304-------------------------------------------------------------------------------
17381305-- semigroups NonEmpty
17391306-------------------------------------------------------------------------------
17401307
17411308instance FromJSON1 NonEmpty where
1742− liftParseJSON p _ = withArray "NonEmpty" $
1309+ liftParseJSON p _ = withArray "NonEmpty a" $
17431310 (>>= ne) . Tr.sequence . zipWith (parseIndexedJSON p) [0..] . V.toList
17441311 where
1745− ne [] = fail "parsing NonEmpty failed, unexpected empty list"
1312+ ne [] = fail "Expected a NonEmpty but got an empty list"
17461313 ne (x:xs) = pure (x :| xs)
17471314 {-# INLINE liftParseJSON #-}
17481315
@@ -1750,6 +1317,8 @@ instance (FromJSON a) => FromJSON (NonEmpty a) where
17501317 parseJSON = parseJSON1
17511318 {-# INLINE parseJSON #-}
17521319
1320+
1321+
17531322-------------------------------------------------------------------------------
17541323-- scientific
17551324-------------------------------------------------------------------------------
@@ -1763,7 +1332,7 @@ instance FromJSON Scientific where
17631332-------------------------------------------------------------------------------
17641333
17651334instance FromJSON1 DList.DList where
1766− liftParseJSON p _ = withArray "DList" $
1335+ liftParseJSON p _ = withArray "DList a" $
17671336 fmap DList.fromList .
17681337 Tr.sequence . zipWith (parseIndexedJSON p) [0..] . V.toList
17691338 {-# INLINE liftParseJSON #-}
@@ -1790,7 +1359,7 @@ instance (FromJSON a) => FromJSON (Identity a) where
17901359 parseJSONList = liftParseJSONList parseJSON parseJSONList
17911360 {-# INLINE parseJSONList #-}
17921361
1793−instance (FromJSONKey a) => FromJSONKey (Identity a) where
1362+instance (FromJSONKey a, FromJSON a) => FromJSONKey (Identity a) where
17941363 fromJSONKey = coerceFromJSONKeyFunction (fromJSONKey :: FromJSONKeyFunction a)
17951364 fromJSONKeyList = coerceFromJSONKeyFunction (fromJSONKeyList :: FromJSONKeyFunction [a])
17961365
@@ -1840,7 +1409,7 @@ instance (FromJSON1 f, FromJSON1 g) => FromJSON1 (Sum f g) where
18401409 inr = "InR"
18411410
18421411 liftParseJSON _ _ _ = fail $
1843− "parsing Sum failed, expected an object with a single property " ++
1412+ "expected an object with a single property " ++
18441413 "where the property key should be either " ++
18451414 "\"InL\" or \"InR\""
18461415 {-# INLINE liftParseJSON #-}
@@ -1854,7 +1423,7 @@ instance (FromJSON1 f, FromJSON1 g, FromJSON a) => FromJSON (Sum f g a) where
18541423-------------------------------------------------------------------------------
18551424
18561425instance FromJSON1 Seq.Seq where
1857− liftParseJSON p _ = withArray "Seq" $
1426+ liftParseJSON p _ = withArray "Seq a" $
18581427 fmap Seq.fromList .
18591428 Tr.sequence . zipWith (parseIndexedJSON p) [0..] . V.toList
18601429 {-# INLINE liftParseJSON #-}
@@ -1888,15 +1457,15 @@ instance FromJSON a => FromJSON (IntMap.IntMap a) where
18881457
18891458instance (FromJSONKey k, Ord k) => FromJSON1 (M.Map k) where
18901459 liftParseJSON p _ = case fromJSONKey of
1891− FromJSONKeyCoerce _ -> withObject "Map" $
1460+ FromJSONKeyCoerce _-> withObject "Map k v" $
18921461 fmap (H.foldrWithKey (M.insert . unsafeCoerce) M.empty) . H.traverseWithKey (\k v -> p v <?> Key k)
1893− FromJSONKeyText f -> withObject "Map" $
1462+ FromJSONKeyText f -> withObject "Map k v" $
18941463 fmap (H.foldrWithKey (M.insert . f) M.empty) . H.traverseWithKey (\k v -> p v <?> Key k)
1895− FromJSONKeyTextParser f -> withObject "Map" $
1464+ FromJSONKeyTextParser f -> withObject "Map k v" $
18961465 H.foldrWithKey (\k v m -> M.insert <$> f k <?> Key k <*> p v <?> Key k <*> m) (pure M.empty)
1897− FromJSONKeyValue f -> withArray "Map" $ \arr ->
1898− fmap M.fromList . Tr.sequence .
1899− zipWith (parseIndexedJSONPair f p) [0..] . V.toList $ arr
1466+ FromJSONKeyValue f -> withArray "Map k v" $ \arr ->
1467+ M.fromList <$> (Tr.sequence .
1468+ zipWith (parseIndexedJSONPair f p) [0..] . V.toList $ arr)
19001469 {-# INLINE liftParseJSON #-}
19011470
19021471instance (FromJSONKey k, Ord k, FromJSON v) => FromJSON (M.Map k v) where
@@ -1916,24 +1485,12 @@ instance (FromJSON v) => FromJSON (Tree.Tree v) where
19161485 parseJSON = parseJSON1
19171486 {-# INLINE parseJSON #-}
19181487
1919−-------------------------------------------------------------------------------
1920−-- uuid
1921−-------------------------------------------------------------------------------
1922−
1923−instance FromJSON UUID.UUID where
1924− parseJSON = withText "UUID" $
1925− maybe (fail "invalid UUID") pure . UUID.fromText
1926−
1927−instance FromJSONKey UUID.UUID where
1928− fromJSONKey = FromJSONKeyTextParser $
1929− maybe (fail "invalid UUID") pure . UUID.fromText
1930−
19311488-------------------------------------------------------------------------------
19321489-- vector
19331490-------------------------------------------------------------------------------
19341491
19351492instance FromJSON1 Vector where
1936− liftParseJSON p _ = withArray "Vector" $
1493+ liftParseJSON p _ = withArray "Vector a" $
19371494 V.mapM (uncurry $ parseIndexedJSON p) . V.indexed
19381495 {-# INLINE liftParseJSON #-}
19391496
@@ -1947,14 +1504,14 @@ vectorParseJSON s = withArray s $ fmap V.convert . V.mapM (uncurry $ parseIndexe
19471504{-# INLINE vectorParseJSON #-}
19481505
19491506instance (Storable a, FromJSON a) => FromJSON (VS.Vector a) where
1950− parseJSON = vectorParseJSON "Data.Vector.Storable.Vector"
1507+ parseJSON = vectorParseJSON "Data.Vector.Storable.Vector a"
19511508
19521509instance (VP.Prim a, FromJSON a) => FromJSON (VP.Vector a) where
1953− parseJSON = vectorParseJSON "Data.Vector.Primitive.Vector"
1510+ parseJSON = vectorParseJSON "Data.Vector.Primitive.Vector a"
19541511 {-# INLINE parseJSON #-}
19551512
19561513instance (VG.Vector VU.Vector a, FromJSON a) => FromJSON (VU.Vector a) where
1957− parseJSON = vectorParseJSON "Data.Vector.Unboxed.Vector"
1514+ parseJSON = vectorParseJSON "Data.Vector.Unboxed.Vector a"
19581515 {-# INLINE parseJSON #-}
19591516
19601517-------------------------------------------------------------------------------
@@ -1968,15 +1525,15 @@ instance (Eq a, Hashable a, FromJSON a) => FromJSON (HashSet.HashSet a) where
19681525
19691526instance (FromJSONKey k, Eq k, Hashable k) => FromJSON1 (H.HashMap k) where
19701527 liftParseJSON p _ = case fromJSONKey of
1971− FromJSONKeyCoerce _ -> withObject "HashMap ~Text" $
1528+ FromJSONKeyCoerce _ -> withObject "HashMap ~Text v" $
19721529 uc . H.traverseWithKey (\k v -> p v <?> Key k)
1973− FromJSONKeyText f -> withObject "HashMap" $
1530+ FromJSONKeyText f -> withObject "HashMap k v" $
19741531 fmap (mapKey f) . H.traverseWithKey (\k v -> p v <?> Key k)
1975− FromJSONKeyTextParser f -> withObject "HashMap" $
1532+ FromJSONKeyTextParser f -> withObject "HashMap k v" $
19761533 H.foldrWithKey (\k v m -> H.insert <$> f k <?> Key k <*> p v <?> Key k <*> m) (pure H.empty)
1977− FromJSONKeyValue f -> withArray "Map" $ \arr ->
1978− fmap H.fromList . Tr.sequence .
1979− zipWith (parseIndexedJSONPair f p) [0..] . V.toList $ arr
1534+ FromJSONKeyValue f -> withArray "Map k v" $ \arr ->
1535+ H.fromList <$> (Tr.sequence .
1536+ zipWith (parseIndexedJSONPair f p) [0..] . V.toList $ arr)
19801537 where
19811538 uc :: Parser (H.HashMap Text v) -> Parser (H.HashMap k v)
19821539 uc = unsafeCoerce
@@ -1997,33 +1554,11 @@ instance FromJSON DotNetTime where
19971554 parseJSON = withText "DotNetTime" $ \t ->
19981555 let (s,m) = T.splitAt (T.length t - 5) t
19991556 t' = T.concat [s,".",m]
2000− in case parseTimeM True defaultTimeLocale "/Date(%s%Q)/" (unpack t') of
1557+ in case parseTime defaultTimeLocale "/Date(%s%Q)/" (unpack t') of
20011558 Just d -> pure (DotNetTime d)
20021559 _ -> fail "could not parse .NET time"
20031560 {-# INLINE parseJSON #-}
20041561
2005−-------------------------------------------------------------------------------
2006−-- primitive
2007−-------------------------------------------------------------------------------
2008−
2009−instance FromJSON a => FromJSON (PM.Array a) where
2010− -- note: we could do better than this if vector exposed the data
2011− -- constructor in Data.Vector.
2012− parseJSON = fmap Exts.fromList . parseJSON
2013−
2014−instance FromJSON a => FromJSON (PM.SmallArray a) where
2015− parseJSON = fmap Exts.fromList . parseJSON
2016−
2017−#if MIN_VERSION_primitive(0,6,4)
2018−instance (PM.Prim a,FromJSON a) => FromJSON (PM.PrimArray a) where
2019− parseJSON = fmap Exts.fromList . parseJSON
2020−
2021−#if !MIN_VERSION_primitive(0,7,0)
2022−instance (PM.PrimUnlifted a,FromJSON a) => FromJSON (PM.UnliftedArray a) where
2023− parseJSON = fmap Exts.fromList . parseJSON
2024−#endif
2025−#endif
2026−
20271562-------------------------------------------------------------------------------
20281563-- time
20291564-------------------------------------------------------------------------------
@@ -2049,17 +1584,6 @@ instance FromJSONKey LocalTime where
20491584 fromJSONKey = FromJSONKeyTextParser (Time.run Time.localTime)
20501585
20511586
2052−-- | Supported string formats:
2053−--
2054−-- @YYYY-MM-DD HH:MM Z@
2055−-- @YYYY-MM-DD HH:MM:SS Z@
2056−-- @YYYY-MM-DD HH:MM:SS.SSS Z@
2057−--
2058−-- The first space may instead be a @T@, and the second space is
2059−-- optional. The @Z@ represents UTC. The @Z@ may be replaced with a
2060−-- time zone offset of the form @+0000@ or @-08:00@, where the first
2061−-- two digits are hours, the @:@ is optional and the second two digits
2062−-- (also optional) are minutes.
20631587instance FromJSON ZonedTime where
20641588 parseJSON = withText "ZonedTime" (Time.run Time.zonedTime)
20651589
@@ -2074,57 +1598,14 @@ instance FromJSONKey UTCTime where
20741598 fromJSONKey = FromJSONKeyTextParser (Time.run Time.utcTime)
20751599
20761600
2077−-- | This instance includes a bounds check to prevent maliciously
2078−-- large inputs to fill up the memory of the target system. You can
2079−-- newtype 'Scientific' and provide your own instance using
2080−-- 'withScientific' if you want to allow larger inputs.
1601+-- | /WARNING:/ Only parse lengths of time from trusted input
1602+-- since an attacker could easily fill up the memory of the target
1603+-- system by specifying a scientific number with a big exponent like
1604+-- @1e1000000000@.
20811605instance FromJSON NominalDiffTime where
2082− parseJSON = withBoundedScientific "NominalDiffTime" $ pure . realToFrac
1606+ parseJSON = withScientific "NominalDiffTime" $ pure . realToFrac
20831607 {-# INLINE parseJSON #-}
20841608
2085−
2086−-- | This instance includes a bounds check to prevent maliciously
2087−-- large inputs to fill up the memory of the target system. You can
2088−-- newtype 'Scientific' and provide your own instance using
2089−-- 'withScientific' if you want to allow larger inputs.
2090−instance FromJSON DiffTime where
2091− parseJSON = withBoundedScientific "DiffTime" $ pure . realToFrac
2092− {-# INLINE parseJSON #-}
2093−
2094−instance FromJSON SystemTime where
2095− parseJSON v = prependContext "SystemTime" $ do
2096− n <- parseJSON v
2097− let n' = floor (n * fromInteger (resolution n) :: Nano)
2098− let (secs, nano) = n' `divMod` resolution n
2099− return (MkSystemTime (fromInteger secs) (fromInteger nano))
2100−
2101−instance FromJSON CalendarDiffTime where
2102− parseJSON = withObject "CalendarDiffTime" $ \obj -> CalendarDiffTime
2103− <$> obj .: "months"
2104− <*> obj .: "time"
2105−
2106−instance FromJSON CalendarDiffDays where
2107− parseJSON = withObject "CalendarDiffDays" $ \obj -> CalendarDiffDays
2108− <$> obj .: "months"
2109− <*> obj .: "days"
2110−
2111−instance FromJSON DayOfWeek where
2112− parseJSON = withText "DaysOfWeek" parseDayOfWeek
2113−
2114−parseDayOfWeek :: T.Text -> Parser DayOfWeek
2115−parseDayOfWeek t = case T.toLower t of
2116− "monday" -> return Monday
2117− "tuesday" -> return Tuesday
2118− "wednesday" -> return Wednesday
2119− "thursday" -> return Thursday
2120− "friday" -> return Friday
2121− "saturday" -> return Saturday
2122− "sunday" -> return Sunday
2123− _ -> fail "Invalid week day"
2124−
2125−instance FromJSONKey DayOfWeek where
2126− fromJSONKey = FromJSONKeyTextParser parseDayOfWeek
2127−
21281609-------------------------------------------------------------------------------
21291610-- base Monoid/Semigroup
21301611-------------------------------------------------------------------------------
@@ -2243,21 +1724,11 @@ instance FromJSON a => FromJSON (Semigroup.Option a) where
22431724-- tagged
22441725-------------------------------------------------------------------------------
22451726
2246−instance FromJSON1 Proxy where
2247− {-# INLINE liftParseJSON #-}
2248− liftParseJSON _ _ = fromNull "Proxy" Proxy
2249−
22501727instance FromJSON (Proxy a) where
22511728 {-# INLINE parseJSON #-}
2252− parseJSON = fromNull "Proxy" Proxy
2253−
2254−fromNull :: String -> a -> Value -> Parser a
2255−fromNull _ a Null = pure a
2256−fromNull c _ v = prependContext c (typeMismatch "Null" v)
1729+ parseJSON Null = pure Proxy
1730+ parseJSON v = typeMismatch "Proxy" v
22571731
2258−instance FromJSON2 Tagged where
2259− liftParseJSON2 _ _ p _ = fmap Tagged . p
2260− {-# INLINE liftParseJSON2 #-}
22611732
22621733instance FromJSON1 (Tagged a) where
22631734 liftParseJSON p _ = fmap Tagged . p
@@ -2280,7 +1751,10 @@ instance (FromJSON a, FromJSON b, FromJSON c) => FromJSONKey (a,b,c)
22801751instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSONKey (a,b,c,d)
22811752
22821753instance FromJSONKey Char where
2283− fromJSONKey = FromJSONKeyTextParser parseChar
1754+ fromJSONKey = FromJSONKeyTextParser $ \t ->
1755+ if T.length t == 1
1756+ then return (T.index t 0)
1757+ else typeMismatch "Expected Char but String didn't contain exactly one character" (String t)
22841758 fromJSONKeyList = FromJSONKeyText T.unpack
22851759
22861760instance (FromJSONKey a, FromJSON a) => FromJSONKey [a] where
Data/Aeson/Types/Generic.hs+8−12
@@ -1,11 +1,10 @@
11{-# LANGUAGE CPP #-}
22{-# LANGUAGE DataKinds #-}
3−{-# LANGUAGE DeriveFunctor #-}
43{-# LANGUAGE EmptyDataDecls #-}
54{-# LANGUAGE FlexibleInstances #-}
65{-# LANGUAGE FunctionalDependencies #-}
76{-# LANGUAGE KindSignatures #-}
8−{-# LANGUAGE NoImplicitPrelude #-}
7+{-# LANGUAGE MultiParamTypeClasses #-}
98{-# LANGUAGE ScopedTypeVariables #-}
109{-# LANGUAGE TypeOperators #-}
1110{-# LANGUAGE UndecidableInstances #-}
@@ -26,7 +25,7 @@
2625
2726module Data.Aeson.Types.Generic
2827 (
29− IsRecord
28+ IsRecord(..)
3029 , AllNullary
3130 , Tagged2(..)
3231 , True
@@ -35,9 +34,9 @@ module Data.Aeson.Types.Generic
3534 , Zero
3635 , One
3736 , ProductSize(..)
38− , (:*)(..)
3937 ) where
4038
39+import Prelude ()
4140import Prelude.Compat
4241
4342import GHC.Generics
@@ -45,8 +44,12 @@ import GHC.Generics
4544--------------------------------------------------------------------------------
4645
4746class IsRecord (f :: * -> *) isRecord | f -> isRecord
47+ where
48+ isUnary :: f a -> Bool
49+ isUnary = const True
4850
4951instance (IsRecord f isRecord) => IsRecord (f :*: g) isRecord
52+ where isUnary = const False
5053#if MIN_VERSION_base(4,9,0)
5154instance OVERLAPPING_ IsRecord (M1 S ('MetaSel 'Nothing u ss ds) f) False
5255#else
@@ -58,6 +61,7 @@ instance IsRecord Par1 True
5861instance IsRecord (Rec1 f) True
5962instance IsRecord (f :.: g) True
6063instance IsRecord U1 False
64+ where isUnary = const False
6165
6266--------------------------------------------------------------------------------
6367
@@ -76,7 +80,6 @@ instance AllNullary (Rec1 f) False
7680instance AllNullary U1 True
7781
7882newtype Tagged2 (s :: * -> *) b = Tagged2 {unTagged2 :: b}
79− deriving Functor
8083
8184--------------------------------------------------------------------------------
8285
@@ -109,10 +112,3 @@ instance (ProductSize a, ProductSize b) => ProductSize (a :*: b) where
109112
110113instance ProductSize (S1 s a) where
111114 productSize = Tagged2 1
112−
113−--------------------------------------------------------------------------------
114−
115−-- | Simple extensible tuple type to simplify passing around many parameters.
116−data a :* b = a :* b
117−
118−infixr 1 :*
Data/Aeson/Types/Internal.hs+26−175
@@ -1,9 +1,8 @@
11{-# LANGUAGE CPP #-}
22{-# LANGUAGE DeriveDataTypeable #-}
3−{-# LANGUAGE DeriveGeneric #-}
43{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5−{-# LANGUAGE NoImplicitPrelude #-}
64{-# LANGUAGE Rank2Types #-}
5+{-# LANGUAGE RecordWildCards #-}
76#if __GLASGOW_HASKELL__ >= 800
87-- a) THQ works on cross-compilers and unregisterised GHCs
98-- b) may make compilation faster as no dynamic loading is ever needed (not sure about this)
@@ -45,33 +44,16 @@ module Data.Aeson.Types.Internal
4544 , parseEither
4645 , parseMaybe
4746 , modifyFailure
48− , prependFailure
49− , parserThrowError
50− , parserCatchError
5147 , formatError
52− , formatPath
53− , formatRelativePath
5448 , (<?>)
5549 -- * Constructors and accessors
5650 , object
5751
5852 -- * Generic and TH encoding configuration
59− , Options(
60− fieldLabelModifier
61− , constructorTagModifier
62− , allNullaryToStringTag
63− , omitNothingFields
64− , sumEncoding
65− , unwrapUnaryRecords
66− , tagSingleConstructors
67− , rejectUnknownFields
68− )
69−
53+ , Options(..)
7054 , SumEncoding(..)
71− , JSONKeyOptions(keyModifier)
7255 , defaultOptions
7356 , defaultTaggedObject
74− , defaultJSONKeyOptions
7557
7658 -- * Used for changing CamelCase names into something else.
7759 , camelTo
@@ -81,6 +63,7 @@ module Data.Aeson.Types.Internal
8163 , DotNetTime(..)
8264 ) where
8365
66+import Prelude ()
8467import Prelude.Compat
8568
8669import Control.Applicative (Alternative(..))
@@ -92,7 +75,6 @@ import Data.Data (Data)
9275import Data.Foldable (foldl')
9376import Data.HashMap.Strict (HashMap)
9477import Data.Hashable (Hashable(..))
95−import Data.List (intercalate)
9678import Data.Scientific (Scientific)
9779import Data.Semigroup (Semigroup((<>)))
9880import Data.String (IsString(..))
@@ -101,8 +83,6 @@ import Data.Time (UTCTime)
10183import Data.Time.Format (FormatTime)
10284import Data.Typeable (Typeable)
10385import Data.Vector (Vector)
104−import GHC.Generics (Generic)
105−import qualified Control.Monad as Monad
10686import qualified Control.Monad.Fail as Fail
10787import qualified Data.HashMap.Strict as H
10888import qualified Data.Scientific as S
@@ -121,7 +101,7 @@ data JSONPathElement = Key Text
121101 | Index {-# UNPACK #-} !Int
122102 -- ^ JSON path element of an index into an
123103 -- array, \"array[index]\".
124− deriving (Eq, Show, Typeable, Ord)
104+ deriving (Eq, Show, Typeable)
125105type JSONPath = [JSONPathElement]
126106
127107-- | The internal result of running a 'Parser'.
@@ -156,7 +136,7 @@ instance Functor Result where
156136 fmap _ (Error err) = Error err
157137 {-# INLINE fmap #-}
158138
159−instance Monad.Monad IResult where
139+instance Monad IResult where
160140 return = pure
161141 {-# INLINE return #-}
162142
@@ -164,16 +144,14 @@ instance Monad.Monad IResult where
164144 IError path err >>= _ = IError path err
165145 {-# INLINE (>>=) #-}
166146
167−#if !(MIN_VERSION_base(4,13,0))
168147 fail = Fail.fail
169148 {-# INLINE fail #-}
170−#endif
171149
172150instance Fail.MonadFail IResult where
173151 fail err = IError [] err
174152 {-# INLINE fail #-}
175153
176−instance Monad.Monad Result where
154+instance Monad Result where
177155 return = pure
178156 {-# INLINE return #-}
179157
@@ -181,10 +159,8 @@ instance Monad.Monad Result where
181159 Error err >>= _ = Error err
182160 {-# INLINE (>>=) #-}
183161
184−#if !(MIN_VERSION_base(4,13,0))
185162 fail = Fail.fail
186163 {-# INLINE fail #-}
187−#endif
188164
189165instance Fail.MonadFail Result where
190166 fail err = Error err
@@ -281,9 +257,7 @@ type Failure f r = JSONPath -> String -> f r
281257-- | Success continuation.
282258type Success a f r = a -> f r
283259
284−-- | A JSON parser. N.B. This might not fit your usual understanding of
285−-- "parser". Instead you might like to think of 'Parser' as a "parse result",
286−-- i.e. a parser to which the input has already been applied.
260+-- | A JSON parser.
287261newtype Parser a = Parser {
288262 runParser :: forall f r.
289263 JSONPath
@@ -292,17 +266,14 @@ newtype Parser a = Parser {
292266 -> f r
293267 }
294268
295−instance Monad.Monad Parser where
269+instance Monad Parser where
296270 m >>= g = Parser $ \path kf ks -> let ks' a = runParser (g a) path kf ks
297271 in runParser m path kf ks'
298272 {-# INLINE (>>=) #-}
299273 return = pure
300274 {-# INLINE return #-}
301−
302−#if !(MIN_VERSION_base(4,13,0))
303275 fail = Fail.fail
304276 {-# INLINE fail #-}
305−#endif
306277
307278instance Fail.MonadFail Parser where
308279 fail msg = Parser $ \path kf _ks -> kf (reverse path) msg
@@ -345,7 +316,8 @@ instance Monoid (Parser a) where
345316apP :: Parser (a -> b) -> Parser a -> Parser b
346317apP d e = do
347318 b <- d
348− b <$> e
319+ a <- e
320+ return (b a)
349321{-# INLINE apP #-}
350322
351323-- | A JSON \"object\" (key\/value map).
@@ -361,7 +333,7 @@ data Value = Object !Object
361333 | Number !Scientific
362334 | Bool !Bool
363335 | Null
364− deriving (Eq, Read, Show, Typeable, Data, Generic)
336+ deriving (Eq, Read, Show, Typeable, Data)
365337
366338-- | A newtype wrapper for 'UTCTime' that uses the same non-standard
367339-- serialization format as Microsoft .NET, whose
@@ -461,17 +433,7 @@ parseEither m v = runParser (m v) [] onError Right
461433-- | Annotate an error message with a
462434-- <http://goessner.net/articles/JsonPath/ JSONPath> error location.
463435formatError :: JSONPath -> String -> String
464−formatError path msg = "Error in " ++ formatPath path ++ ": " ++ msg
465−
466−-- | Format a <http://goessner.net/articles/JsonPath/ JSONPath> as a 'String',
467−-- representing the root object as @$@.
468−formatPath :: JSONPath -> String
469−formatPath path = "$" ++ formatRelativePath path
470−
471−-- | Format a <http://goessner.net/articles/JsonPath/ JSONPath> as a 'String'
472−-- which represents the path relative to some root object.
473−formatRelativePath :: JSONPath -> String
474−formatRelativePath path = format "" path
436+formatError path msg = "Error in " ++ format "$" path ++ ": " ++ msg
475437 where
476438 format :: String -> JSONPath -> String
477439 format pfx [] = pfx
@@ -534,40 +496,13 @@ p <?> pathElem = Parser $ \path kf ks -> runParser p (pathElem:path) kf ks
534496--
535497-- Since 0.6.2.0
536498modifyFailure :: (String -> String) -> Parser a -> Parser a
537−modifyFailure f (Parser p) = Parser $ \path kf ks ->
538− p path (\p' m -> kf p' (f m)) ks
539−
540−-- | If the inner 'Parser' failed, prepend the given string to the failure
541−-- message.
542−--
543−-- @
544−-- 'prependFailure' s = 'modifyFailure' (s '++')
545−-- @
546−prependFailure :: String -> Parser a -> Parser a
547−prependFailure = modifyFailure . (++)
548−
549−-- | Throw a parser error with an additional path.
550−--
551−-- @since 1.2.1.0
552−parserThrowError :: JSONPath -> String -> Parser a
553−parserThrowError path' msg = Parser $ \path kf _ks ->
554− kf (reverse path ++ path') msg
555−
556−-- | A handler function to handle previous errors and return to normal execution.
557−--
558−-- @since 1.2.1.0
559−parserCatchError :: Parser a -> (JSONPath -> String -> Parser a) -> Parser a
560−parserCatchError (Parser p) handler = Parser $ \path kf ks ->
561− p path (\e msg -> runParser (handler e msg) path kf ks) ks
499+modifyFailure f (Parser p) = Parser $ \path kf ks -> p path (\p' m -> kf p' (f m)) ks
562500
563501--------------------------------------------------------------------------------
564502-- Generic and TH encoding configuration
565503--------------------------------------------------------------------------------
566504
567505-- | Options that specify how to encode\/decode your datatype to\/from JSON.
568−--
569−-- Options can be set using record syntax on 'defaultOptions' with the fields
570−-- below.
571506data Options = Options
572507 { fieldLabelModifier :: String -> String
573508 -- ^ Function applied to field labels.
@@ -584,67 +519,24 @@ data Options = Options
584519 -- ^ If 'True' record fields with a 'Nothing' value will be
585520 -- omitted from the resulting object. If 'False' the resulting
586521 -- object will include those fields mapping to @null@.
587− --
588− -- === Note
589− --
590− -- Setting 'omitNothingFields' to 'True' only affects fields which are of
591− -- type 'Maybe' /uniformly/ in the 'ToJSON' or 'FromJSON' instance. In
592− -- particular, if the type of a field is declared as a type variable, it
593− -- will not be omitted from the JSON object, unless the field is
594− -- specialized upfront in the instance.
595− --
596− -- ==== __Example__
597− --
598− -- The generic instance for the following type @Fruit@ depends on whether
599− -- the instance head is @Fruit a@ or @Fruit (Maybe a)@.
600− --
601− -- @
602− -- data Fruit a =
603− -- { apples :: a -- A field whose type is a type variable.
604− -- , oranges :: 'Maybe' Int
605− -- }
606− --
607− -- options :: 'Options'
608− -- options = 'defaultOptions' { 'omitNothingFields' = 'True' }
609− --
610− -- -- apples required, oranges optional
611− -- -- Even if 'Data.Aeson.fromJSON' is then specialized to (Fruit ('Maybe' a)).
612− -- instance 'Data.Aeson.FromJSON' a => 'Data.Aeson.FromJSON' (Fruit a) where
613− -- 'Data.Aeson.fromJSON' = 'Data.Aeson.genericFromJSON' options
614− --
615− -- -- apples optional, oranges optional
616− -- -- In this instance, the field apples is uniformly of type ('Maybe' a).
617− -- instance 'Data.Aeson.FromJSON' a => 'Data.Aeson.FromJSON' (Fruit ('Maybe' a)) where
618− -- 'Data.Aeson.fromJSON' = 'Data.Aeson.genericFromJSON' options
619− -- @
620522 , sumEncoding :: SumEncoding
621523 -- ^ Specifies how to encode constructors of a sum datatype.
622524 , unwrapUnaryRecords :: Bool
623525 -- ^ Hide the field name when a record constructor has only one
624526 -- field, like a newtype.
625− , tagSingleConstructors :: Bool
626− -- ^ Encode types with a single constructor as sums,
627− -- so that `allNullaryToStringTag` and `sumEncoding` apply.
628− , rejectUnknownFields :: Bool
629− -- ^ Applies only to 'Data.Aeson.FromJSON' instances. If a field appears in
630− -- the parsed object map, but does not appear in the target object, parsing
631− -- will fail, with an error message indicating which fields were unknown.
632527 }
633528
634529instance Show Options where
635− show (Options f c a o s u t r) =
636− "Options {"
637− ++ intercalate ", "
638− [ "fieldLabelModifier =~ " ++ show (f "exampleField")
639− , "constructorTagModifier =~ " ++ show (c "ExampleConstructor")
640− , "allNullaryToStringTag = " ++ show a
641− , "omitNothingFields = " ++ show o
642− , "sumEncoding = " ++ show s
643− , "unwrapUnaryRecords = " ++ show u
644− , "tagSingleConstructors = " ++ show t
645− , "rejectUnknownFields = " ++ show r
646− ]
647− ++ "}"
530+ show Options{..} = "Options {" ++
531+ "fieldLabelModifier =~ " ++
532+ show (fieldLabelModifier "exampleField") ++ ", " ++
533+ "constructorTagModifier =~ " ++
534+ show (constructorTagModifier "ExampleConstructor") ++ ", " ++
535+ "allNullaryToStringTag = " ++ show allNullaryToStringTag ++ ", " ++
536+ "omitNothingFields = " ++ show omitNothingFields ++ ", " ++
537+ "sumEncoding = " ++ show sumEncoding ++ ", " ++
538+ "unwrapUnaryRecords = " ++ show unwrapUnaryRecords ++
539+ "}"
648540
649541-- | Specifies how to encode constructors of a sum datatype.
650542data SumEncoding =
@@ -662,18 +554,18 @@ data SumEncoding =
662554 -- the 'contentsFieldName' field.
663555 | UntaggedValue
664556 -- ^ Constructor names won't be encoded. Instead only the contents of the
665− -- constructor will be encoded as if the type had a single constructor. JSON
557+ -- constructor will be encoded as if the type had single constructor. JSON
666558 -- encodings have to be disjoint for decoding to work properly.
667559 --
668560 -- When decoding, constructors are tried in the order of definition. If some
669561 -- encodings overlap, the first one defined will succeed.
670562 --
671− -- /Note:/ Nullary constructors are encoded as strings (using
563+ -- /Note:/ Nullary constructors are encoded as the string (using
672564 -- 'constructorTagModifier'). Having a nullary constructor alongside a
673565 -- single field constructor that encodes to a string leads to ambiguity.
674566 --
675567 -- /Note:/ Only the last error is kept when decoding, so in the case of
676− -- malformed JSON, only an error for the last constructor will be reported.
568+ -- mailformed JSON, only an error for the last constructor will be reported.
677569 | ObjectWithSingleField
678570 -- ^ A constructor will be encoded to an object with a single
679571 -- field named after the constructor tag (modified by the
@@ -686,33 +578,6 @@ data SumEncoding =
686578 -- contents of the constructor.
687579 deriving (Eq, Show)
688580
689−-- | Options for encoding keys with 'Data.Aeson.Types.genericFromJSONKey' and
690−-- 'Data.Aeson.Types.genericToJSONKey'.
691−data JSONKeyOptions = JSONKeyOptions
692− { keyModifier :: String -> String
693− -- ^ Function applied to keys. Its result is what goes into the encoded
694− -- 'Value'.
695− --
696− -- === __Example__
697− --
698− -- The following instances encode the constructor @Bar@ to lower-case keys
699− -- @\"bar\"@.
700− --
701− -- @
702− -- data Foo = Bar
703− -- deriving 'Generic'
704− --
705− -- opts :: 'JSONKeyOptions'
706− -- opts = 'defaultJSONKeyOptions' { 'keyModifier' = 'toLower' }
707− --
708− -- instance 'ToJSONKey' Foo where
709− -- 'toJSONKey' = 'genericToJSONKey' opts
710− --
711− -- instance 'FromJSONKey' Foo where
712− -- 'fromJSONKey' = 'genericFromJSONKey' opts
713− -- @
714− }
715−
716581-- | Default encoding 'Options':
717582--
718583-- @
@@ -723,8 +588,6 @@ data JSONKeyOptions = JSONKeyOptions
723588-- , 'omitNothingFields' = False
724589-- , 'sumEncoding' = 'defaultTaggedObject'
725590-- , 'unwrapUnaryRecords' = False
726−-- , 'tagSingleConstructors' = False
727−-- , 'rejectUnknownFields' = False
728591-- }
729592-- @
730593defaultOptions :: Options
@@ -735,8 +598,6 @@ defaultOptions = Options
735598 , omitNothingFields = False
736599 , sumEncoding = defaultTaggedObject
737600 , unwrapUnaryRecords = False
738− , tagSingleConstructors = False
739− , rejectUnknownFields = False
740601 }
741602
742603-- | Default 'TaggedObject' 'SumEncoding' options:
@@ -753,16 +614,6 @@ defaultTaggedObject = TaggedObject
753614 , contentsFieldName = "contents"
754615 }
755616
756−-- | Default 'JSONKeyOptions':
757−--
758−-- @
759−-- defaultJSONKeyOptions = 'JSONKeyOptions'
760−-- { 'keyModifier' = 'id'
761−-- }
762−-- @
763−defaultJSONKeyOptions :: JSONKeyOptions
764−defaultJSONKeyOptions = JSONKeyOptions id
765−
766617-- | Converts from CamelCase to another lower case, interspersing
767618-- the character between all capital letters and their previous
768619-- entries, except those capital letters that appear together,
Data/Aeson/Types/ToJSON.hs+534−626
@@ -1,21 +1,25 @@
1+{-# LANGUAGE BangPatterns #-}
12{-# LANGUAGE CPP #-}
3+{-# LANGUAGE DataKinds #-}
24{-# LANGUAGE DefaultSignatures #-}
3−{-# LANGUAGE EmptyDataDecls #-}
45{-# LANGUAGE FlexibleContexts #-}
56{-# LANGUAGE FlexibleInstances #-}
6−{-# LANGUAGE FunctionalDependencies #-}
77{-# LANGUAGE GADTs #-}
8−{-# LANGUAGE NoImplicitPrelude #-}
8+{-# LANGUAGE MultiParamTypeClasses #-}
9+{-# LANGUAGE NamedFieldPuns #-}
910{-# LANGUAGE OverloadedStrings #-}
1011{-# LANGUAGE PatternGuards #-}
11−{-# LANGUAGE PolyKinds #-}
1212{-# LANGUAGE RecordWildCards #-}
1313{-# LANGUAGE ScopedTypeVariables #-}
1414{-# LANGUAGE TypeOperators #-}
15+{-# LANGUAGE TypeSynonymInstances #-}
1516{-# LANGUAGE UndecidableInstances #-}
1617
18+#if __GLASGOW_HASKELL__ >= 706
19+{-# LANGUAGE PolyKinds #-}
20+#endif
21+
1722#include "overlapping-compat.h"
18−#include "incoherent-compat.h"
1923
2024-- TODO: Drop this when we remove support for Data.Attoparsec.Number
2125{-# OPTIONS_GHC -fno-warn-deprecations #-}
@@ -33,6 +37,7 @@ module Data.Aeson.Types.ToJSON
3337 , toEncoding2
3438 -- * Generic JSON classes
3539 , GToJSON(..)
40+ , GToEncoding(..)
3641 , ToArgs(..)
3742 , genericToJSON
3843 , genericToEncoding
@@ -43,63 +48,54 @@ module Data.Aeson.Types.ToJSON
4348 , ToJSONKeyFunction(..)
4449 , toJSONKeyText
4550 , contramapToJSONKeyFunction
46−
47− , GToJSONKey()
48− , genericToJSONKey
49−
5051 -- * Object key-value pairs
5152 , KeyValue(..)
52− , KeyValuePair(..)
53− , FromPairs(..)
5453 -- * Functions needed for documentation
5554 -- * Encoding functions
5655 , listEncoding
5756 , listValue
5857 ) where
5958
59+import Prelude ()
6060import Prelude.Compat
6161
6262import Control.Applicative (Const(..))
6363import Control.Monad.ST (ST)
6464import Data.Aeson.Encoding (Encoding, Encoding', Series, dict, emptyArray_)
65−import Data.Aeson.Encoding.Internal ((>*<))
65+import Data.Aeson.Encoding.Internal ((>*<), (><))
6666import Data.Aeson.Internal.Functions (mapHashKeyVal, mapKeyVal)
67−import Data.Aeson.Types.Generic (AllNullary, False, IsRecord, One, ProductSize, Tagged2(..), True, Zero, productSize)
67+import Data.Aeson.Types.Generic (AllNullary, False, IsRecord(..), One, ProductSize, Tagged2(..), True, Zero, productSize)
6868import Data.Aeson.Types.Internal
6969import Data.Attoparsec.Number (Number(..))
7070import Data.Bits (unsafeShiftR)
7171import Data.DList (DList)
72−import Data.Fixed (Fixed, HasResolution, Nano)
72+import Data.Fixed (Fixed, HasResolution)
7373import Data.Foldable (toList)
7474import Data.Functor.Compose (Compose(..))
75−import Data.Functor.Contravariant (Contravariant (..))
7675import Data.Functor.Identity (Identity(..))
7776import Data.Functor.Product (Product(..))
7877import Data.Functor.Sum (Sum(..))
7978import Data.Int (Int16, Int32, Int64, Int8)
8079import Data.List (intersperse)
8180import Data.List.NonEmpty (NonEmpty(..))
82−import Data.Semigroup ((<>))
81+import Data.Monoid ((<>))
8382import Data.Proxy (Proxy(..))
8483import Data.Ratio (Ratio, denominator, numerator)
8584import Data.Scientific (Scientific)
8685import Data.Tagged (Tagged(..))
8786import Data.Text (Text, pack)
88−import Data.Time (Day, DiffTime, LocalTime, NominalDiffTime, TimeOfDay, UTCTime, ZonedTime)
89−import Data.Time.Calendar.Compat (CalendarDiffDays (..), DayOfWeek (..))
90−import Data.Time.LocalTime.Compat (CalendarDiffTime (..))
91−import Data.Time.Clock.System.Compat (SystemTime (..))
92−import Data.Time.Format.Compat (FormatTime, formatTime, defaultTimeLocale)
87+import Data.Time (Day, LocalTime, NominalDiffTime, TimeOfDay, UTCTime, ZonedTime)
88+import Data.Time.Format (FormatTime, formatTime)
89+import Data.Time.Locale.Compat (defaultTimeLocale)
9390import Data.Vector (Vector)
9491import Data.Version (Version, showVersion)
95−import Data.Void (Void, absurd)
9692import Data.Word (Word16, Word32, Word64, Word8)
9793import Foreign.Storable (Storable)
98−import Foreign.C.Types (CTime (..))
9994import GHC.Generics
10095import Numeric.Natural (Natural)
10196import qualified Data.Aeson.Encoding as E
102−import qualified Data.Aeson.Encoding.Internal as E (InArray, comma, econcat, retagEncoding)
97+import qualified Data.Aeson.Encoding.Internal as E (InArray, colon, comma, econcat, empty, retagEncoding, wrapObject)
98+import qualified Data.ByteString as S
10399import qualified Data.ByteString.Lazy as L
104100import qualified Data.DList as DList
105101import qualified Data.HashMap.Strict as H
@@ -117,7 +113,6 @@ import qualified Data.Text as T
117113import qualified Data.Text.Encoding as T
118114import qualified Data.Text.Lazy as LT
119115import qualified Data.Tree as Tree
120−import qualified Data.UUID.Types as UUID
121116import qualified Data.Vector as V
122117import qualified Data.Vector.Generic as VG
123118import qualified Data.Vector.Mutable as VM
@@ -125,19 +120,12 @@ import qualified Data.Vector.Primitive as VP
125120import qualified Data.Vector.Storable as VS
126121import qualified Data.Vector.Unboxed as VU
127122
128−import qualified Data.Aeson.Encoding.Builder as EB
129−import qualified Data.ByteString.Builder as B
130−
131−import qualified GHC.Exts as Exts
132−import qualified Data.Primitive.Array as PM
133−import qualified Data.Primitive.SmallArray as PM
134−import qualified Data.Primitive.Types as PM
135−
136−#if MIN_VERSION_primitive(0,6,4)
137−#if !MIN_VERSION_primitive(0,7,0)
138−import qualified Data.Primitive.UnliftedArray as PM
139−#endif
140−import qualified Data.Primitive.PrimArray as PM
123+#if !(MIN_VERSION_bytestring(0,10,0))
124+import Foreign.ForeignPtr (withForeignPtr)
125+import Foreign.Marshal.Utils (copyBytes)
126+import Foreign.Ptr (plusPtr)
127+import qualified Data.ByteString.Internal as S
128+import qualified Data.ByteString.Lazy.Internal as L
141129#endif
142130
143131toJSONPair :: (a -> Value) -> (b -> Value) -> (a, b) -> Value
@@ -156,16 +144,19 @@ realFloatToJSON d
156144
157145-- | Class of generic representation types that can be converted to
158146-- JSON.
159−class GToJSON enc arity f where
147+class GToJSON arity f where
160148 -- | This method (applied to 'defaultOptions') is used as the
161− -- default generic implementation of 'toJSON'
162− -- (with @enc ~ 'Value'@ and @arity ~ 'Zero'@)
163− -- and 'liftToJSON' (if the @arity@ is 'One').
164− --
165− -- It also provides a generic implementation of 'toEncoding'
166− -- (with @enc ~ 'Encoding'@ and @arity ~ 'Zero'@)
167− -- and 'liftToEncoding' (if the @arity@ is 'One').
168− gToJSON :: Options -> ToArgs enc arity a -> f a -> enc
149+ -- default generic implementation of 'toJSON' (if the @arity@ is 'Zero')
150+ -- or 'liftToJSON' (if the @arity@ is 'One').
151+ gToJSON :: Options -> ToArgs Value arity a -> f a -> Value
152+
153+-- | Class of generic representation types that can be converted to
154+-- a JSON 'Encoding'.
155+class GToEncoding arity f where
156+ -- | This method (applied to 'defaultOptions') can be used as the
157+ -- default generic implementation of 'toEncoding' (if the @arity@ is 'Zero')
158+ -- or 'liftToEncoding' (if the @arity@ is 'One').
159+ gToEncoding :: Options -> ToArgs Encoding arity a -> f a -> Encoding
169160
170161-- | A 'ToArgs' value either stores nothing (for 'ToJSON') or it stores the two
171162-- function arguments that encode occurrences of the type parameter (for
@@ -177,14 +168,14 @@ data ToArgs res arity a where
177168-- | A configurable generic JSON creator. This function applied to
178169-- 'defaultOptions' is used as the default for 'toJSON' when the type
179170-- is an instance of 'Generic'.
180−genericToJSON :: (Generic a, GToJSON Value Zero (Rep a))
171+genericToJSON :: (Generic a, GToJSON Zero (Rep a))
181172 => Options -> a -> Value
182173genericToJSON opts = gToJSON opts NoToArgs . from
183174
184175-- | A configurable generic JSON creator. This function applied to
185176-- 'defaultOptions' is used as the default for 'liftToJSON' when the type
186177-- is an instance of 'Generic1'.
187−genericLiftToJSON :: (Generic1 f, GToJSON Value One (Rep1 f))
178+genericLiftToJSON :: (Generic1 f, GToJSON One (Rep1 f))
188179 => Options -> (a -> Value) -> ([a] -> Value)
189180 -> f a -> Value
190181genericLiftToJSON opts tj tjl = gToJSON opts (To1Args tj tjl) . from1
@@ -192,17 +183,17 @@ genericLiftToJSON opts tj tjl = gToJSON opts (To1Args tj tjl) . from1
192183-- | A configurable generic JSON encoder. This function applied to
193184-- 'defaultOptions' is used as the default for 'toEncoding' when the type
194185-- is an instance of 'Generic'.
195−genericToEncoding :: (Generic a, GToJSON Encoding Zero (Rep a))
186+genericToEncoding :: (Generic a, GToEncoding Zero (Rep a))
196187 => Options -> a -> Encoding
197−genericToEncoding opts = gToJSON opts NoToArgs . from
188+genericToEncoding opts = gToEncoding opts NoToArgs . from
198189
199190-- | A configurable generic JSON encoder. This function applied to
200191-- 'defaultOptions' is used as the default for 'liftToEncoding' when the type
201192-- is an instance of 'Generic1'.
202−genericLiftToEncoding :: (Generic1 f, GToJSON Encoding One (Rep1 f))
193+genericLiftToEncoding :: (Generic1 f, GToEncoding One (Rep1 f))
203194 => Options -> (a -> Encoding) -> ([a] -> Encoding)
204195 -> f a -> Encoding
205−genericLiftToEncoding opts te tel = gToJSON opts (To1Args te tel) . from1
196+genericLiftToEncoding opts te tel = gToEncoding opts (To1Args te tel) . from1
206197
207198-------------------------------------------------------------------------------
208199-- Class
@@ -210,9 +201,6 @@ genericLiftToEncoding opts te tel = gToJSON opts (To1Args te tel) . from1
210201
211202-- | A type that can be converted to JSON.
212203--
213−-- Instances in general /must/ specify 'toJSON' and /should/ (but don't need
214−-- to) specify 'toEncoding'.
215−--
216204-- An example type and instance:
217205--
218206-- @
@@ -221,10 +209,10 @@ genericLiftToEncoding opts te tel = gToJSON opts (To1Args te tel) . from1
221209--
222210-- data Coord = Coord { x :: Double, y :: Double }
223211--
224−-- instance 'ToJSON' Coord where
225−-- 'toJSON' (Coord x y) = 'object' [\"x\" '.=' x, \"y\" '.=' y]
212+-- instance ToJSON Coord where
213+-- toJSON (Coord x y) = 'object' [\"x\" '.=' x, \"y\" '.=' y]
226214--
227−-- 'toEncoding' (Coord x y) = 'pairs' (\"x\" '.=' x '<>' \"y\" '.=' y)
215+-- toEncoding (Coord x y) = 'pairs' (\"x\" '.=' x '<>' \"y\" '.=' y)
228216-- @
229217--
230218-- Instead of manually writing your 'ToJSON' instance, there are two options
@@ -232,15 +220,17 @@ genericLiftToEncoding opts te tel = gToJSON opts (To1Args te tel) . from1
232220--
233221-- * "Data.Aeson.TH" provides Template Haskell functions which will derive an
234222-- instance at compile time. The generated instance is optimized for your type
235−-- so it will probably be more efficient than the following option.
223+-- so will probably be more efficient than the following two options:
236224--
237225-- * The compiler can provide a default generic implementation for
238226-- 'toJSON'.
239227--
240228-- To use the second, simply add a @deriving 'Generic'@ clause to your
241−-- datatype and declare a 'ToJSON' instance. If you require nothing other than
242−-- 'defaultOptions', it is sufficient to write (and this is the only
243−-- alternative where the default 'toJSON' implementation is sufficient):
229+-- datatype and declare a 'ToJSON' instance for your datatype without giving
230+-- definitions for 'toJSON' or 'toEncoding'.
231+--
232+-- For example, the previous example can be simplified to a more
233+-- minimal instance:
244234--
245235-- @
246236-- {-\# LANGUAGE DeriveGeneric \#-}
@@ -249,46 +239,35 @@ genericLiftToEncoding opts te tel = gToJSON opts (To1Args te tel) . from1
249239--
250240-- data Coord = Coord { x :: Double, y :: Double } deriving 'Generic'
251241--
252−-- instance 'ToJSON' Coord where
253−-- 'toEncoding' = 'genericToEncoding' 'defaultOptions'
242+-- instance ToJSON Coord where
243+-- toEncoding = 'genericToEncoding' 'defaultOptions'
254244-- @
255245--
256−-- If on the other hand you wish to customize the generic decoding, you have
257−-- to implement both methods:
246+-- Why do we provide an implementation for 'toEncoding' here? The
247+-- 'toEncoding' function is a relatively new addition to this class.
248+-- To allow users of older versions of this library to upgrade without
249+-- having to edit all of their instances or encounter surprising
250+-- incompatibilities, the default implementation of 'toEncoding' uses
251+-- 'toJSON'. This produces correct results, but since it performs an
252+-- intermediate conversion to a 'Value', it will be less efficient
253+-- than directly emitting an 'Encoding'. Our one-liner definition of
254+-- 'toEncoding' above bypasses the intermediate 'Value'.
255+--
256+-- If @DefaultSignatures@ doesn't give exactly the results you want,
257+-- you can customize the generic encoding with only a tiny amount of
258+-- effort, using 'genericToJSON' and 'genericToEncoding' with your
259+-- preferred 'Options':
258260--
259261-- @
260−-- customOptions = 'defaultOptions'
261−-- { 'fieldLabelModifier' = 'map' 'Data.Char.toUpper'
262−-- }
263−--
264−-- instance 'ToJSON' Coord where
265−-- 'toJSON' = 'genericToJSON' customOptions
266−-- 'toEncoding' = 'genericToEncoding' customOptions
262+-- instance ToJSON Coord where
263+-- toJSON = 'genericToJSON' 'defaultOptions'
264+-- toEncoding = 'genericToEncoding' 'defaultOptions'
267265-- @
268−--
269−-- Previous versions of this library only had the 'toJSON' method. Adding
270−-- 'toEncoding' had two reasons:
271−--
272−-- 1. toEncoding is more efficient for the common case that the output of
273−-- 'toJSON' is directly serialized to a @ByteString@.
274−-- Further, expressing either method in terms of the other would be
275−-- non-optimal.
276−--
277−-- 2. The choice of defaults allows a smooth transition for existing users:
278−-- Existing instances that do not define 'toEncoding' still
279−-- compile and have the correct semantics. This is ensured by making
280−-- the default implementation of 'toEncoding' use 'toJSON'. This produces
281−-- correct results, but since it performs an intermediate conversion to a
282−-- 'Value', it will be less efficient than directly emitting an 'Encoding'.
283−-- (this also means that specifying nothing more than
284−-- @instance ToJSON Coord@ would be sufficient as a generically decoding
285−-- instance, but there probably exists no good reason to not specify
286−-- 'toEncoding' in new instances.)
287266class ToJSON a where
288267 -- | Convert a Haskell value to a JSON-friendly intermediate type.
289268 toJSON :: a -> Value
290269
291− default toJSON :: (Generic a, GToJSON Value Zero (Rep a)) => a -> Value
270+ default toJSON :: (Generic a, GToJSON Zero (Rep a)) => a -> Value
292271 toJSON = genericToJSON defaultOptions
293272
294273 -- | Encode a Haskell value as JSON.
@@ -305,8 +284,8 @@ class ToJSON a where
305284 -- extension, and then have GHC generate a method body as follows.
306285 --
307286 -- @
308− -- instance 'ToJSON' Coord where
309− -- 'toEncoding' = 'genericToEncoding' 'defaultOptions'
287+ -- instance ToJSON Coord where
288+ -- toEncoding = 'genericToEncoding' 'defaultOptions'
310289 -- @
311290
312291 toEncoding :: a -> Encoding
@@ -338,13 +317,6 @@ instance KeyValue Pair where
338317 name .= value = (name, toJSON value)
339318 {-# INLINE (.=) #-}
340319
341−-- | Constructs a singleton 'H.HashMap'. For calling functions that
342−-- demand an 'Object' for constructing objects. To be used in
343−-- conjunction with 'mconcat'. Prefer to use 'object' where possible.
344−instance KeyValue Object where
345− name .= value = H.singleton name (toJSON value)
346− {-# INLINE (.=) #-}
347−
348320-------------------------------------------------------------------------------
349321-- Classes and types for map keys
350322-------------------------------------------------------------------------------
@@ -402,7 +374,7 @@ instance KeyValue Object where
402374-- newtype wrapper around 'Text'. The recommended approach is to use
403375-- generalized newtype deriving:
404376--
405−-- > newtype RecordId = RecordId { getRecordId :: Text }
377+-- > newtype RecordId = RecordId { getRecordId :: Text}
406378-- > deriving (Eq,Ord,ToJSONKey)
407379--
408380-- Then we may write:
@@ -417,18 +389,8 @@ instance KeyValue Object where
417389--
418390-- It is possible to get the 'ToJSONKey' instance for free as we did
419391-- with 'Foo'. However, in this case, we have a natural way to go to
420−-- and from 'Text' that does not require any escape sequences. So
421−-- 'ToJSONKeyText' can be used instead of 'ToJSONKeyValue' to encode maps
422−-- as objects instead of arrays of pairs. This instance may be
423−-- implemented using generics as follows:
424−--
425−-- @
426−-- instance 'ToJSONKey' Color where
427−-- 'toJSONKey' = 'genericToJSONKey' 'defaultJSONKeyOptions'
428−-- @
429−--
430−-- === __Low-level implementations__
431−--
392+-- and from 'Text' that does not require any escape sequences. So, in
393+-- this example, 'ToJSONKeyText' will be used instead of 'ToJSONKeyValue'.
432394-- The 'Show' instance can be used to help write 'ToJSONKey':
433395--
434396-- > instance ToJSONKey Color where
@@ -503,42 +465,16 @@ toJSONKeyTextEnc e = ToJSONKeyText tot e
503465 -- TODO: dropAround is also used in stringEncoding, which is unfortunate atm
504466 tot = T.dropAround (== '"')
505467 . T.decodeLatin1
506− . L.toStrict
468+ . lazyToStrictByteString
507469 . E.encodingToLazyByteString
508470 . e
509471
510−instance Contravariant ToJSONKeyFunction where
511− contramap = contramapToJSONKeyFunction
512−
513472-- | Contravariant map, as 'ToJSONKeyFunction' is a contravariant functor.
514473contramapToJSONKeyFunction :: (b -> a) -> ToJSONKeyFunction a -> ToJSONKeyFunction b
515474contramapToJSONKeyFunction h x = case x of
516475 ToJSONKeyText f g -> ToJSONKeyText (f . h) (g . h)
517476 ToJSONKeyValue f g -> ToJSONKeyValue (f . h) (g . h)
518477
519−-- 'toJSONKey' for 'Generic' types.
520−-- Deriving is supported for enumeration types, i.e. the sums of nullary
521−-- constructors. The names of constructors will be used as keys for JSON
522−-- objects.
523−--
524−-- See also 'genericFromJSONKey'.
525−--
526−-- === __Example__
527−--
528−-- @
529−-- data Color = Red | Green | Blue
530−-- deriving 'Generic'
531−--
532−-- instance 'ToJSONKey' Color where
533−-- 'toJSONKey' = 'genericToJSONKey' 'defaultJSONKeyOptions'
534−-- @
535−genericToJSONKey :: (Generic a, GToJSONKey (Rep a))
536− => JSONKeyOptions -> ToJSONKeyFunction a
537−genericToJSONKey opts = toJSONKeyText (pack . keyModifier opts . getConName . from)
538−
539−class GetConName f => GToJSONKey f
540−instance GetConName f => GToJSONKey f
541−
542478-------------------------------------------------------------------------------
543479-- Lifings of FromJSON and ToJSON to unary and binary type constructors
544480-------------------------------------------------------------------------------
@@ -551,7 +487,7 @@ instance GetConName f => GToJSONKey f
551487--
552488-- * "Data.Aeson.TH" provides Template Haskell functions which will derive an
553489-- instance at compile time. The generated instance is optimized for your type
554−-- so it will probably be more efficient than the following option.
490+-- so will probably be more efficient than the following two options:
555491--
556492-- * The compiler can provide a default generic implementation for
557493-- 'toJSON1'.
@@ -569,29 +505,23 @@ instance GetConName f => GToJSONKey f
569505--
570506-- data Pair = Pair { pairFst :: a, pairSnd :: b } deriving 'Generic1'
571507--
572−-- instance 'ToJSON' a => 'ToJSON1' (Pair a)
508+-- instance ToJSON a => ToJSON1 (Pair a)
573509-- @
574510--
575−-- If the default implementation doesn't give exactly the results you want,
511+-- If @DefaultSignatures@ doesn't give exactly the results you want,
576512-- you can customize the generic encoding with only a tiny amount of
577513-- effort, using 'genericLiftToJSON' and 'genericLiftToEncoding' with
578514-- your preferred 'Options':
579515--
580516-- @
581−-- customOptions = 'defaultOptions'
582−-- { 'fieldLabelModifier' = 'map' 'Data.Char.toUpper'
583−-- }
584−--
585−-- instance 'ToJSON' a => 'ToJSON1' (Pair a) where
586−-- 'liftToJSON' = 'genericLiftToJSON' customOptions
587−-- 'liftToEncoding' = 'genericLiftToEncoding' customOptions
517+-- instance ToJSON a => ToJSON1 (Pair a) where
518+-- liftToJSON = 'genericLiftToJSON' 'defaultOptions'
519+-- liftToEncoding = 'genericLiftToEncoding' 'defaultOptions'
588520-- @
589−--
590−-- See also 'ToJSON'.
591521class ToJSON1 f where
592522 liftToJSON :: (a -> Value) -> ([a] -> Value) -> f a -> Value
593523
594− default liftToJSON :: (Generic1 f, GToJSON Value One (Rep1 f))
524+ default liftToJSON :: (Generic1 f, GToJSON One (Rep1 f))
595525 => (a -> Value) -> ([a] -> Value) -> f a -> Value
596526 liftToJSON = genericLiftToJSON defaultOptions
597527
@@ -600,7 +530,7 @@ class ToJSON1 f where
600530
601531 liftToEncoding :: (a -> Encoding) -> ([a] -> Encoding) -> f a -> Encoding
602532
603− default liftToEncoding :: (Generic1 f, GToJSON Encoding One (Rep1 f))
533+ default liftToEncoding :: (Generic1 f, GToEncoding One (Rep1 f))
604534 => (a -> Encoding) -> ([a] -> Encoding)
605535 -> f a -> Encoding
606536 liftToEncoding = genericLiftToEncoding defaultOptions
@@ -654,7 +584,7 @@ toEncoding2 = liftToEncoding2 toEncoding toEncodingList toEncoding toEncodingLis
654584-- @
655585-- newtype F a = F [a]
656586--
657−-- -- This instance encodes 'String' as an array of chars
587+-- -- This instance encodes String as an array of chars
658588-- instance 'ToJSON1' F where
659589-- 'liftToJSON' tj _ (F xs) = 'liftToJSON' tj ('listValue' tj) xs
660590-- 'liftToEncoding' te _ (F xs) = 'liftToEncoding' te ('listEncoding' te) xs
@@ -685,11 +615,6 @@ instance ToJSON1 [] where
685615 {-# INLINE liftToEncoding #-}
686616
687617instance (ToJSON a) => ToJSON [a] where
688− {-# SPECIALIZE instance ToJSON String #-}
689− {-# SPECIALIZE instance ToJSON [String] #-}
690− {-# SPECIALIZE instance ToJSON [Array] #-}
691− {-# SPECIALIZE instance ToJSON [Object] #-}
692−
693618 toJSON = toJSON1
694619 {-# INLINE toJSON #-}
695620
@@ -700,80 +625,39 @@ instance (ToJSON a) => ToJSON [a] where
700625-- Generic toJSON / toEncoding
701626-------------------------------------------------------------------------------
702627
703−instance OVERLAPPABLE_ (GToJSON enc arity a) => GToJSON enc arity (M1 i c a) where
704− -- Meta-information, which is not handled elsewhere, is ignored:
705− gToJSON opts targs = gToJSON opts targs . unM1
706− {-# INLINE gToJSON #-}
707−
708−instance GToJSON enc One Par1 where
709− -- Direct occurrences of the last type parameter are encoded with the
710− -- function passed in as an argument:
711− gToJSON _opts (To1Args tj _) = tj . unPar1
712− {-# INLINE gToJSON #-}
713−
714−instance ( ConsToJSON enc arity a
715− , AllNullary (C1 c a) allNullary
716− , SumToJSON enc arity (C1 c a) allNullary
717− ) => GToJSON enc arity (D1 d (C1 c a)) where
718− -- The option 'tagSingleConstructors' determines whether to wrap
719− -- a single-constructor type.
720− gToJSON opts targs
721− | tagSingleConstructors opts = (unTagged :: Tagged allNullary enc -> enc)
722− . sumToJSON opts targs
723− . unM1
724− | otherwise = consToJSON opts targs . unM1 . unM1
725− {-# INLINE gToJSON #-}
726−
727−instance (ConsToJSON enc arity a) => GToJSON enc arity (C1 c a) where
728− -- Constructors need to be encoded differently depending on whether they're
729− -- a record or not. This distinction is made by 'consToJSON':
730− gToJSON opts targs = consToJSON opts targs . unM1
731− {-# INLINE gToJSON #-}
732−
733−instance ( AllNullary (a :+: b) allNullary
734− , SumToJSON enc arity (a :+: b) allNullary
735− ) => GToJSON enc arity (a :+: b)
736− where
737− -- If all constructors of a sum datatype are nullary and the
738− -- 'allNullaryToStringTag' option is set they are encoded to
739− -- strings. This distinction is made by 'sumToJSON':
740− gToJSON opts targs = (unTagged :: Tagged allNullary enc -> enc)
741− . sumToJSON opts targs
742− {-# INLINE gToJSON #-}
743−
744628--------------------------------------------------------------------------------
745629-- Generic toJSON
746630
747−-- Note: Refactoring 'ToJSON a' to 'ToJSON enc a' (and 'ToJSON1' similarly) is
748−-- possible but makes error messages a bit harder to understand for missing
749−-- instances.
750−
751−instance GToJSON Value arity V1 where
752− -- Empty values do not exist, which makes the job of formatting them
753− -- rather easy:
754− gToJSON _ _ x = x `seq` error "case: V1"
755− {-# INLINE gToJSON #-}
631+instance OVERLAPPABLE_ (GToJSON arity a) => GToJSON arity (M1 i c a) where
632+ -- Meta-information, which is not handled elsewhere, is ignored:
633+ gToJSON opts targs = gToJSON opts targs . unM1
756634
757−instance ToJSON a => GToJSON Value arity (K1 i a) where
635+instance (ToJSON a) => GToJSON arity (K1 i a) where
758636 -- Constant values are encoded using their ToJSON instance:
759637 gToJSON _opts _ = toJSON . unK1
760− {-# INLINE gToJSON #-}
761638
762−instance ToJSON1 f => GToJSON Value One (Rec1 f) where
639+instance GToJSON One Par1 where
640+ -- Direct occurrences of the last type parameter are encoded with the
641+ -- function passed in as an argument:
642+ gToJSON _opts (To1Args tj _) = tj . unPar1
643+
644+instance (ToJSON1 f) => GToJSON One (Rec1 f) where
763645 -- Recursive occurrences of the last type parameter are encoded using their
764646 -- ToJSON1 instance:
765647 gToJSON _opts (To1Args tj tjl) = liftToJSON tj tjl . unRec1
766− {-# INLINE gToJSON #-}
767648
768−instance GToJSON Value arity U1 where
649+instance GToJSON arity U1 where
769650 -- Empty constructors are encoded to an empty array:
770651 gToJSON _opts _ _ = emptyArray
771− {-# INLINE gToJSON #-}
652+
653+instance (ConsToJSON arity a) => GToJSON arity (C1 c a) where
654+ -- Constructors need to be encoded differently depending on whether they're
655+ -- a record or not. This distinction is made by 'consToJSON':
656+ gToJSON opts targs = consToJSON opts targs . unM1
772657
773658instance ( WriteProduct arity a, WriteProduct arity b
774659 , ProductSize a, ProductSize b
775− ) => GToJSON Value arity (a :*: b)
776− where
660+ ) => GToJSON arity (a :*: b) where
777661 -- Products are encoded to an array. Here we allocate a mutable vector of
778662 -- the same size as the product and write the product's elements to it using
779663 -- 'writeProduct':
@@ -785,175 +669,237 @@ instance ( WriteProduct arity a, WriteProduct arity b
785669 where
786670 lenProduct = (unTagged2 :: Tagged2 (a :*: b) Int -> Int)
787671 productSize
788− {-# INLINE gToJSON #-}
789672
790−instance ( ToJSON1 f
791− , GToJSON Value One g
792− ) => GToJSON Value One (f :.: g)
793− where
673+instance ( AllNullary (a :+: b) allNullary
674+ , SumToJSON arity (a :+: b) allNullary
675+ ) => GToJSON arity (a :+: b) where
676+ -- If all constructors of a sum datatype are nullary and the
677+ -- 'allNullaryToStringTag' option is set they are encoded to
678+ -- strings. This distinction is made by 'sumToJSON':
679+ gToJSON opts targs = (unTagged :: Tagged allNullary Value -> Value)
680+ . sumToJSON opts targs
681+
682+instance (ToJSON1 f, GToJSON One g) => GToJSON One (f :.: g) where
794683 -- If an occurrence of the last type parameter is nested inside two
795684 -- composed types, it is encoded by using the outermost type's ToJSON1
796685 -- instance to generically encode the innermost type:
797686 gToJSON opts targs =
798687 let gtj = gToJSON opts targs in
799688 liftToJSON gtj (listValue gtj) . unComp1
800− {-# INLINE gToJSON #-}
801689
802690--------------------------------------------------------------------------------
803691-- Generic toEncoding
804692
805−instance ToJSON a => GToJSON Encoding arity (K1 i a) where
693+instance OVERLAPPABLE_ (GToEncoding arity a) => GToEncoding arity (M1 i c a) where
694+ -- Meta-information, which is not handled elsewhere, is ignored:
695+ gToEncoding opts targs = gToEncoding opts targs . unM1
696+
697+instance (ToJSON a) => GToEncoding arity (K1 i a) where
806698 -- Constant values are encoded using their ToJSON instance:
807− gToJSON _opts _ = toEncoding . unK1
808− {-# INLINE gToJSON #-}
699+ gToEncoding _opts _ = toEncoding . unK1
809700
810−instance ToJSON1 f => GToJSON Encoding One (Rec1 f) where
701+instance GToEncoding One Par1 where
702+ -- Direct occurrences of the last type parameter are encoded with the
703+ -- function passed in as an argument:
704+ gToEncoding _opts (To1Args te _) = te . unPar1
705+
706+instance (ToJSON1 f) => GToEncoding One (Rec1 f) where
811707 -- Recursive occurrences of the last type parameter are encoded using their
812708 -- ToEncoding1 instance:
813− gToJSON _opts (To1Args te tel) = liftToEncoding te tel . unRec1
814− {-# INLINE gToJSON #-}
709+ gToEncoding _opts (To1Args te tel) = liftToEncoding te tel . unRec1
815710
816−instance GToJSON Encoding arity U1 where
711+instance GToEncoding arity U1 where
817712 -- Empty constructors are encoded to an empty array:
818− gToJSON _opts _ _ = E.emptyArray_
819− {-# INLINE gToJSON #-}
713+ gToEncoding _opts _ _ = E.emptyArray_
714+
715+instance (ConsToEncoding arity a) => GToEncoding arity (C1 c a) where
716+ -- Constructors need to be encoded differently depending on whether they're
717+ -- a record or not. This distinction is made by 'consToEncoding':
718+ gToEncoding opts targs = consToEncoding opts targs . unM1
820719
821720instance ( EncodeProduct arity a
822721 , EncodeProduct arity b
823− ) => GToJSON Encoding arity (a :*: b)
824− where
722+ ) => GToEncoding arity (a :*: b) where
825723 -- Products are encoded to an array. Here we allocate a mutable vector of
826724 -- the same size as the product and write the product's elements to it using
827725 -- 'encodeProduct':
828− gToJSON opts targs p = E.list E.retagEncoding [encodeProduct opts targs p]
829− {-# INLINE gToJSON #-}
726+ gToEncoding opts targs p = E.list E.retagEncoding [encodeProduct opts targs p]
830727
831−instance ( ToJSON1 f
832− , GToJSON Encoding One g
833− ) => GToJSON Encoding One (f :.: g)
834− where
728+instance ( AllNullary (a :+: b) allNullary
729+ , SumToEncoding arity (a :+: b) allNullary
730+ ) => GToEncoding arity (a :+: b) where
731+ -- If all constructors of a sum datatype are nullary and the
732+ -- 'allNullaryToStringTag' option is set they are encoded to
733+ -- strings. This distinction is made by 'sumToEncoding':
734+ gToEncoding opts targs
735+ = (unTagged :: Tagged allNullary Encoding -> Encoding)
736+ . sumToEncoding opts targs
737+
738+instance (ToJSON1 f, GToEncoding One g) => GToEncoding One (f :.: g) where
835739 -- If an occurrence of the last type parameter is nested inside two
836740 -- composed types, it is encoded by using the outermost type's ToJSON1
837741 -- instance to generically encode the innermost type:
838− gToJSON opts targs =
839− let gte = gToJSON opts targs in
742+ gToEncoding opts targs =
743+ let gte = gToEncoding opts targs in
840744 liftToEncoding gte (listEncoding gte) . unComp1
841− {-# INLINE gToJSON #-}
842745
843746--------------------------------------------------------------------------------
844747
845−class SumToJSON enc arity f allNullary where
846− sumToJSON :: Options -> ToArgs enc arity a
847− -> f a -> Tagged allNullary enc
848−
849−instance ( GetConName f
850− , FromString enc
851− , TaggedObject enc arity f
852− , SumToJSON' ObjectWithSingleField enc arity f
853− , SumToJSON' TwoElemArray enc arity f
854− , SumToJSON' UntaggedValue enc arity f
855− ) => SumToJSON enc arity f True
856− where
748+class SumToJSON arity f allNullary where
749+ sumToJSON :: Options -> ToArgs Value arity a
750+ -> f a -> Tagged allNullary Value
751+
752+instance ( GetConName f
753+ , TaggedObjectPairs arity f
754+ , ObjectWithSingleFieldObj arity f
755+ , TwoElemArrayObj arity f
756+ , UntaggedValueObj arity f
757+ ) => SumToJSON arity f True where
857758 sumToJSON opts targs
858− | allNullaryToStringTag opts = Tagged . fromString
759+ | allNullaryToStringTag opts = Tagged . String . pack
859760 . constructorTagModifier opts . getConName
860761 | otherwise = Tagged . nonAllNullarySumToJSON opts targs
861762
862−instance ( TaggedObject enc arity f
863− , SumToJSON' ObjectWithSingleField enc arity f
864− , SumToJSON' TwoElemArray enc arity f
865− , SumToJSON' UntaggedValue enc arity f
866− ) => SumToJSON enc arity f False
867− where
763+instance ( TwoElemArrayObj arity f
764+ , TaggedObjectPairs arity f
765+ , ObjectWithSingleFieldObj arity f
766+ , UntaggedValueObj arity f
767+ ) => SumToJSON arity f False where
868768 sumToJSON opts targs = Tagged . nonAllNullarySumToJSON opts targs
869769
870−nonAllNullarySumToJSON :: ( TaggedObject enc arity f
871− , SumToJSON' ObjectWithSingleField enc arity f
872− , SumToJSON' TwoElemArray enc arity f
873− , SumToJSON' UntaggedValue enc arity f
874− ) => Options -> ToArgs enc arity a
875− -> f a -> enc
770+nonAllNullarySumToJSON :: ( TwoElemArrayObj arity f
771+ , TaggedObjectPairs arity f
772+ , ObjectWithSingleFieldObj arity f
773+ , UntaggedValueObj arity f
774+ ) => Options -> ToArgs Value arity a
775+ -> f a -> Value
876776nonAllNullarySumToJSON opts targs =
877777 case sumEncoding opts of
878−
879778 TaggedObject{..} ->
880− taggedObject opts targs tagFieldName contentsFieldName
881−
882− ObjectWithSingleField ->
883− (unTagged :: Tagged ObjectWithSingleField enc -> enc)
884− . sumToJSON' opts targs
779+ object . taggedObjectPairs opts targs tagFieldName contentsFieldName
780+ ObjectWithSingleField -> Object . objectWithSingleFieldObj opts targs
781+ TwoElemArray -> Array . twoElemArrayObj opts targs
782+ UntaggedValue -> untaggedValueObj opts targs
885783
886− TwoElemArray ->
887− (unTagged :: Tagged TwoElemArray enc -> enc)
888− . sumToJSON' opts targs
784+--------------------------------------------------------------------------------
889785
890− UntaggedValue ->
891− (unTagged :: Tagged UntaggedValue enc -> enc)
892− . sumToJSON' opts targs
786+class SumToEncoding arity f allNullary where
787+ sumToEncoding :: Options -> ToArgs Encoding arity a
788+ -> f a -> Tagged allNullary Encoding
789+
790+instance ( GetConName f
791+ , TaggedObjectEnc arity f
792+ , ObjectWithSingleFieldEnc arity f
793+ , TwoElemArrayEnc arity f
794+ , UntaggedValueEnc arity f
795+ ) => SumToEncoding arity f True where
796+ sumToEncoding opts targs
797+ | allNullaryToStringTag opts = Tagged . toEncoding .
798+ constructorTagModifier opts . getConName
799+ | otherwise = Tagged . nonAllNullarySumToEncoding opts targs
800+
801+instance ( TwoElemArrayEnc arity f
802+ , TaggedObjectEnc arity f
803+ , ObjectWithSingleFieldEnc arity f
804+ , UntaggedValueEnc arity f
805+ ) => SumToEncoding arity f False where
806+ sumToEncoding opts targs = Tagged . nonAllNullarySumToEncoding opts targs
807+
808+nonAllNullarySumToEncoding :: ( TwoElemArrayEnc arity f
809+ , TaggedObjectEnc arity f
810+ , ObjectWithSingleFieldEnc arity f
811+ , UntaggedValueEnc arity f
812+ ) => Options -> ToArgs Encoding arity a
813+ -> f a -> Encoding
814+nonAllNullarySumToEncoding opts targs =
815+ case sumEncoding opts of
816+ TaggedObject{..} ->
817+ taggedObjectEnc opts targs tagFieldName contentsFieldName
818+ ObjectWithSingleField -> objectWithSingleFieldEnc opts targs
819+ TwoElemArray -> twoElemArrayEnc opts targs
820+ UntaggedValue -> untaggedValueEnc opts targs
893821
894822--------------------------------------------------------------------------------
895823
896−class FromString enc where
897− fromString :: String -> enc
824+class TaggedObjectPairs arity f where
825+ taggedObjectPairs :: Options -> ToArgs Value arity a
826+ -> String -> String
827+ -> f a -> [Pair]
828+
829+instance ( TaggedObjectPairs arity a
830+ , TaggedObjectPairs arity b
831+ ) => TaggedObjectPairs arity (a :+: b) where
832+ taggedObjectPairs opts targs tagFieldName contentsFieldName (L1 x) =
833+ taggedObjectPairs opts targs tagFieldName contentsFieldName x
834+ taggedObjectPairs opts targs tagFieldName contentsFieldName (R1 x) =
835+ taggedObjectPairs opts targs tagFieldName contentsFieldName x
836+
837+instance ( IsRecord a isRecord
838+ , TaggedObjectPairs' arity a isRecord
839+ , Constructor c
840+ ) => TaggedObjectPairs arity (C1 c a) where
841+ taggedObjectPairs opts targs tagFieldName contentsFieldName =
842+ (pack tagFieldName .= constructorTagModifier opts
843+ (conName (undefined :: t c a p)) :) .
844+ (unTagged :: Tagged isRecord [Pair] -> [Pair]) .
845+ taggedObjectPairs' opts targs contentsFieldName . unM1
898846
899−instance FromString Encoding where
900− fromString = toEncoding
847+class TaggedObjectPairs' arity f isRecord where
848+ taggedObjectPairs' :: Options -> ToArgs Value arity a
849+ -> String -> f a -> Tagged isRecord [Pair]
901850
902−instance FromString Value where
903− fromString = String . pack
851+instance OVERLAPPING_ TaggedObjectPairs' arity U1 False where
852+ taggedObjectPairs' _ _ _ _ = Tagged []
904853
905−--------------------------------------------------------------------------------
854+instance (RecordToPairs arity f) => TaggedObjectPairs' arity f True where
855+ taggedObjectPairs' opts targs _ =
856+ Tagged . toList . recordToPairs opts targs
906857
907−class TaggedObject enc arity f where
908− taggedObject :: Options -> ToArgs enc arity a
909− -> String -> String
910− -> f a -> enc
858+instance (GToJSON arity f) => TaggedObjectPairs' arity f False where
859+ taggedObjectPairs' opts targs contentsFieldName =
860+ Tagged . (:[]) . (pack contentsFieldName .=) . gToJSON opts targs
911861
912−instance ( TaggedObject enc arity a
913− , TaggedObject enc arity b
914− ) => TaggedObject enc arity (a :+: b)
915− where
916− taggedObject opts targs tagFieldName contentsFieldName (L1 x) =
917− taggedObject opts targs tagFieldName contentsFieldName x
918− taggedObject opts targs tagFieldName contentsFieldName (R1 x) =
919− taggedObject opts targs tagFieldName contentsFieldName x
920−
921−instance ( IsRecord a isRecord
922− , TaggedObject' enc pairs arity a isRecord
923− , FromPairs enc pairs
924− , FromString enc
925− , KeyValuePair enc pairs
862+--------------------------------------------------------------------------------
863+
864+class TaggedObjectEnc arity f where
865+ taggedObjectEnc :: Options -> ToArgs Encoding arity a
866+ -> String -> String
867+ -> f a -> Encoding
868+
869+instance ( TaggedObjectEnc arity a
870+ , TaggedObjectEnc arity b
871+ ) => TaggedObjectEnc arity (a :+: b) where
872+ taggedObjectEnc opts targs tagFieldName contentsFieldName (L1 x) =
873+ taggedObjectEnc opts targs tagFieldName contentsFieldName x
874+ taggedObjectEnc opts targs tagFieldName contentsFieldName (R1 x) =
875+ taggedObjectEnc opts targs tagFieldName contentsFieldName x
876+
877+instance ( IsRecord a isRecord
878+ , TaggedObjectEnc' arity a isRecord
926879 , Constructor c
927− ) => TaggedObject enc arity (C1 c a)
928− where
929− taggedObject opts targs tagFieldName contentsFieldName =
930− fromPairs . mappend tag . contents
880+ ) => TaggedObjectEnc arity (C1 c a) where
881+ taggedObjectEnc opts targs tagFieldName contentsFieldName v = E.pairs (E.pair key val)
931882 where
932− tag = tagFieldName `pair`
933− (fromString (constructorTagModifier opts (conName (undefined :: t c a p)))
934− :: enc)
935− contents =
936− (unTagged :: Tagged isRecord pairs -> pairs) .
937− taggedObject' opts targs contentsFieldName . unM1
938−
939−class TaggedObject' enc pairs arity f isRecord where
940− taggedObject' :: Options -> ToArgs enc arity a
941− -> String -> f a -> Tagged isRecord pairs
942−
943−instance ( GToJSON enc arity f
944− , KeyValuePair enc pairs
945− ) => TaggedObject' enc pairs arity f False
946− where
947− taggedObject' opts targs contentsFieldName =
948− Tagged . (contentsFieldName `pair`) . gToJSON opts targs
883+ key :: Text
884+ key = pack tagFieldName
885+ val = toEncoding (constructorTagModifier opts (conName (undefined :: t c a p)))
886+ >< ((unTagged :: Tagged isRecord Encoding -> Encoding) . taggedObjectEnc' opts targs contentsFieldName . unM1 $ v)
949887
950−instance OVERLAPPING_ Monoid pairs => TaggedObject' enc pairs arity U1 False where
951− taggedObject' _ _ _ _ = Tagged mempty
888+class TaggedObjectEnc' arity f isRecord where
889+ taggedObjectEnc' :: Options -> ToArgs Encoding arity a
890+ -> String -> f a -> Tagged isRecord Encoding
952891
953−instance ( RecordToPairs enc pairs arity f
954− ) => TaggedObject' enc pairs arity f True
955− where
956− taggedObject' opts targs _ = Tagged . recordToPairs opts targs
892+instance OVERLAPPING_ TaggedObjectEnc' arity U1 False where
893+ taggedObjectEnc' _ _ _ _ = Tagged E.empty
894+
895+instance (RecordToEncoding arity f) => TaggedObjectEnc' arity f True where
896+ taggedObjectEnc' opts targs _ = Tagged . (E.comma ><) . fst
897+ . recordToEncoding opts targs
898+
899+instance (GToEncoding arity f) => TaggedObjectEnc' arity f False where
900+ taggedObjectEnc' opts targs contentsFieldName =
901+ Tagged . (\z -> E.comma >< toEncoding contentsFieldName >< E.colon >< z) .
902+ gToEncoding opts targs
957903
958904--------------------------------------------------------------------------------
959905
@@ -968,38 +914,23 @@ instance (GetConName a, GetConName b) => GetConName (a :+: b) where
968914instance (Constructor c) => GetConName (C1 c a) where
969915 getConName = conName
970916
971−-- For genericToJSONKey
972−instance GetConName a => GetConName (D1 d a) where
973− getConName (M1 x) = getConName x
974−
975917--------------------------------------------------------------------------------
976918
977−-- Reflection of SumEncoding variants
978−
979−data ObjectWithSingleField
980−data TwoElemArray
981−data UntaggedValue
919+class TwoElemArrayObj arity f where
920+ twoElemArrayObj :: Options -> ToArgs Value arity a
921+ -> f a -> V.Vector Value
982922
983−--------------------------------------------------------------------------------
984−
985−class SumToJSON' s enc arity f where
986− sumToJSON' :: Options -> ToArgs enc arity a
987− -> f a -> Tagged s enc
923+instance ( TwoElemArrayObj arity a
924+ , TwoElemArrayObj arity b
925+ ) => TwoElemArrayObj arity (a :+: b) where
926+ twoElemArrayObj opts targs (L1 x) = twoElemArrayObj opts targs x
927+ twoElemArrayObj opts targs (R1 x) = twoElemArrayObj opts targs x
988928
989−instance ( SumToJSON' s enc arity a
990− , SumToJSON' s enc arity b
991− ) => SumToJSON' s enc arity (a :+: b)
992− where
993− sumToJSON' opts targs (L1 x) = sumToJSON' opts targs x
994− sumToJSON' opts targs (R1 x) = sumToJSON' opts targs x
995−
996−--------------------------------------------------------------------------------
997−
998−instance ( GToJSON Value arity a
999− , ConsToJSON Value arity a
929+instance ( GToJSON arity a
930+ , ConsToJSON arity a
1000931 , Constructor c
1001− ) => SumToJSON' TwoElemArray Value arity (C1 c a) where
1002− sumToJSON' opts targs x = Tagged $ Array $ V.create $ do
932+ ) => TwoElemArrayObj arity (C1 c a) where
933+ twoElemArrayObj opts targs x = V.create $ do
1003934 mv <- VM.unsafeNew 2
1004935 VM.unsafeWrite mv 0 $ String $ pack $ constructorTagModifier opts
1005936 $ conName (undefined :: t c a p)
@@ -1008,121 +939,149 @@ instance ( GToJSON Value arity a
1008939
1009940--------------------------------------------------------------------------------
1010941
1011−instance ( GToJSON Encoding arity a
1012− , ConsToJSON Encoding arity a
942+class TwoElemArrayEnc arity f where
943+ twoElemArrayEnc :: Options -> ToArgs Encoding arity a
944+ -> f a -> Encoding
945+
946+instance ( TwoElemArrayEnc arity a
947+ , TwoElemArrayEnc arity b
948+ ) => TwoElemArrayEnc arity (a :+: b) where
949+ twoElemArrayEnc opts targs (L1 x) = twoElemArrayEnc opts targs x
950+ twoElemArrayEnc opts targs (R1 x) = twoElemArrayEnc opts targs x
951+
952+instance ( GToEncoding arity a
953+ , ConsToEncoding arity a
1013954 , Constructor c
1014− ) => SumToJSON' TwoElemArray Encoding arity (C1 c a)
1015− where
1016− sumToJSON' opts targs x = Tagged $ E.list id
955+ ) => TwoElemArrayEnc arity (C1 c a) where
956+ twoElemArrayEnc opts targs x = E.list id
1017957 [ toEncoding (constructorTagModifier opts (conName (undefined :: t c a p)))
1018− , gToJSON opts targs x
958+ , gToEncoding opts targs x
1019959 ]
1020960
1021961--------------------------------------------------------------------------------
1022962
1023−class ConsToJSON enc arity f where
1024− consToJSON :: Options -> ToArgs enc arity a
1025− -> f a -> enc
963+class ConsToJSON arity f where
964+ consToJSON :: Options -> ToArgs Value arity a
965+ -> f a -> Value
1026966
1027−class ConsToJSON' enc arity f isRecord where
1028− consToJSON' :: Options -> ToArgs enc arity a
1029− -> f a -> Tagged isRecord enc
967+class ConsToJSON' arity f isRecord where
968+ consToJSON' :: Options -> ToArgs Value arity a
969+ -> Bool -- ^ Are we a record with one field?
970+ -> f a -> Tagged isRecord Value
1030971
1031−instance ( IsRecord f isRecord
1032− , ConsToJSON' enc arity f isRecord
1033− ) => ConsToJSON enc arity f
1034− where
972+instance ( IsRecord f isRecord
973+ , ConsToJSON' arity f isRecord
974+ ) => ConsToJSON arity f where
1035975 consToJSON opts targs =
1036− (unTagged :: Tagged isRecord enc -> enc)
1037− . consToJSON' opts targs
1038− {-# INLINE consToJSON #-}
976+ (unTagged :: Tagged isRecord Value -> Value)
977+ . consToJSON' opts targs (isUnary (undefined :: f a))
1039978
1040−instance OVERLAPPING_
1041− ( RecordToPairs enc pairs arity (S1 s f)
1042− , FromPairs enc pairs
1043− , GToJSON enc arity f
1044− ) => ConsToJSON' enc arity (S1 s f) True
1045− where
1046− consToJSON' opts targs
1047− | unwrapUnaryRecords opts = Tagged . gToJSON opts targs
1048− | otherwise = Tagged . fromPairs . recordToPairs opts targs
1049− {-# INLINE consToJSON' #-}
1050−
1051−instance ( RecordToPairs enc pairs arity f
1052− , FromPairs enc pairs
1053− ) => ConsToJSON' enc arity f True
1054− where
1055− consToJSON' opts targs = Tagged . fromPairs . recordToPairs opts targs
1056− {-# INLINE consToJSON' #-}
979+instance (RecordToPairs arity f) => ConsToJSON' arity f True where
980+ consToJSON' opts targs isUn f = let
981+ vals = toList $ recordToPairs opts targs f
982+ in case (unwrapUnaryRecords opts,isUn,vals) of
983+ (True,True,[(_,val)]) -> Tagged val
984+ _ -> Tagged $ object vals
1057985
1058−instance GToJSON enc arity f => ConsToJSON' enc arity f False where
1059− consToJSON' opts targs = Tagged . gToJSON opts targs
1060− {-# INLINE consToJSON' #-}
986+instance GToJSON arity f => ConsToJSON' arity f False where
987+ consToJSON' opts targs _ = Tagged . gToJSON opts targs
1061988
1062989--------------------------------------------------------------------------------
1063990
1064−class RecordToPairs enc pairs arity f where
1065− -- 1st element: whole thing
1066− -- 2nd element: in case the record has only 1 field, just the value
1067− -- of the field (without the key); 'Nothing' otherwise
1068− recordToPairs :: Options -> ToArgs enc arity a
1069− -> f a -> pairs
991+class ConsToEncoding arity f where
992+ consToEncoding :: Options -> ToArgs Encoding arity a
993+ -> f a -> Encoding
1070994
1071−instance ( Monoid pairs
1072− , RecordToPairs enc pairs arity a
1073− , RecordToPairs enc pairs arity b
1074− ) => RecordToPairs enc pairs arity (a :*: b)
1075− where
1076− recordToPairs opts (targs :: ToArgs enc arity p) (a :*: b) =
1077− pairsOf a `mappend` pairsOf b
1078− where
1079− pairsOf :: (RecordToPairs enc pairs arity f) => f p -> pairs
1080− pairsOf = recordToPairs opts targs
1081− {-# INLINE recordToPairs #-}
1082−
1083−instance ( Selector s
1084− , GToJSON enc arity a
1085− , KeyValuePair enc pairs
1086− ) => RecordToPairs enc pairs arity (S1 s a)
1087− where
995+class ConsToEncoding' arity f isRecord where
996+ consToEncoding' :: Options -> ToArgs Encoding arity a
997+ -> Bool -- ^ Are we a record with one field?
998+ -> f a -> Tagged isRecord Encoding
999+
1000+instance ( IsRecord f isRecord
1001+ , ConsToEncoding' arity f isRecord
1002+ ) => ConsToEncoding arity f where
1003+ consToEncoding opts targs =
1004+ (unTagged :: Tagged isRecord Encoding -> Encoding)
1005+ . consToEncoding' opts targs (isUnary (undefined :: f a))
1006+
1007+instance (RecordToEncoding arity f) => ConsToEncoding' arity f True where
1008+ consToEncoding' opts targs isUn x =
1009+ let (enc, mbVal) = recordToEncoding opts targs x
1010+ in case (unwrapUnaryRecords opts, isUn, mbVal) of
1011+ (True, True, Just val) -> Tagged val
1012+ _ -> Tagged $ E.wrapObject enc
1013+
1014+instance GToEncoding arity f => ConsToEncoding' arity f False where
1015+ consToEncoding' opts targs _ = Tagged . gToEncoding opts targs
1016+
1017+--------------------------------------------------------------------------------
1018+
1019+class RecordToPairs arity f where
1020+ recordToPairs :: Options -> ToArgs Value arity a
1021+ -> f a -> DList Pair
1022+
1023+instance ( RecordToPairs arity a
1024+ , RecordToPairs arity b
1025+ ) => RecordToPairs arity (a :*: b) where
1026+ recordToPairs opts targs (a :*: b) = recordToPairs opts targs a <>
1027+ recordToPairs opts targs b
1028+
1029+instance (Selector s, GToJSON arity a) => RecordToPairs arity (S1 s a) where
10881030 recordToPairs = fieldToPair
1089− {-# INLINE recordToPairs #-}
1090−
1091−instance INCOHERENT_
1092− ( Selector s
1093− , GToJSON enc arity (K1 i (Maybe a))
1094− , KeyValuePair enc pairs
1095− , Monoid pairs
1096− ) => RecordToPairs enc pairs arity (S1 s (K1 i (Maybe a)))
1097− where
1031+
1032+instance OVERLAPPING_ (Selector s, ToJSON a) =>
1033+ RecordToPairs arity (S1 s (K1 i (Maybe a))) where
10981034 recordToPairs opts _ (M1 k1) | omitNothingFields opts
1099− , K1 Nothing <- k1 = mempty
1035+ , K1 Nothing <- k1 = DList.empty
11001036 recordToPairs opts targs m1 = fieldToPair opts targs m1
1101− {-# INLINE recordToPairs #-}
1102−
1103−instance INCOHERENT_
1104− ( Selector s
1105− , GToJSON enc arity (K1 i (Maybe a))
1106− , KeyValuePair enc pairs
1107− , Monoid pairs
1108− ) => RecordToPairs enc pairs arity (S1 s (K1 i (Semigroup.Option a)))
1109− where
1110− recordToPairs opts targs = recordToPairs opts targs . unwrap
1111− where
1112− unwrap :: S1 s (K1 i (Semigroup.Option a)) p -> S1 s (K1 i (Maybe a)) p
1113− unwrap (M1 (K1 (Semigroup.Option a))) = M1 (K1 a)
1114− {-# INLINE recordToPairs #-}
1115−
1116−fieldToPair :: (Selector s
1117− , GToJSON enc arity a
1118− , KeyValuePair enc pairs)
1119− => Options -> ToArgs enc arity p
1120− -> S1 s a p -> pairs
1121−fieldToPair opts targs m1 =
1122− let key = fieldLabelModifier opts (selName m1)
1123− value = gToJSON opts targs (unM1 m1)
1124− in key `pair` value
1125−{-# INLINE fieldToPair #-}
1037+
1038+fieldToPair :: (Selector s, GToJSON arity a)
1039+ => Options -> ToArgs Value arity p
1040+ -> S1 s a p -> DList Pair
1041+fieldToPair opts targs m1 = pure ( pack $ fieldLabelModifier opts $ selName m1
1042+ , gToJSON opts targs (unM1 m1)
1043+ )
1044+
1045+--------------------------------------------------------------------------------
1046+
1047+class RecordToEncoding arity f where
1048+ -- 1st element: whole thing
1049+ -- 2nd element: in case the record has only 1 field, just the value
1050+ -- of the field (without the key); 'Nothing' otherwise
1051+ recordToEncoding :: Options -> ToArgs Encoding arity a
1052+ -> f a -> (Encoding, Maybe Encoding)
1053+
1054+instance ( RecordToEncoding arity a
1055+ , RecordToEncoding arity b
1056+ ) => RecordToEncoding arity (a :*: b) where
1057+ recordToEncoding opts targs (a :*: b) | omitNothingFields opts =
1058+ (E.econcat $ intersperse E.comma $
1059+ filter (not . E.nullEncoding)
1060+ [ fst (recordToEncoding opts targs a)
1061+ , fst (recordToEncoding opts targs b) ]
1062+ , Nothing)
1063+ recordToEncoding opts targs (a :*: b) =
1064+ (fst (recordToEncoding opts targs a) >< E.comma ><
1065+ fst (recordToEncoding opts targs b),
1066+ Nothing)
1067+
1068+
1069+instance (Selector s, GToEncoding arity a) => RecordToEncoding arity (S1 s a) where
1070+ recordToEncoding = fieldToEncoding
1071+
1072+instance OVERLAPPING_ (Selector s, ToJSON a) =>
1073+ RecordToEncoding arity (S1 s (K1 i (Maybe a))) where
1074+ recordToEncoding opts _ (M1 k1) | omitNothingFields opts
1075+ , K1 Nothing <- k1 = (E.empty, Nothing)
1076+ recordToEncoding opts targs m1 = fieldToEncoding opts targs m1
1077+
1078+fieldToEncoding :: (Selector s, GToEncoding arity a)
1079+ => Options -> ToArgs Encoding arity p
1080+ -> S1 s a p -> (Encoding, Maybe Encoding)
1081+fieldToEncoding opts targs m1 =
1082+ let keyBuilder = toEncoding (fieldLabelModifier opts $ selName m1)
1083+ valueBuilder = gToEncoding opts targs (unM1 m1)
1084+ in (keyBuilder >< E.colon >< valueBuilder, Just valueBuilder)
11261085
11271086--------------------------------------------------------------------------------
11281087
@@ -1145,12 +1104,10 @@ instance ( WriteProduct arity a
11451104 lenL = len `unsafeShiftR` 1
11461105 lenR = len - lenL
11471106 ixR = ix + lenL
1148− {-# INLINE writeProduct #-}
11491107
1150−instance OVERLAPPABLE_ (GToJSON Value arity a) => WriteProduct arity a where
1108+instance OVERLAPPABLE_ (GToJSON arity a) => WriteProduct arity a where
11511109 writeProduct opts targs mv ix _ =
11521110 VM.unsafeWrite mv ix . gToJSON opts targs
1153− {-# INLINE writeProduct #-}
11541111
11551112--------------------------------------------------------------------------------
11561113
@@ -1168,41 +1125,110 @@ instance ( EncodeProduct arity a
11681125 encodeProduct opts targs (a :*: b) =
11691126 encodeProduct opts targs a >*<
11701127 encodeProduct opts targs b
1171− {-# INLINE encodeProduct #-}
11721128
1173−instance OVERLAPPABLE_ (GToJSON Encoding arity a) => EncodeProduct arity a where
1174− encodeProduct opts targs a = E.retagEncoding $ gToJSON opts targs a
1175− {-# INLINE encodeProduct #-}
1129+instance OVERLAPPABLE_ (GToEncoding arity a) => EncodeProduct arity a where
1130+ encodeProduct opts targs a = E.retagEncoding $ gToEncoding opts targs a
11761131
11771132--------------------------------------------------------------------------------
11781133
1179−instance ( GToJSON enc arity a
1180− , ConsToJSON enc arity a
1181− , FromPairs enc pairs
1182− , KeyValuePair enc pairs
1134+class ObjectWithSingleFieldObj arity f where
1135+ objectWithSingleFieldObj :: Options -> ToArgs Value arity a
1136+ -> f a -> Object
1137+
1138+instance ( ObjectWithSingleFieldObj arity a
1139+ , ObjectWithSingleFieldObj arity b
1140+ ) => ObjectWithSingleFieldObj arity (a :+: b) where
1141+ objectWithSingleFieldObj opts targs (L1 x) =
1142+ objectWithSingleFieldObj opts targs x
1143+ objectWithSingleFieldObj opts targs (R1 x) =
1144+ objectWithSingleFieldObj opts targs x
1145+
1146+instance ( GToJSON arity a
1147+ , ConsToJSON arity a
11831148 , Constructor c
1184− ) => SumToJSON' ObjectWithSingleField enc arity (C1 c a)
1185− where
1186− sumToJSON' opts targs =
1187− Tagged . fromPairs . (typ `pair`) . gToJSON opts targs
1149+ ) => ObjectWithSingleFieldObj arity (C1 c a) where
1150+ objectWithSingleFieldObj opts targs = H.singleton typ . gToJSON opts targs
11881151 where
1189− typ = constructorTagModifier opts $
1152+ typ = pack $ constructorTagModifier opts $
11901153 conName (undefined :: t c a p)
11911154
11921155--------------------------------------------------------------------------------
11931156
1157+class ObjectWithSingleFieldEnc arity f where
1158+ objectWithSingleFieldEnc :: Options -> ToArgs Encoding arity a
1159+ -> f a -> Encoding
1160+
1161+instance ( ObjectWithSingleFieldEnc arity a
1162+ , ObjectWithSingleFieldEnc arity b
1163+ ) => ObjectWithSingleFieldEnc arity (a :+: b) where
1164+ objectWithSingleFieldEnc opts targs (L1 x) =
1165+ objectWithSingleFieldEnc opts targs x
1166+ objectWithSingleFieldEnc opts targs (R1 x) =
1167+ objectWithSingleFieldEnc opts targs x
1168+
1169+instance ( GToEncoding arity a
1170+ , ConsToEncoding arity a
1171+ , Constructor c
1172+ ) => ObjectWithSingleFieldEnc arity (C1 c a) where
1173+ objectWithSingleFieldEnc opts targs v = E.pairs (E.pair key val)
1174+ where
1175+ key :: Text
1176+ key = pack (constructorTagModifier opts (conName (undefined :: t c a p)))
1177+ val :: Encoding' Value
1178+ val = gToEncoding opts targs v
1179+
1180+--------------------------------------------------------------------------------
1181+
1182+class UntaggedValueObj arity f where
1183+ untaggedValueObj :: Options -> ToArgs Value arity a
1184+ -> f a -> Value
1185+
1186+instance
1187+ ( UntaggedValueObj arity a
1188+ , UntaggedValueObj arity b
1189+ ) => UntaggedValueObj arity (a :+: b)
1190+ where
1191+ untaggedValueObj opts targs (L1 x) = untaggedValueObj opts targs x
1192+ untaggedValueObj opts targs (R1 x) = untaggedValueObj opts targs x
1193+
11941194instance OVERLAPPABLE_
1195− ( ConsToJSON enc arity a
1196− ) => SumToJSON' UntaggedValue enc arity (C1 c a)
1195+ ( GToJSON arity a
1196+ , ConsToJSON arity a
1197+ ) => UntaggedValueObj arity (C1 c a) where
1198+ untaggedValueObj = gToJSON
1199+
1200+instance OVERLAPPING_
1201+ ( Constructor c )
1202+ => UntaggedValueObj arity (C1 c U1)
11971203 where
1198− sumToJSON' opts targs = Tagged . gToJSON opts targs
1204+ untaggedValueObj opts _ _ = toJSON $
1205+ constructorTagModifier opts $ conName (undefined :: t c U1 p)
1206+
1207+--------------------------------------------------------------------------------
1208+
1209+class UntaggedValueEnc arity f where
1210+ untaggedValueEnc :: Options -> ToArgs Encoding arity a
1211+ -> f a -> Encoding
1212+instance
1213+ ( UntaggedValueEnc arity a
1214+ , UntaggedValueEnc arity b
1215+ ) => UntaggedValueEnc arity (a :+: b)
1216+ where
1217+ untaggedValueEnc opts targs (L1 x) = untaggedValueEnc opts targs x
1218+ untaggedValueEnc opts targs (R1 x) = untaggedValueEnc opts targs x
1219+
1220+instance OVERLAPPABLE_
1221+ ( GToEncoding arity a
1222+ , ConsToEncoding arity a
1223+ ) => UntaggedValueEnc arity (C1 c a)
1224+ where
1225+ untaggedValueEnc = gToEncoding
11991226
12001227instance OVERLAPPING_
1201− ( Constructor c
1202− , FromString enc
1203− ) => SumToJSON' UntaggedValue enc arity (C1 c U1)
1228+ ( Constructor c )
1229+ => UntaggedValueEnc arity (C1 c U1)
12041230 where
1205− sumToJSON' opts _ _ = Tagged . fromString $
1231+ untaggedValueEnc opts _ _ = toEncoding $
12061232 constructorTagModifier opts $ conName (undefined :: t c U1 p)
12071233
12081234-------------------------------------------------------------------------------
@@ -1276,13 +1302,6 @@ instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
12761302 toEncoding = toEncoding2
12771303 {-# INLINE toEncoding #-}
12781304
1279−instance ToJSON Void where
1280− toJSON = absurd
1281− {-# INLINE toJSON #-}
1282−
1283− toEncoding = absurd
1284− {-# INLINE toEncoding #-}
1285−
12861305
12871306instance ToJSON Bool where
12881307 toJSON = Bool
@@ -1468,6 +1487,7 @@ instance ToJSONKey Int64 where
14681487 toJSONKey = toJSONKeyTextEnc E.int64Text
14691488 {-# INLINE toJSONKey #-}
14701489
1490+
14711491instance ToJSON Word where
14721492 toJSON = Number . fromIntegral
14731493 {-# INLINE toJSON #-}
@@ -1527,12 +1547,6 @@ instance ToJSONKey Word64 where
15271547 toJSONKey = toJSONKeyTextEnc E.word64Text
15281548 {-# INLINE toJSONKey #-}
15291549
1530−instance ToJSON CTime where
1531− toJSON (CTime i) = toJSON i
1532− {-# INLINE toJSON #-}
1533−
1534− toEncoding (CTime i) = toEncoding i
1535− {-# INLINE toEncoding #-}
15361550
15371551instance ToJSON Text where
15381552 toJSON = String
@@ -1647,7 +1661,7 @@ instance (ToJSON a) => ToJSON (Identity a) where
16471661 toEncodingList = liftToEncodingList toEncoding toEncodingList
16481662 {-# INLINE toEncodingList #-}
16491663
1650−instance (ToJSONKey a) => ToJSONKey (Identity a) where
1664+instance (ToJSONKey a, ToJSON a) => ToJSONKey (Identity a) where
16511665 toJSONKey = contramapToJSONKeyFunction runIdentity toJSONKey
16521666 toJSONKeyList = contramapToJSONKeyFunction (map runIdentity) toJSONKeyList
16531667
@@ -1838,17 +1852,6 @@ instance (ToJSON v) => ToJSON (Tree.Tree v) where
18381852 toEncoding = toEncoding1
18391853 {-# INLINE toEncoding #-}
18401854
1841−-------------------------------------------------------------------------------
1842−-- uuid
1843−-------------------------------------------------------------------------------
1844−
1845−instance ToJSON UUID.UUID where
1846− toJSON = toJSON . UUID.toText
1847− toEncoding = E.unsafeToEncoding . EB.quote . B.byteString . UUID.toASCIIBytes
1848−
1849−instance ToJSONKey UUID.UUID where
1850− toJSONKey = ToJSONKeyText UUID.toText $
1851− E.unsafeToEncoding . EB.quote . B.byteString . UUID.toASCIIBytes
18521855
18531856-------------------------------------------------------------------------------
18541857-- vector
@@ -1862,8 +1865,6 @@ instance ToJSON1 Vector where
18621865 {-# INLINE liftToEncoding #-}
18631866
18641867instance (ToJSON a) => ToJSON (Vector a) where
1865− {-# SPECIALIZE instance ToJSON Array #-}
1866−
18671868 toJSON = toJSON1
18681869 {-# INLINE toJSON #-}
18691870
@@ -1935,8 +1936,6 @@ instance ToJSONKey k => ToJSON1 (H.HashMap k) where
19351936 {-# INLINE liftToEncoding #-}
19361937
19371938instance (ToJSON v, ToJSONKey k) => ToJSON (H.HashMap k v) where
1938− {-# SPECIALIZE instance ToJSON Object #-}
1939−
19401939 toJSON = toJSON1
19411940 {-# INLINE toJSON #-}
19421941
@@ -1966,32 +1965,6 @@ dotNetTime (DotNetTime t) = secs ++ formatMillis t ++ ")/"
19661965formatMillis :: (FormatTime t) => t -> String
19671966formatMillis = take 3 . formatTime defaultTimeLocale "%q"
19681967
1969−-------------------------------------------------------------------------------
1970−-- primitive
1971−-------------------------------------------------------------------------------
1972−
1973−instance ToJSON a => ToJSON (PM.Array a) where
1974− -- note: we could do better than this if vector exposed the data
1975− -- constructor in Data.Vector.
1976− toJSON = toJSON . Exts.toList
1977− toEncoding = toEncoding . Exts.toList
1978−
1979−instance ToJSON a => ToJSON (PM.SmallArray a) where
1980− toJSON = toJSON . Exts.toList
1981− toEncoding = toEncoding . Exts.toList
1982−
1983−#if (MIN_VERSION_primitive(0,6,4))
1984−instance (PM.Prim a,ToJSON a) => ToJSON (PM.PrimArray a) where
1985− toJSON = toJSON . Exts.toList
1986− toEncoding = toEncoding . Exts.toList
1987−
1988−#if !MIN_VERSION_primitive(0,7,0)
1989−instance (PM.PrimUnlifted a,ToJSON a) => ToJSON (PM.UnliftedArray a) where
1990− toJSON = toJSON . Exts.toList
1991− toEncoding = toEncoding . Exts.toList
1992−#endif
1993−#endif
1994−
19951968-------------------------------------------------------------------------------
19961969-- time
19971970-------------------------------------------------------------------------------
@@ -2040,11 +2013,10 @@ stringEncoding :: Encoding' Text -> Value
20402013stringEncoding = String
20412014 . T.dropAround (== '"')
20422015 . T.decodeLatin1
2043− . L.toStrict
2016+ . lazyToStrictByteString
20442017 . E.encodingToLazyByteString
20452018{-# INLINE stringEncoding #-}
20462019
2047−
20482020instance ToJSON NominalDiffTime where
20492021 toJSON = Number . realToFrac
20502022 {-# INLINE toJSON #-}
@@ -2052,58 +2024,6 @@ instance ToJSON NominalDiffTime where
20522024 toEncoding = E.scientific . realToFrac
20532025 {-# INLINE toEncoding #-}
20542026
2055−
2056−instance ToJSON DiffTime where
2057− toJSON = Number . realToFrac
2058− {-# INLINE toJSON #-}
2059−
2060− toEncoding = E.scientific . realToFrac
2061− {-# INLINE toEncoding #-}
2062−
2063−-- | Encoded as number
2064−instance ToJSON SystemTime where
2065− toJSON (MkSystemTime secs nsecs) =
2066− toJSON (fromIntegral secs + fromIntegral nsecs / 1000000000 :: Nano)
2067− toEncoding (MkSystemTime secs nsecs) =
2068− toEncoding (fromIntegral secs + fromIntegral nsecs / 1000000000 :: Nano)
2069−
2070−instance ToJSON CalendarDiffTime where
2071− toJSON (CalendarDiffTime m nt) = object
2072− [ "months" .= m
2073− , "time" .= nt
2074− ]
2075− toEncoding (CalendarDiffTime m nt) = E.pairs
2076− ("months" .= m <> "time" .= nt)
2077−
2078−instance ToJSON CalendarDiffDays where
2079− toJSON (CalendarDiffDays m d) = object
2080− [ "months" .= m
2081− , "days" .= d
2082− ]
2083− toEncoding (CalendarDiffDays m d) = E.pairs
2084− ("months" .= m <> "days" .= d)
2085−
2086−instance ToJSON DayOfWeek where
2087− toJSON Monday = "monday"
2088− toJSON Tuesday = "tuesday"
2089− toJSON Wednesday = "wednesday"
2090− toJSON Thursday = "thursday"
2091− toJSON Friday = "friday"
2092− toJSON Saturday = "saturday"
2093− toJSON Sunday = "sunday"
2094−
2095−toEncodingDayOfWeek :: DayOfWeek -> E.Encoding' Text
2096−toEncodingDayOfWeek Monday = E.unsafeToEncoding "\"monday\""
2097−toEncodingDayOfWeek Tuesday = E.unsafeToEncoding "\"tuesday\""
2098−toEncodingDayOfWeek Wednesday = E.unsafeToEncoding "\"wednesday\""
2099−toEncodingDayOfWeek Thursday = E.unsafeToEncoding "\"thursday\""
2100−toEncodingDayOfWeek Friday = E.unsafeToEncoding "\"friday\""
2101−toEncodingDayOfWeek Saturday = E.unsafeToEncoding "\"saturday\""
2102−toEncodingDayOfWeek Sunday = E.unsafeToEncoding "\"sunday\""
2103−
2104−instance ToJSONKey DayOfWeek where
2105− toJSONKey = toJSONKeyTextEnc toEncodingDayOfWeek
2106−
21072027-------------------------------------------------------------------------------
21082028-- base Monoid/Semigroup
21092029-------------------------------------------------------------------------------
@@ -2245,13 +2165,6 @@ instance ToJSON a => ToJSON (Semigroup.Option a) where
22452165-- tagged
22462166-------------------------------------------------------------------------------
22472167
2248−instance ToJSON1 Proxy where
2249− liftToJSON _ _ _ = Null
2250− {-# INLINE liftToJSON #-}
2251−
2252− liftToEncoding _ _ _ = E.null_
2253− {-# INLINE liftToEncoding #-}
2254−
22552168instance ToJSON (Proxy a) where
22562169 toJSON _ = Null
22572170 {-# INLINE toJSON #-}
@@ -2260,13 +2173,6 @@ instance ToJSON (Proxy a) where
22602173 {-# INLINE toEncoding #-}
22612174
22622175
2263−instance ToJSON2 Tagged where
2264− liftToJSON2 _ _ t _ (Tagged x) = t x
2265− {-# INLINE liftToJSON2 #-}
2266−
2267− liftToEncoding2 _ _ t _ (Tagged x) = t x
2268− {-# INLINE liftToEncoding2 #-}
2269−
22702176instance ToJSON1 (Tagged a) where
22712177 liftToJSON t _ (Tagged x) = t x
22722178 {-# INLINE liftToJSON #-}
@@ -2281,6 +2187,7 @@ instance ToJSON b => ToJSON (Tagged a b) where
22812187 toEncoding = toEncoding1
22822188 {-# INLINE toEncoding #-}
22832189
2190+
22842191instance ToJSONKey b => ToJSONKey (Tagged a b) where
22852192 toJSONKey = contramapToJSONKeyFunction unTagged toJSONKey
22862193 toJSONKeyList = contramapToJSONKeyFunction (fmap unTagged) toJSONKeyList
@@ -2847,26 +2754,27 @@ instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g,
28472754 toEncoding = toEncoding2
28482755 {-# INLINE toEncoding #-}
28492756
2850−--------------------------------------------------------------------------------
2851−
2852−-- | Wrap a list of pairs as an object.
2853−class Monoid pairs => FromPairs enc pairs | enc -> pairs where
2854− fromPairs :: pairs -> enc
2855−
2856−instance (a ~ Value) => FromPairs (Encoding' a) Series where
2857− fromPairs = E.pairs
2858−
2859−instance FromPairs Value (DList Pair) where
2860− fromPairs = object . toList
2757+-------------------------------------------------------------------------------
2758+-- pre-bytestring-0.10 compatibility
2759+-------------------------------------------------------------------------------
28612760
2862−-- | Like 'KeyValue' but the value is already converted to JSON
2863−-- ('Value' or 'Encoding'), and the result actually represents lists of pairs
2864−-- so it can be readily concatenated.
2865−class Monoid kv => KeyValuePair v kv where
2866− pair :: String -> v -> kv
2761+{-# INLINE lazyToStrictByteString #-}
2762+lazyToStrictByteString :: L.ByteString -> S.ByteString
2763+#if MIN_VERSION_bytestring(0,10,0)
2764+lazyToStrictByteString = L.toStrict
2765+#else
2766+lazyToStrictByteString = packChunks
28672767
2868−instance (v ~ Value) => KeyValuePair v (DList Pair) where
2869− pair k v = DList.singleton (pack k .= v)
2768+-- packChunks is taken from the blaze-builder package.
28702769
2871−instance (e ~ Encoding) => KeyValuePair e Series where
2872− pair = E.pairStr
2770+-- | Pack the chunks of a lazy bytestring into a single strict bytestring.
2771+packChunks :: L.ByteString -> S.ByteString
2772+packChunks lbs = do
2773+ S.unsafeCreate (fromIntegral $ L.length lbs) (copyChunks lbs)
2774+ where
2775+ copyChunks !L.Empty !_pf = return ()
2776+ copyChunks !(L.Chunk (S.PS fpbuf o l) lbs') !pf = do
2777+ withForeignPtr fpbuf $ \pbuf ->
2778+ copyBytes pf (pbuf `plusPtr` o) l
2779+ copyChunks lbs' (pf `plusPtr` l)
2780+#endif
Makefiledeleted−2
@@ -1,2 +0,0 @@
1−lint:
2− ./run-hlint.sh --cpp-include include/ --cpp-file travis/cabal_macros.h Data/ attoparsec-iso8601/ benchmarks/ examples/ ffi/ pure/ tests/
README.markdown+4−3
@@ -15,13 +15,14 @@ Master [git repository](http://github.com/bos/aeson):
1515
1616* `git clone git://github.com/bos/aeson.git`
1717
18−See what's changed in recent (and upcoming) releases:
18+There's also a [Mercurial mirror](http://bitbucket.org/bos/aeson):
1919
20−* https://github.com/bos/aeson/blob/master/changelog.md
20+* `hg clone http://bitbucket.org/bos/aeson`
2121
2222(You can create and contribute changes using either git or Mercurial.)
2323
2424
2525# Authors
2626
27−This library was originally written by Bryan O'Sullivan.
27+This library is written and maintained by Bryan O'Sullivan,
28+<bos@serpentine.com>.
aeson.cabal+65−107
@@ -1,12 +1,12 @@
11name: aeson
2−version: 1.4.6.0
2+version: 1.0.0.0
33license: BSD3
44license-file: LICENSE
55category: Text, Web, JSON
66copyright: (c) 2011-2016 Bryan O'Sullivan
77 (c) 2011 MailRank, Inc.
88author: Bryan O'Sullivan <bos@serpentine.com>
9−maintainer: Adam Bergmark <adam@bergmark.nl>
9+maintainer: Bryan O'Sullivan <bos@serpentine.com>
1010stability: experimental
1111tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1
1212synopsis: Fast JSON parsing and encoding
@@ -21,10 +21,23 @@ description:
2121 To get started, see the documentation for the @Data.Aeson@ module
2222 below.
2323 .
24+ Parsing performance on a late 2013 MacBook Pro (2.6GHz Core i7),
25+ running 64-bit GHC 7.10.1, for mostly-English tweets from Twitter's
26+ JSON search API:
27+ .
28+ * 6.4 KB payloads, English: 7570 msg\/sec (47.6 MB\/sec)
29+ .
30+ * 14.6 KB payloads, Japanese: 3261 msg\/sec (46.6 MB\/sec)
31+ .
32+ Encoding performance on the same machine and data:
33+ .
34+ * 6.4 KB payloads, English: 22738 msg\/sec (142.9 MB\/sec)
35+ .
36+ * 14.6 KB payloads, Japanese: 15911 msg\/sec (227.4 MB\/sec)
37+ .
2438 (A note on naming: in Greek mythology, Aeson was the father of Jason.)
2539
2640extra-source-files:
27− *.yaml
2841 README.markdown
2942 benchmarks/*.cabal
3043 benchmarks/*.hs
@@ -33,17 +46,13 @@ extra-source-files:
3346 benchmarks/Makefile
3447 benchmarks/Typed/*.hs
3548 benchmarks/json-data/*.json
36− cbits/*.c
49+ include/overlapping-compat.h
3750 changelog.md
3851 examples/*.cabal
3952 examples/*.hs
4053 examples/Twitter/*.hs
41− ffi/Data/Aeson/Parser/*.hs
4254 include/*.h
43− tests/JSONTestSuite/test_parsing/*.json
44− tests/JSONTestSuite/test_transform/*.json
45− tests/golden/*.expected
46− pure/Data/Aeson/Parser/*.hs
55+ cbits/*.c
4756
4857flag developer
4958 description: operate in developer mode
@@ -60,14 +69,8 @@ flag bytestring-builder
6069 default: False
6170 manual: False
6271
63−flag cffi
64− description: Controls whether to include c-ffi bits or pure haskell. Default to False for security.
65− default: False
66− manual: True
67−
6872library
6973 default-language: Haskell2010
70− hs-source-dirs: . attoparsec-iso8601/
7174
7275 exposed-modules:
7376 Data.Aeson
@@ -76,12 +79,10 @@ library
7679 Data.Aeson.Text
7780 Data.Aeson.Types
7881 Data.Aeson.TH
79− Data.Aeson.QQ.Simple
8082
8183 Data.Aeson.Encoding.Internal
8284 Data.Aeson.Internal
8385 Data.Aeson.Internal.Time
84− Data.Aeson.Parser.Internal
8586
8687 -- Deprecated modules
8788 exposed-modules:
@@ -90,6 +91,7 @@ library
9091 other-modules:
9192 Data.Aeson.Encoding.Builder
9293 Data.Aeson.Internal.Functions
94+ Data.Aeson.Parser.Internal
9395 Data.Aeson.Parser.Unescape
9496 Data.Aeson.Parser.Time
9597 Data.Aeson.Types.FromJSON
@@ -97,62 +99,42 @@ library
9799 Data.Aeson.Types.ToJSON
98100 Data.Aeson.Types.Class
99101 Data.Aeson.Types.Internal
100− Data.Attoparsec.Time
101− Data.Attoparsec.Time.Internal
102102
103− -- GHC bundled libs
104103 build-depends:
105− base >= 4.7.0.0 && < 5,
106− bytestring >= 0.10.4.0 && < 0.11,
107− containers >= 0.5.5.1 && < 0.7,
108− deepseq >= 1.3.0.0 && < 1.5,
109− ghc-prim >= 0.2 && < 0.6,
110− template-haskell >= 2.9.0.0 && < 2.16,
111− text >= 1.2.3.0 && < 1.3,
112− time >= 1.4 && < 1.10
113−
114− if impl(ghc >= 8.0)
115− build-depends: bytestring >= 0.10.8.1
116−
117− -- Compat
118− build-depends:
119− base-compat >= 0.9.1 && < 0.12,
120− time-compat >= 1.9.2.2 && < 1.10
104+ attoparsec >= 0.13.0.1,
105+ base >= 4.5 && < 5,
106+ base-compat >= 0.9.1 && < 0.10,
107+ containers >= 0.2.4.1,
108+ deepseq >= 1.3,
109+ dlist >= 0.2,
110+ ghc-prim >= 0.2,
111+ hashable >= 1.1.2.0,
112+ scientific >= 0.3.4.7 && < 0.4,
113+ tagged >=0.8.3 && <0.9,
114+ template-haskell >= 2.7,
115+ text >= 1.1.1.0,
116+ time >= 1.1.1.4,
117+ time-locale-compat >= 0.1.1 && < 0.2,
118+ unordered-containers >= 0.2.5.0,
119+ vector >= 0.8
121120
122− if !impl(ghc >= 8.6)
123− build-depends:
124− contravariant >=1.4.1 && <1.6
121+ if flag(bytestring-builder)
122+ build-depends: bytestring >= 0.9 && < 0.10.4,
123+ bytestring-builder >= 0.10.4 && < 1
124+ else
125+ build-depends: bytestring >= 0.10.4
125126
126127 if !impl(ghc >= 8.0)
127128 -- `Data.Semigroup` and `Control.Monad.Fail` and `Control.Monad.IO.Class` are available in base only since GHC 8.0 / base 4.9
128129 build-depends:
129− semigroups >= 0.18.5 && < 0.20,
130− transformers >= 0.3.0.0 && < 0.6,
131− transformers-compat >= 0.6.2 && < 0.7,
130+ semigroups >= 0.18.2 && < 0.19,
131+ transformers >= 0.2.2.0,
132+ transformers-compat >= 0.3,
132133 fail == 4.9.*
133134
134135 if !impl(ghc >= 7.10)
135136 -- `Numeric.Natural` is available in base only since GHC 7.10 / base 4.8
136− build-depends: nats >= 1.1.1 && < 1.2,
137− void >= 0.7.2 && < 0.8
138−
139− -- cannot use latest version
140− build-depends:
141− unordered-containers >= 0.2.8.0 && < 0.3,
142−
143− -- not in LTS-12.10
144− tagged >= 0.8.5 && < 0.9,
145− primitive >= 0.6.3.0 && < 0.8
146−
147− -- Other dependencies
148− build-depends:
149− attoparsec >= 0.13.2.2 && < 0.14,
150− dlist >= 0.8.0.4 && < 0.9,
151− hashable >= 1.2.7.0 && < 1.4,
152− scientific >= 0.3.6.2 && < 0.4,
153− th-abstraction >= 0.2.8.0 && < 0.4,
154− uuid-types >= 1.0.3 && < 1.1,
155− vector >= 0.12.0.1 && < 0.13
137+ build-depends: nats >= 1 && < 1.2
156138
157139 ghc-options: -Wall
158140
@@ -166,78 +148,54 @@ library
166148 ghc-options: -O2
167149
168150 include-dirs: include
169− if impl(ghcjs) || !flag(cffi)
170− hs-source-dirs: pure
171− other-modules: Data.Aeson.Parser.UnescapePure
172− else
173− c-sources: cbits/unescape_string.c
174− cpp-options: -DCFFI
175− hs-source-dirs: ffi
176− other-modules: Data.Aeson.Parser.UnescapeFFI
151+ c-sources: cbits/unescape_string.c
177152
178153test-suite tests
179154 default-language: Haskell2010
180− type: exitcode-stdio-1.0
181− hs-source-dirs: tests ffi pure
182− main-is: Tests.hs
183− c-sources: cbits/unescape_string.c
184− ghc-options: -Wall -threaded -rtsopts
185−
155+ type: exitcode-stdio-1.0
156+ hs-source-dirs: tests
157+ main-is: Tests.hs
186158 other-modules:
187− Data.Aeson.Parser.UnescapeFFI
188− Data.Aeson.Parser.UnescapePure
189159 DataFamilies.Properties
190160 DataFamilies.Instances
191161 DataFamilies.Encoders
192162 DataFamilies.Types
193163 Encoders
194− ErrorMessages
195164 Functions
196165 Instances
197166 Options
198− PropUtils
199167 Properties
200− PropertyGeneric
201− PropertyKeys
202− PropertyRoundTrip
203− PropertyRTFunctors
204− PropertyTH
205− SerializationFormatSpec
206168 Types
207169 UnitTests
208170 UnitTests.NullaryConstructors
209171
172+ ghc-options: -Wall -threaded -rtsopts
173+
210174 build-depends:
211− QuickCheck >= 2.10.0.1 && < 2.14,
175+ HUnit,
176+ QuickCheck >= 2.7 && <2.8.3,
212177 aeson,
213− integer-logarithms >= 1 && <1.1,
214178 attoparsec,
215179 base,
216180 base-compat,
217− base-orphans >= 0.5.3 && <0.9,
218− base16-bytestring,
181+ base-orphans >= 0.5.3 && <0.6,
219182 containers,
220− directory,
221183 dlist,
222− Diff >= 0.4 && < 0.5,
223− filepath,
224− generic-deriving >= 1.10 && < 1.14,
184+ generic-deriving >= 1.10 && < 1.11,
225185 ghc-prim >= 0.2,
226186 hashable >= 1.2.4.0,
227187 scientific,
228188 tagged,
229189 template-haskell,
230− tasty,
231− tasty-golden,
232− tasty-hunit,
233− tasty-quickcheck,
190+ test-framework,
191+ test-framework-hunit,
192+ test-framework-quickcheck2,
234193 text,
235194 time,
236− time-compat,
195+ time-locale-compat,
237196 unordered-containers,
238− uuid-types,
239197 vector,
240− quickcheck-instances >= 0.3.21 && <0.4
198+ quickcheck-instances >=0.3.12
241199
242200 if flag(bytestring-builder)
243201 build-depends: bytestring >= 0.9 && < 0.10.4,
@@ -247,20 +205,20 @@ test-suite tests
247205
248206 if !impl(ghc >= 8.0)
249207 build-depends:
250− semigroups >= 0.18.2 && < 0.20,
208+ semigroups >= 0.18.2 && < 0.19,
251209 transformers >= 0.2.2.0,
252210 transformers-compat >= 0.3
253211
254212 if !impl(ghc >= 7.10)
255− build-depends: nats >=1 && <1.2,
256− void >=0.7.2 && <0.8
213+ build-depends: nats >=1 && <1.2
257214
258215 if impl(ghc >= 7.8)
259216 build-depends: hashable-time >= 0.2 && <0.3
260217
261− if flag(fast)
262− ghc-options: -fno-enable-rewrite-rules
263−
264218source-repository head
265219 type: git
266220 location: git://github.com/bos/aeson.git
221+
222+source-repository head
223+ type: mercurial
224+ location: https://bitbucket.org/bos/aeson
attoparsec-iso8601/Data/Attoparsec/Time.hsdeleted−148
@@ -1,148 +0,0 @@
1−{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
4−-- |
5−-- Module: Data.Aeson.Parser.Time
6−-- Copyright: (c) 2015-2016 Bryan O'Sullivan
7−-- License: BSD3
8−-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>
9−-- Stability: experimental
10−-- Portability: portable
11−--
12−-- Parsers for parsing dates and times.
13−
14−module Data.Attoparsec.Time
15− (
16− day
17− , localTime
18− , timeOfDay
19− , timeZone
20− , utcTime
21− , zonedTime
22− ) where
23−
24−import Prelude.Compat
25−
26−import Control.Applicative ((<|>))
27−import Control.Monad (void, when)
28−import Data.Attoparsec.Text as A
29−import Data.Attoparsec.Time.Internal (toPico)
30−import Data.Bits ((.&.))
31−import Data.Char (isDigit, ord)
32−import Data.Fixed (Pico)
33−import Data.Int (Int64)
34−import Data.Maybe (fromMaybe)
35−import Data.Time.Calendar (Day, fromGregorianValid)
36−import Data.Time.Clock (UTCTime(..))
37−import qualified Data.Text as T
38−import qualified Data.Time.LocalTime as Local
39−
40−-- | Parse a date of the form @[+,-]YYYY-MM-DD@.
41−day :: Parser Day
42−day = do
43− absOrNeg <- negate <$ char '-' <|> id <$ char '+' <|> pure id
44− y <- (decimal <* char '-') <|> fail "date must be of form [+,-]YYYY-MM-DD"
45− m <- (twoDigits <* char '-') <|> fail "date must be of form [+,-]YYYY-MM-DD"
46− d <- twoDigits <|> fail "date must be of form [+,-]YYYY-MM-DD"
47− maybe (fail "invalid date") return (fromGregorianValid (absOrNeg y) m d)
48−
49−-- | Parse a two-digit integer (e.g. day of month, hour).
50−twoDigits :: Parser Int
51−twoDigits = do
52− a <- digit
53− b <- digit
54− let c2d c = ord c .&. 15
55− return $! c2d a * 10 + c2d b
56−
57−-- | Parse a time of the form @HH:MM[:SS[.SSS]]@.
58−timeOfDay :: Parser Local.TimeOfDay
59−timeOfDay = do
60− h <- twoDigits
61− m <- char ':' *> twoDigits
62− s <- option 0 (char ':' *> seconds)
63− if h < 24 && m < 60 && s < 61
64− then return (Local.TimeOfDay h m s)
65− else fail "invalid time"
66−
67−data T = T {-# UNPACK #-} !Int {-# UNPACK #-} !Int64
68−
69−-- | Parse a count of seconds, with the integer part being two digits
70−-- long.
71−seconds :: Parser Pico
72−seconds = do
73− real <- twoDigits
74− mc <- peekChar
75− case mc of
76− Just '.' -> do
77− t <- anyChar *> takeWhile1 isDigit
78− return $! parsePicos real t
79− _ -> return $! fromIntegral real
80− where
81− parsePicos a0 t = toPico (fromIntegral (t' * 10^n))
82− where T n t' = T.foldl' step (T 12 (fromIntegral a0)) t
83− step ma@(T m a) c
84− | m <= 0 = ma
85− | otherwise = T (m-1) (10 * a + fromIntegral (ord c) .&. 15)
86−
87−-- | Parse a time zone, and return 'Nothing' if the offset from UTC is
88−-- zero. (This makes some speedups possible.)
89−timeZone :: Parser (Maybe Local.TimeZone)
90−timeZone = do
91− let maybeSkip c = do ch <- peekChar'; when (ch == c) (void anyChar)
92− maybeSkip ' '
93− ch <- satisfy $ \c -> c == 'Z' || c == '+' || c == '-'
94− if ch == 'Z'
95− then return Nothing
96− else do
97− h <- twoDigits
98− mm <- peekChar
99− m <- case mm of
100− Just ':' -> anyChar *> twoDigits
101− Just d | isDigit d -> twoDigits
102− _ -> return 0
103− let off | ch == '-' = negate off0
104− | otherwise = off0
105− off0 = h * 60 + m
106− case undefined of
107− _ | off == 0 ->
108− return Nothing
109− | off < -720 || off > 840 || m > 59 ->
110− fail "invalid time zone offset"
111− | otherwise ->
112− let !tz = Local.minutesToTimeZone off
113− in return (Just tz)
114−
115−-- | Parse a date and time, of the form @YYYY-MM-DD HH:MM[:SS[.SSS]]@.
116−-- The space may be replaced with a @T@. The number of seconds is optional
117−-- and may be followed by a fractional component.
118−localTime :: Parser Local.LocalTime
119−localTime = Local.LocalTime <$> day <* daySep <*> timeOfDay
120− where daySep = satisfy (\c -> c == 'T' || c == ' ')
121−
122−-- | Behaves as 'zonedTime', but converts any time zone offset into a
123−-- UTC time.
124−utcTime :: Parser UTCTime
125−utcTime = do
126− lt@(Local.LocalTime d t) <- localTime
127− mtz <- timeZone
128− case mtz of
129− Nothing -> let !tt = Local.timeOfDayToTime t
130− in return (UTCTime d tt)
131− Just tz -> return $! Local.localTimeToUTC tz lt
132−
133−-- | Parse a date with time zone info. Acceptable formats:
134−--
135−-- @YYYY-MM-DD HH:MM Z@
136−-- @YYYY-MM-DD HH:MM:SS Z@
137−-- @YYYY-MM-DD HH:MM:SS.SSS Z@
138−--
139−-- The first space may instead be a @T@, and the second space is
140−-- optional. The @Z@ represents UTC. The @Z@ may be replaced with a
141−-- time zone offset of the form @+0000@ or @-08:00@, where the first
142−-- two digits are hours, the @:@ is optional and the second two digits
143−-- (also optional) are minutes.
144−zonedTime :: Parser Local.ZonedTime
145−zonedTime = Local.ZonedTime <$> localTime <*> (fromMaybe utc <$> timeZone)
146−
147−utc :: Local.TimeZone
148−utc = Local.TimeZone 0 False ""
attoparsec-iso8601/Data/Attoparsec/Time/Internal.hsdeleted−64
@@ -1,64 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
3−-- |
4−-- Module: Data.Aeson.Internal.Time
5−-- Copyright: (c) 2015-2016 Bryan O'Sullivan
6−-- License: BSD3
7−-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>
8−-- Stability: experimental
9−-- Portability: portable
10−
11−module Data.Attoparsec.Time.Internal
12− (
13− TimeOfDay64(..)
14− , fromPico
15− , toPico
16− , diffTimeOfDay64
17− , toTimeOfDay64
18− ) where
19−
20−import Prelude.Compat
21−
22−import Data.Int (Int64)
23−import Data.Time
24−import Unsafe.Coerce (unsafeCoerce)
25−
26−#if MIN_VERSION_time(1,6,0)
27−
28−import Data.Time.Clock (diffTimeToPicoseconds)
29−
30−#endif
31−
32−import Data.Fixed (Pico, Fixed(MkFixed))
33−
34−#if !MIN_VERSION_time(1,6,0)
35−
36−diffTimeToPicoseconds :: DiffTime -> Integer
37−diffTimeToPicoseconds = unsafeCoerce
38−
39−#endif
40−
41−toPico :: Integer -> Pico
42−toPico = MkFixed
43−
44−fromPico :: Pico -> Integer
45−fromPico (MkFixed i) = i
46−
47−-- | Like TimeOfDay, but using a fixed-width integer for seconds.
48−data TimeOfDay64 = TOD {-# UNPACK #-} !Int
49− {-# UNPACK #-} !Int
50− {-# UNPACK #-} !Int64
51−
52−posixDayLength :: DiffTime
53−posixDayLength = 86400
54−
55−diffTimeOfDay64 :: DiffTime -> TimeOfDay64
56−diffTimeOfDay64 t
57− | t >= posixDayLength = TOD 23 59 (60000000000000 + pico (t - posixDayLength))
58− | otherwise = TOD (fromIntegral h) (fromIntegral m) s
59− where (h,mp) = pico t `quotRem` 3600000000000000
60− (m,s) = mp `quotRem` 60000000000000
61− pico = fromIntegral . diffTimeToPicoseconds
62−
63−toTimeOfDay64 :: TimeOfDay -> TimeOfDay64
64−toTimeOfDay64 (TimeOfDay h m s) = TOD h m (fromIntegral (fromPico s))
attoparsec-iso8601/LICENSEdeleted−30
@@ -1,30 +0,0 @@
1−Copyright (c) 2011, MailRank, Inc.
2−
3−All rights reserved.
4−
5−Redistribution and use in source and binary forms, with or without
6−modification, are permitted provided that the following conditions
7−are met:
8−
9−1. Redistributions of source code must retain the above copyright
10− notice, this list of conditions and the following disclaimer.
11−
12−2. Redistributions in binary form must reproduce the above copyright
13− notice, this list of conditions and the following disclaimer in the
14− documentation and/or other materials provided with the distribution.
15−
16−3. Neither the name of the author nor the names of his contributors
17− may be used to endorse or promote products derived from this software
18− without specific prior written permission.
19−
20−THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
21−OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22−WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23−DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
24−ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25−DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26−OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27−HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28−STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29−ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30−POSSIBILITY OF SUCH DAMAGE.
attoparsec-iso8601/README.mddeleted−19
@@ -1,19 +0,0 @@
1−Parsing of ISO 8601 dates.
2−
3−This package is used to parse dates in aeson. It is split into a
4−separate package to be shared by other projects that want to parse
5−dates like aeson does.
6−
7−For now, this project is located in the aeson repository and aeson
8−itself uses the source of this package without pulling in the package
9−as a dependency.
10−
11−## Stability
12−
13−Since aeson depends on this package we want to be very careful about
14−changing the format.
15−
16−There may be breaking changes if we find that the format is
17−incorrectly too lenient. We consider widening of the allowed input a
18−non-breaking addition since all previously valid input will still
19−parse correctly.
attoparsec-iso8601/attoparsec-iso8601.cabaldeleted−55
@@ -1,55 +0,0 @@
1−name: attoparsec-iso8601
2−version: 1.0.1.0
3−synopsis: Parsing of ISO 8601 dates, originally from aeson.
4−description: Parsing of ISO 8601 dates, originally from aeson.
5−license: BSD3
6−license-file: LICENSE
7−category: Parsing
8−copyright: (c) 2011-2016 Bryan O'Sullivan
9− (c) 2011 MailRank, Inc.
10−author: Bryan O'Sullivan <bos@serpentine.com>
11−maintainer: Adam Bergmark <adam@bergmark.nl>
12−stability: experimental
13−cabal-version: >=1.10
14−homepage: https://github.com/bos/aeson
15−bug-reports: https://github.com/bos/aeson/issues
16−build-type: Simple
17−extra-source-files:
18− README.md
19−
20−flag developer
21− description: operate in developer mode
22− default: False
23− manual: True
24−
25−flag fast
26− description: compile without optimizations
27− default: False
28− manual: True
29−
30−library
31− hs-source-dirs: .
32− default-language: Haskell2010
33− ghc-options: -Wall
34− exposed-modules:
35− Data.Attoparsec.Time.Internal
36− Data.Attoparsec.Time
37− build-depends:
38− attoparsec >= 0.13.0.1,
39− base >= 4.7 && < 5,
40− base-compat >= 0.9.1 && < 0.12,
41− text >= 1.1.1.0,
42− time >= 1.1.1.4
43−
44− if flag(fast)
45− ghc-options: -O0
46− else
47− ghc-options: -O2
48−
49− if flag(developer)
50− ghc-options: -Werror
51− ghc-prof-options: -auto-all
52−
53−source-repository head
54− type: git
55− location: git://github.com/bos/aeson.git
attoparsec-iso8601/changelog.mddeleted−5
@@ -1,5 +0,0 @@
1−For the latest version of this document, please see [https://github.com/bos/aeson/blob/master/attoparsec-iso8601/changelog.md](https://github.com/bos/aeson/blob/master/attoparsec-iso8601/changelog.md).
2−
3−### 1.0.1.0
4−
5−* Fixes handling of `UTCTime` wrt. leap seconds , thanks to Adam Schønemann
benchmarks/AesonCompareAutoInstances.hsnew file+229
@@ -0,0 +1,229 @@
1+{-# LANGUAGE DeriveDataTypeable #-}
2+{-# LANGUAGE DeriveGeneric #-}
3+{-# LANGUAGE TemplateHaskell #-}
4+
5+module Main (main) where
6+
7+import Prelude ()
8+import Prelude.Compat
9+
10+import Control.DeepSeq (NFData, rnf, deepseq)
11+import Criterion.Main hiding (defaultOptions)
12+import Data.Aeson.Encode
13+import Data.Aeson.TH
14+import Data.Aeson.Types
15+import Data.Data (Data)
16+import Data.Typeable (Typeable)
17+import GHC.Generics (Generic)
18+import Options
19+import qualified Data.Aeson.Generic as G (fromJSON, toJSON)
20+
21+--------------------------------------------------------------------------------
22+
23+data D a = Nullary
24+ | Unary Int
25+ | Product String Char a
26+ | Record { testOne :: Double
27+ , testTwo :: Bool
28+ , testThree :: D a
29+ }
30+ deriving (Show, Eq, Data, Typeable)
31+
32+deriveJSON opts ''D
33+
34+instance NFData a => NFData (D a) where
35+ rnf Nullary = ()
36+ rnf (Unary n) = rnf n
37+ rnf (Product s c x) = s `deepseq` c `deepseq` rnf x
38+ rnf (Record d b y) = d `deepseq` b `deepseq` rnf y
39+
40+type T = D (D (D ()))
41+
42+d :: T
43+d = Record
44+ { testOne = 1234.56789
45+ , testTwo = True
46+ , testThree = Product "Hello World!" 'a' $
47+ Record
48+ { testOne = 9876.54321
49+ , testTwo = False
50+ , testThree = Product "Yeehaa!!!" '\n' Nullary
51+ }
52+ }
53+
54+--------------------------------------------------------------------------------
55+
56+data D' a = Nullary'
57+ | Unary' Int
58+ | Product' String Char a
59+ | Record' { testOne' :: Double
60+ , testTwo' :: Bool
61+ , testThree' :: D' a
62+ }
63+ deriving (Show, Eq, Generic, Data, Typeable)
64+
65+instance ToJSON a => ToJSON (D' a) where
66+ toJSON = genericToJSON opts
67+
68+instance FromJSON a => FromJSON (D' a) where
69+ parseJSON = genericParseJSON opts
70+
71+instance NFData a => NFData (D' a) where
72+ rnf Nullary' = ()
73+ rnf (Unary' n) = rnf n
74+ rnf (Product' s c x) = s `deepseq` c `deepseq` rnf x
75+ rnf (Record' d b y) = d `deepseq` b `deepseq` rnf y
76+
77+type T' = D' (D' (D' ()))
78+
79+d' :: T'
80+d' = Record'
81+ { testOne' = 1234.56789
82+ , testTwo' = True
83+ , testThree' = Product' "Hello World!" 'a' $
84+ Record'
85+ { testOne' = 9876.54321
86+ , testTwo' = False
87+ , testThree' = Product' "Yeehaa!!!" '\n' Nullary'
88+ }
89+ }
90+
91+--------------------------------------------------------------------------------
92+
93+data BigRecord = BigRecord
94+ { field01 :: !Int, field02 :: !Int, field03 :: !Int, field04 :: !Int, field05 :: !Int
95+ , field06 :: !Int, field07 :: !Int, field08 :: !Int, field09 :: !Int, field10 :: !Int
96+ , field11 :: !Int, field12 :: !Int, field13 :: !Int, field14 :: !Int, field15 :: !Int
97+ , field16 :: !Int, field17 :: !Int, field18 :: !Int, field19 :: !Int, field20 :: !Int
98+ , field21 :: !Int, field22 :: !Int, field23 :: !Int, field24 :: !Int, field25 :: !Int
99+ } deriving (Show, Eq, Generic, Data, Typeable)
100+
101+instance NFData BigRecord
102+
103+bigRecord = BigRecord 1 2 3 4 5
104+ 6 7 8 9 10
105+ 11 12 13 14 15
106+ 16 17 18 19 20
107+ 21 22 23 24 25
108+
109+gBigRecordToJSON :: BigRecord -> Value
110+gBigRecordToJSON = genericToJSON opts
111+
112+gBigRecordFromJSON :: Value -> Result BigRecord
113+gBigRecordFromJSON = parse $ genericParseJSON opts
114+
115+thBigRecordToJSON :: BigRecord -> Value
116+thBigRecordToJSON = $(mkToJSON opts ''BigRecord)
117+
118+thBigRecordFromJSON :: Value -> Result BigRecord
119+thBigRecordFromJSON = parse $(mkParseJSON opts ''BigRecord)
120+
121+--------------------------------------------------------------------------------
122+
123+data BigProduct = BigProduct
124+ !Int !Int !Int !Int !Int
125+ !Int !Int !Int !Int !Int
126+ !Int !Int !Int !Int !Int
127+ !Int !Int !Int !Int !Int
128+ !Int !Int !Int !Int !Int
129+ deriving (Show, Eq, Generic, Data, Typeable)
130+
131+instance NFData BigProduct
132+
133+bigProduct = BigProduct 1 2 3 4 5
134+ 6 7 8 9 10
135+ 11 12 13 14 15
136+ 16 17 18 19 20
137+ 21 22 23 24 25
138+
139+gBigProductToJSON :: BigProduct -> Value
140+gBigProductToJSON = genericToJSON opts
141+
142+gBigProductFromJSON :: Value -> Result BigProduct
143+gBigProductFromJSON = parse $ genericParseJSON opts
144+
145+thBigProductToJSON :: BigProduct -> Value
146+thBigProductToJSON = $(mkToJSON opts ''BigProduct)
147+
148+thBigProductFromJSON :: Value -> Result BigProduct
149+thBigProductFromJSON = parse $(mkParseJSON opts ''BigProduct)
150+
151+--------------------------------------------------------------------------------
152+
153+data BigSum = F01 | F02 | F03 | F04 | F05
154+ | F06 | F07 | F08 | F09 | F10
155+ | F11 | F12 | F13 | F14 | F15
156+ | F16 | F17 | F18 | F19 | F20
157+ | F21 | F22 | F23 | F24 | F25
158+ deriving (Show, Eq, Generic, Data, Typeable)
159+
160+instance NFData BigSum
161+
162+bigSum = F25
163+
164+gBigSumToJSON :: BigSum -> Value
165+gBigSumToJSON = genericToJSON opts
166+
167+gBigSumFromJSON :: Value -> Result BigSum
168+gBigSumFromJSON = parse $ genericParseJSON opts
169+
170+thBigSumToJSON :: BigSum -> Value
171+thBigSumToJSON = $(mkToJSON opts ''BigSum)
172+
173+thBigSumFromJSON :: Value -> Result BigSum
174+thBigSumFromJSON = parse $(mkParseJSON opts ''BigSum)
175+
176+--------------------------------------------------------------------------------
177+
178+type FJ a = Value -> Result a
179+
180+main :: IO ()
181+main = defaultMain
182+ [ let v = toJSON d
183+ in (d, d', v) `deepseq`
184+ bgroup "D"
185+ [ group "toJSON" (nf toJSON d)
186+ (nf G.toJSON d)
187+ (nf toJSON d')
188+ , group "fromJSON" (nf ( fromJSON :: FJ T ) v)
189+ (nf (G.fromJSON :: FJ T ) v)
190+ (nf ( fromJSON :: FJ T') v)
191+ ]
192+ , let v = thBigRecordToJSON bigRecord
193+ in bigRecord `deepseq` v `deepseq`
194+ bgroup "BigRecord"
195+ [ group "toJSON" (nf thBigRecordToJSON bigRecord)
196+ (nf G.toJSON bigRecord)
197+ (nf gBigRecordToJSON bigRecord)
198+ , group "fromJSON" (nf (thBigRecordFromJSON :: FJ BigRecord) v)
199+ (nf (G.fromJSON :: FJ BigRecord) v)
200+ (nf (gBigRecordFromJSON :: FJ BigRecord) v)
201+ ]
202+ , let v = thBigProductToJSON bigProduct
203+ in bigProduct `deepseq` v `deepseq`
204+ bgroup "BigProduct"
205+ [ group "toJSON" (nf thBigProductToJSON bigProduct)
206+ (nf G.toJSON bigProduct)
207+ (nf gBigProductToJSON bigProduct)
208+ , group "fromJSON" (nf (thBigProductFromJSON :: FJ BigProduct) v)
209+ (nf (G.fromJSON :: FJ BigProduct) v)
210+ (nf (gBigProductFromJSON :: FJ BigProduct) v)
211+ ]
212+ , let v = thBigSumToJSON bigSum
213+ in bigSum `deepseq` v `deepseq`
214+ bgroup "BigSum"
215+ [ group "toJSON" (nf thBigSumToJSON bigSum)
216+ (nf G.toJSON bigSum)
217+ (nf gBigSumToJSON bigSum)
218+ , group "fromJSON" (nf (thBigSumFromJSON :: FJ BigSum) v)
219+ (nf (G.fromJSON :: FJ BigSum) v)
220+ (nf (gBigSumFromJSON :: FJ BigSum) v)
221+ ]
222+ ]
223+
224+group n th syb gen = bcompare
225+ [ bgroup n [ bench "th" th
226+ , bench "syb" syb
227+ , bench "generic" gen
228+ ]
229+ ]
benchmarks/AesonEncode.hs+5−4
@@ -1,13 +1,14 @@
11{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
32{-# LANGUAGE OverloadedStrings #-}
43
54module Main (main) where
65
6+import Prelude ()
77import Prelude.Compat
88
99import Control.DeepSeq
10−import Control.Monad (forM_)
10+import Control.Exception
11+import Control.Monad
1112import Data.Aeson
1213import Data.Attoparsec.ByteString (IResult(..), parseWith)
1314import Data.Char (isDigit)
@@ -24,7 +25,7 @@ main = do
2425 (c:a) -> (c,a)
2526 [] -> error "Unexpected empty list"
2627 let count = read cnt :: Int
27− forM_ args $ \arg -> withFile arg ReadMode $ \h -> do
28+ forM_ args $ \arg -> bracket (openFile arg ReadMode) hClose $ \h -> do
2829 putStrLn $ arg ++ ":"
2930 let refill = B.hGet h 16384
3031 result0 <- parseWith refill json =<< refill
@@ -34,7 +35,7 @@ main = do
3435 start <- getCurrentTime
3536 let loop !n r
3637 | n >= count = return ()
37− | otherwise = {-# SCC "loop" #-}
38+ | otherwise = {-# SCC "loop" #-} do
3839 rnf (encode r) `seq` loop (n+1) r
3940 loop 0 r0
4041 delta <- flip diffUTCTime start `fmap` getCurrentTime
benchmarks/AesonFoldable.hs+42−14
@@ -1,14 +1,16 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE PackageImports #-}
33
44module Main (main) where
55
66import Criterion.Main
77
8+import Prelude ()
89import Prelude.Compat
910
1011import Data.Foldable (toList)
11−import qualified Data.Aeson as A
12+import qualified "aeson" Data.Aeson as A
13+import qualified "aeson-benchmarks" Data.Aeson as B
1214import qualified Data.Sequence as S
1315import qualified Data.Vector as V
1416import qualified Data.Vector.Unboxed as U
@@ -19,6 +21,10 @@ import qualified Data.Vector.Unboxed as U
1921
2022newtype L f = L { getL :: f Int }
2123
24+instance Foldable f => B.ToJSON (L f) where
25+ toJSON = error "do not use this"
26+ toEncoding = B.toEncoding . toList . getL
27+
2228instance Foldable f => A.ToJSON (L f) where
2329 toJSON = error "do not use this"
2430 toEncoding = A.toEncoding . toList . getL
@@ -29,6 +35,10 @@ instance Foldable f => A.ToJSON (L f) where
2935
3036newtype F f = F { getF :: f Int }
3137
38+instance Foldable f => B.ToJSON (F f) where
39+ toJSON = error "do not use this"
40+ toEncoding = B.foldable . getF
41+
3242instance Foldable f => A.ToJSON (F f) where
3343 toJSON = error "do not use this"
3444 toEncoding = A.foldable . getF
@@ -53,34 +63,52 @@ valueUVector = U.fromList valueList
5363-- Main
5464-------------------------------------------------------------------------------
5565
56−benchEncode
66+benchEncodeA
5767 :: A.ToJSON a
5868 => String
5969 -> a
6070 -> Benchmark
61−benchEncode name val
71+benchEncodeA name val
6272 = bench ("A " ++ name) $ nf A.encode val
6373
74+benchEncodeB
75+ :: B.ToJSON a
76+ => String
77+ -> a
78+ -> Benchmark
79+benchEncodeB name val
80+ = bench ("B " ++ name) $ nf B.encode val
81+
6482main :: IO ()
6583main = defaultMain
6684 [ bgroup "encode"
6785 [ bgroup "List"
68− [ benchEncode "-" valueList
69− , benchEncode "L" $ L valueList
70− , benchEncode "F" $ F valueList
86+ [ benchEncodeB "-" valueList
87+ , benchEncodeB "L" $ L valueList
88+ , benchEncodeB "F" $ F valueList
89+ , benchEncodeA "-" valueList
90+ , benchEncodeA "L" $ L valueList
91+ , benchEncodeA "F" $ F valueList
7192 ]
7293 , bgroup "Seq"
73− [ benchEncode "-" valueSeq
74− , benchEncode "L" $ L valueSeq
75− , benchEncode "F" $ F valueSeq
94+ [ benchEncodeB "-" valueSeq
95+ , benchEncodeB "L" $ L valueSeq
96+ , benchEncodeB "F" $ F valueSeq
97+ , benchEncodeA "-" valueSeq
98+ , benchEncodeA "L" $ L valueSeq
99+ , benchEncodeA "F" $ F valueSeq
76100 ]
77101 , bgroup "Vector"
78− [ benchEncode "-" valueVector
79− , benchEncode "L" $ L valueVector
80− , benchEncode "F" $ F valueVector
102+ [ benchEncodeB "-" valueVector
103+ , benchEncodeB "L" $ L valueVector
104+ , benchEncodeB "F" $ F valueVector
105+ , benchEncodeA "-" valueVector
106+ , benchEncodeA "L" $ L valueVector
107+ , benchEncodeA "F" $ F valueVector
81108 ]
82109 , bgroup "Vector.Unboxed"
83− [ benchEncode "-" valueUVector
110+ [ benchEncodeB "-" valueUVector
111+ , benchEncodeA "-" valueUVector
84112 ]
85113 ]
86114 ]
benchmarks/AesonMap.hs+56−39
@@ -1,11 +1,13 @@
11{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE PackageImports #-}
34{-# LANGUAGE RankNTypes #-}
45
56{-# OPTIONS_GHC -fno-warn-orphans #-}
67
78module Main (main) where
89
10+import Prelude ()
911import Prelude.Compat
1012
1113import Control.DeepSeq
@@ -13,8 +15,9 @@ import Criterion.Main
1315import Data.Hashable
1416import Data.Proxy (Proxy (..))
1517import Data.Tagged (Tagged (..))
16−import Data.Aeson
17−import Data.Aeson.Types (fromJSONKeyCoerce)
18+import qualified "aeson" Data.Aeson as A
19+import qualified "aeson-benchmarks" Data.Aeson as B
20+import qualified "aeson-benchmarks" Data.Aeson.Types as B (fromJSONKeyCoerce)
1821import qualified Data.ByteString.Lazy as LBS
1922import qualified Data.HashMap.Strict as HM
2023import qualified Data.Map as M
@@ -44,10 +47,10 @@ instance NFData T1 where
4447instance Hashable T1 where
4548 hashWithSalt salt (T1 t) = hashWithSalt salt t
4649
47−instance FromJSON T1 where
48− parseJSON = withText "T1" $ pure . T1
49−instance FromJSONKey T1 where
50− fromJSONKey = FromJSONKeyText T1
50+instance B.FromJSON T1 where
51+ parseJSON = B.withText "T1" $ pure . T1
52+instance B.FromJSONKey T1 where
53+ fromJSONKey = B.FromJSONKeyText T1
5154
5255-------------------------------------------------------------------------------
5356-- Coerce
@@ -61,10 +64,10 @@ instance NFData T2 where
6164instance Hashable T2 where
6265 hashWithSalt salt (T2 t) = hashWithSalt salt t
6366
64−instance FromJSON T2 where
65− parseJSON = withText "T2" $ pure . T2
66−instance FromJSONKey T2 where
67− fromJSONKey = fromJSONKeyCoerce
67+instance B.FromJSON T2 where
68+ parseJSON = B.withText "T2" $ pure . T2
69+instance B.FromJSONKey T2 where
70+ fromJSONKey = B.fromJSONKeyCoerce
6871
6972-------------------------------------------------------------------------------
7073-- TextParser
@@ -78,10 +81,10 @@ instance NFData T3 where
7881instance Hashable T3 where
7982 hashWithSalt salt (T3 t) = hashWithSalt salt t
8083
81−instance FromJSON T3 where
82− parseJSON = withText "T3" $ pure . T3
83−instance FromJSONKey T3 where
84− fromJSONKey = FromJSONKeyTextParser (pure . T3)
84+instance B.FromJSON T3 where
85+ parseJSON = B.withText "T3" $ pure . T3
86+instance B.FromJSONKey T3 where
87+ fromJSONKey = B.FromJSONKeyTextParser (pure . T3)
8588
8689-------------------------------------------------------------------------------
8790-- Values
@@ -94,30 +97,40 @@ value1000 = value 1000
9497value10000 = value 10000
9598
9699encodedValue10 :: LBS.ByteString
97−encodedValue10 = encode value10
100+encodedValue10 = B.encode $ value10
98101
99102encodedValue100 :: LBS.ByteString
100−encodedValue100 = encode value100
103+encodedValue100 = B.encode $ value100
101104
102105encodedValue1000 :: LBS.ByteString
103−encodedValue1000 = encode value1000
106+encodedValue1000 = B.encode $ value1000
104107
105108encodedValue10000 :: LBS.ByteString
106−encodedValue10000 = encode value10000
109+encodedValue10000 = B.encode $ value10000
107110
108111-------------------------------------------------------------------------------
109112-- Helpers
110113-------------------------------------------------------------------------------
111114
112−decodeHM
113− :: (FromJSON (HM.HashMap k T.Text), Eq k, Hashable k)
115+decodeHMB
116+ :: (B.FromJSONKey k, Eq k, Hashable k)
114117 => Proxy k -> LBS.ByteString -> Maybe (HM.HashMap k T.Text)
115−decodeHM _ = decode
118+decodeHMB _ = B.decode
116119
117−decodeMap
118− :: (FromJSON (M.Map k T.Text), Ord k)
120+decodeHMA
121+ :: (A.FromJSON (HM.HashMap k T.Text), Eq k, Hashable k)
122+ => Proxy k -> LBS.ByteString -> Maybe (HM.HashMap k T.Text)
123+decodeHMA _ = A.decode
124+
125+decodeMapB
126+ :: (B.FromJSONKey k, Ord k)
127+ => Proxy k -> LBS.ByteString -> Maybe (M.Map k T.Text)
128+decodeMapB _ = B.decode
129+
130+decodeMapA
131+ :: (A.FromJSON (M.Map k T.Text), Ord k)
119132 => Proxy k -> LBS.ByteString -> Maybe (M.Map k T.Text)
120−decodeMap _ = decode
133+decodeMapA _ = A.decode
121134
122135proxyText :: Proxy T.Text
123136proxyText = Proxy
@@ -143,14 +156,15 @@ benchDecodeHM
143156 -> LBS.ByteString
144157 -> Benchmark
145158benchDecodeHM name val = bgroup name
146− [ bench "Text" $ nf (decodeHM proxyText) val
147− , bench "Identity" $ nf (decodeHM proxyT1) val
148− , bench "Coerce" $ nf (decodeHM proxyT2) val
149− , bench "Parser" $ nf (decodeHM proxyT3) val
150− , bench "Tagged Text" $ nf (decodeHM $ proxyTagged proxyText) val
151− , bench "Tagged Identity" $ nf (decodeHM $ proxyTagged proxyT1) val
152− , bench "Tagged Coerce" $ nf (decodeHM $ proxyTagged proxyT2) val
153− , bench "Tagged Parser" $ nf (decodeHM $ proxyTagged proxyT3) val
159+ [ bench "Text" $ nf (decodeHMB proxyText) val
160+ , bench "Identity" $ nf (decodeHMB proxyT1) val
161+ , bench "Coerce" $ nf (decodeHMB proxyT2) val
162+ , bench "Parser" $ nf (decodeHMB proxyT3) val
163+ , bench "aeson-0.11" $ nf (decodeHMA proxyText) val
164+ , bench "Tagged Text" $ nf (decodeHMB $ proxyTagged proxyText) val
165+ , bench "Tagged Identity" $ nf (decodeHMB $ proxyTagged proxyT1) val
166+ , bench "Tagged Coerce" $ nf (decodeHMB $ proxyTagged proxyT2) val
167+ , bench "Tagged Parser" $ nf (decodeHMB $ proxyTagged proxyT3) val
154168 ]
155169
156170benchDecodeMap
@@ -158,10 +172,11 @@ benchDecodeMap
158172 -> LBS.ByteString
159173 -> Benchmark
160174benchDecodeMap name val = bgroup name
161− [ bench "Text" $ nf (decodeMap proxyText) val
162− , bench "Identity" $ nf (decodeMap proxyT1) val
163− , bench "Coerce" $ nf (decodeMap proxyT2) val
164− , bench "Parser" $ nf (decodeMap proxyT3) val
175+ [ bench "Text" $ nf (decodeMapB proxyText) val
176+ , bench "Identity" $ nf (decodeMapB proxyT1) val
177+ , bench "Coerce" $ nf (decodeMapB proxyT2) val
178+ , bench "Parser" $ nf (decodeMapB proxyT3) val
179+ , bench "aeson-0.11" $ nf (decodeMapA proxyText) val
165180 ]
166181
167182benchEncodeHM
@@ -169,7 +184,8 @@ benchEncodeHM
169184 -> HM.HashMap T.Text T.Text
170185 -> Benchmark
171186benchEncodeHM name val = bgroup name
172− [ bench "Text" $ nf encode val
187+ [ bench "Text" $ nf B.encode val
188+ , bench "aeson-0.11" $ nf A.encode val
173189 ]
174190
175191benchEncodeMap
@@ -177,7 +193,8 @@ benchEncodeMap
177193 -> HM.HashMap T.Text T.Text
178194 -> Benchmark
179195benchEncodeMap name val = bgroup name
180− [ bench "Text" $ nf encode val'
196+ [ bench "Text" $ nf B.encode val'
197+ , bench "aeson-0.11" $ nf A.encode val'
181198 ]
182199 where
183200 val' :: M.Map T.Text T.Text
benchmarks/AesonParse.hs+5−3
@@ -1,12 +1,14 @@
11{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
32{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE PackageImports #-}
44
55module Main (main) where
66
7+import Prelude ()
78import Prelude.Compat
89
9−import Data.Aeson
10+import "aeson-benchmarks" Data.Aeson
11+import Control.Exception
1012import Control.Monad
1113import Data.Attoparsec.ByteString (IResult(..), parseWith)
1214import Data.Time.Clock
@@ -19,7 +21,7 @@ main = do
1921 (bs:cnt:args) <- getArgs
2022 let count = read cnt :: Int
2123 blkSize = read bs
22− forM_ args $ \arg -> withFile arg ReadMode $ \h -> do
24+ forM_ args $ \arg -> bracket (openFile arg ReadMode) hClose $ \h -> do
2325 putStrLn $ arg ++ ":"
2426 start <- getCurrentTime
2527 let loop !good !bad
benchmarks/AesonTuples.hs+2−1
@@ -1,7 +1,8 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
1+module Main where
22
33module Main (main) where
44
5+import Prelude ()
56import Prelude.Compat
67
78import Control.DeepSeq (deepseq)
benchmarks/Auto/G/BigProduct.hsdeleted−33
@@ -1,33 +0,0 @@
1−{-# LANGUAGE DeriveGeneric #-}
2−
3−module Auto.G.BigProduct where
4−
5−import Control.DeepSeq
6−import Data.Aeson
7−import GHC.Generics (Generic)
8−import Options
9−
10−data BigProduct = BigProduct
11− !Int !Int !Int !Int !Int
12− !Int !Int !Int !Int !Int
13− !Int !Int !Int !Int !Int
14− !Int !Int !Int !Int !Int
15− !Int !Int !Int !Int !Int
16− deriving (Show, Eq, Generic)
17−
18−instance NFData BigProduct where
19− rnf a = a `seq` ()
20−
21−instance ToJSON BigProduct where
22− toJSON = genericToJSON opts
23− toEncoding = genericToEncoding opts
24−
25−instance FromJSON BigProduct where
26− parseJSON = genericParseJSON opts
27−
28−bigProduct :: BigProduct
29−bigProduct = BigProduct 1 2 3 4 5
30− 6 7 8 9 10
31− 11 12 13 14 15
32− 16 17 18 19 20
33− 21 22 23 24 25
benchmarks/Auto/G/BigRecord.hsdeleted−33
@@ -1,33 +0,0 @@
1−{-# LANGUAGE DeriveGeneric #-}
2−
3−module Auto.G.BigRecord where
4−
5−import Control.DeepSeq
6−import Data.Aeson
7−import GHC.Generics (Generic)
8−import Options
9−
10−data BigRecord = BigRecord
11− { field01 :: !Int, field02 :: !Int, field03 :: !Int, field04 :: !Int, field05 :: !Int
12− , field06 :: !Int, field07 :: !Int, field08 :: !Int, field09 :: !Int, field10 :: !Int
13− , field11 :: !Int, field12 :: !Int, field13 :: !Int, field14 :: !Int, field15 :: !Int
14− , field16 :: !Int, field17 :: !Int, field18 :: !Int, field19 :: !Int, field20 :: !Int
15− , field21 :: !Int, field22 :: !Int, field23 :: !Int, field24 :: !Int, field25 :: !Int
16− } deriving (Show, Eq, Generic)
17−
18−instance NFData BigRecord where
19− rnf a = a `seq` ()
20−
21−instance ToJSON BigRecord where
22− toJSON = genericToJSON opts
23− toEncoding = genericToEncoding opts
24−
25−instance FromJSON BigRecord where
26− parseJSON = genericParseJSON opts
27−
28−bigRecord :: BigRecord
29−bigRecord = BigRecord 1 2 3 4 5
30− 6 7 8 9 10
31− 11 12 13 14 15
32− 16 17 18 19 20
33− 21 22 23 24 25
benchmarks/Auto/G/BigSum.hsdeleted−28
@@ -1,28 +0,0 @@
1−{-# LANGUAGE DeriveGeneric #-}
2−
3−module Auto.G.BigSum where
4−
5−import Control.DeepSeq
6−import Data.Aeson
7−import GHC.Generics (Generic)
8−import Options
9−
10−data BigSum = F01 | F02 | F03 | F04 | F05
11− | F06 | F07 | F08 | F09 | F10
12− | F11 | F12 | F13 | F14 | F15
13− | F16 | F17 | F18 | F19 | F20
14− | F21 | F22 | F23 | F24 | F25
15− deriving (Show, Eq, Generic)
16−
17−instance NFData BigSum where
18− rnf a = a `seq` ()
19−
20−instance ToJSON BigSum where
21− toJSON = genericToJSON opts
22− toEncoding = genericToEncoding opts
23−
24−instance FromJSON BigSum where
25− parseJSON = genericParseJSON opts
26−
27−bigSum :: BigSum
28−bigSum = F25
benchmarks/Auto/G/D.hsdeleted−44
@@ -1,44 +0,0 @@
1−{-# LANGUAGE DeriveGeneric #-}
2−
3−module Auto.G.D where
4−
5−import Control.DeepSeq
6−import Data.Aeson
7−import GHC.Generics (Generic)
8−import Options
9−
10−data D a = Nullary
11− | Unary Int
12− | Product String Char a
13− | Record { testOne :: Double
14− , testTwo :: Bool
15− , testThree :: D a
16− }
17− deriving (Show, Eq, Generic)
18−
19−instance NFData a => NFData (D a) where
20− rnf Nullary = ()
21− rnf (Unary n) = rnf n
22− rnf (Product s c x) = s `deepseq` c `deepseq` rnf x
23− rnf (Record a b y) = a `deepseq` b `deepseq` rnf y
24−
25−instance ToJSON a => ToJSON (D a) where
26− toJSON = genericToJSON opts
27− toEncoding = genericToEncoding opts
28−
29−instance FromJSON a => FromJSON (D a) where
30− parseJSON = genericParseJSON opts
31−
32−type T = D (D (D ()))
33−
34−d :: T
35−d = Record
36− { testOne = 1234.56789
37− , testTwo = True
38− , testThree = Product "Hello World!" 'a'
39− Record
40− { testOne = 9876.54321
41− , testTwo = False
42− , testThree = Product "Yeehaa!!!" '\n' Nullary
43− }
44− }
benchmarks/Auto/T/BigProduct.hsdeleted−27
@@ -1,27 +0,0 @@
1−{-# LANGUAGE TemplateHaskell #-}
2−
3−module Auto.T.BigProduct where
4−
5−import Control.DeepSeq
6−import Data.Aeson.TH
7−import Options
8−
9−data BigProduct = BigProduct
10− !Int !Int !Int !Int !Int
11− !Int !Int !Int !Int !Int
12− !Int !Int !Int !Int !Int
13− !Int !Int !Int !Int !Int
14− !Int !Int !Int !Int !Int
15− deriving (Show, Eq)
16−
17−instance NFData BigProduct where
18− rnf a = a `seq` ()
19−
20−deriveJSON opts ''BigProduct
21−
22−bigProduct :: BigProduct
23−bigProduct = BigProduct 1 2 3 4 5
24− 6 7 8 9 10
25− 11 12 13 14 15
26− 16 17 18 19 20
27− 21 22 23 24 25
benchmarks/Auto/T/BigRecord.hsdeleted−27
@@ -1,27 +0,0 @@
1−{-# LANGUAGE TemplateHaskell #-}
2−
3−module Auto.T.BigRecord where
4−
5−import Control.DeepSeq
6−import Data.Aeson.TH
7−import Options
8−
9−data BigRecord = BigRecord
10− { field01 :: !Int, field02 :: !Int, field03 :: !Int, field04 :: !Int, field05 :: !Int
11− , field06 :: !Int, field07 :: !Int, field08 :: !Int, field09 :: !Int, field10 :: !Int
12− , field11 :: !Int, field12 :: !Int, field13 :: !Int, field14 :: !Int, field15 :: !Int
13− , field16 :: !Int, field17 :: !Int, field18 :: !Int, field19 :: !Int, field20 :: !Int
14− , field21 :: !Int, field22 :: !Int, field23 :: !Int, field24 :: !Int, field25 :: !Int
15− } deriving (Show, Eq)
16−
17−instance NFData BigRecord where
18− rnf a = a `seq` ()
19−
20−deriveJSON opts ''BigRecord
21−
22−bigRecord :: BigRecord
23−bigRecord = BigRecord 1 2 3 4 5
24− 6 7 8 9 10
25− 11 12 13 14 15
26− 16 17 18 19 20
27− 21 22 23 24 25
benchmarks/Auto/T/BigSum.hsdeleted−22
@@ -1,22 +0,0 @@
1−{-# LANGUAGE TemplateHaskell #-}
2−
3−module Auto.T.BigSum where
4−
5−import Control.DeepSeq
6−import Data.Aeson.TH
7−import Options
8−
9−data BigSum = F01 | F02 | F03 | F04 | F05
10− | F06 | F07 | F08 | F09 | F10
11− | F11 | F12 | F13 | F14 | F15
12− | F16 | F17 | F18 | F19 | F20
13− | F21 | F22 | F23 | F24 | F25
14− deriving (Show, Eq)
15−
16−instance NFData BigSum where
17− rnf a = a `seq` ()
18−
19−deriveJSON opts ''BigSum
20−
21−bigSum :: BigSum
22−bigSum = F25
benchmarks/Auto/T/D.hsdeleted−38
@@ -1,38 +0,0 @@
1−{-# LANGUAGE TemplateHaskell #-}
2−
3−module Auto.T.D where
4−
5−import Control.DeepSeq
6−import Data.Aeson.TH
7−import Options
8−
9−data D a = Nullary
10− | Unary Int
11− | Product String Char a
12− | Record { testOne :: Double
13− , testTwo :: Bool
14− , testThree :: D a
15− }
16− deriving (Show, Eq)
17−
18−instance NFData a => NFData (D a) where
19− rnf Nullary = ()
20− rnf (Unary n) = rnf n
21− rnf (Product s c x) = s `deepseq` c `deepseq` rnf x
22− rnf (Record a b y) = a `deepseq` b `deepseq` rnf y
23−
24−deriveJSON opts ''D
25−
26−type T = D (D (D ()))
27−
28−d :: T
29−d = Record
30− { testOne = 1234.56789
31− , testTwo = True
32− , testThree = Product "Hello World!" 'a'
33− Record
34− { testOne = 9876.54321
35− , testTwo = False
36− , testThree = Product "Yeehaa!!!" '\n' Nullary
37− }
38− }
benchmarks/AutoCompare.hsdeleted−73
@@ -1,73 +0,0 @@
1−{-# LANGUAGE RankNTypes #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
4−module Main (main) where
5−
6−import Control.DeepSeq
7−import Control.Monad
8−import Criterion.Main
9−import Data.Aeson
10−
11−import qualified Auto.T.D as T
12−import qualified Auto.T.BigRecord as T
13−import qualified Auto.T.BigProduct as T
14−import qualified Auto.T.BigSum as T
15−import qualified Auto.G.D as G
16−import qualified Auto.G.BigRecord as G
17−import qualified Auto.G.BigProduct as G
18−import qualified Auto.G.BigSum as G
19−
20−--------------------------------------------------------------------------------
21−
22−runBench :: IO ()
23−runBench = defaultMain
24− [ compareBench "D" T.d G.d
25− , compareBench "BigRecord" T.bigRecord G.bigRecord
26− , compareBench "BigProduct" T.bigProduct G.bigProduct
27− , compareBench "BigSum" T.bigSum G.bigSum
28− ]
29−
30−group :: String -> Benchmarkable -> Benchmarkable -> Benchmark
31−group n th gen = bgroup n [ bench "th" th
32− , bench "generic" gen
33− ]
34−
35−compareBench
36− :: forall a b
37− . (ToJSON a, FromJSON a, NFData a, ToJSON b, FromJSON b, NFData b)
38− => String -> a -> b -> Benchmark
39−compareBench name a b = v `deepseq` bgroup name
40− [ group "toJSON" (nf toJSON a)
41− (nf toJSON b)
42− , group "encode" (nf encode a)
43− (nf encode b)
44− , group "fromJSON" (nf (fromJSON :: Value -> Result a) v)
45− (nf (fromJSON :: Value -> Result b) v)
46− ] where
47− v = toJSON a -- == toJSON b
48−
49−sanityCheck :: IO ()
50−sanityCheck = do
51− check T.d
52− check G.d
53− check T.bigRecord
54− check G.bigRecord
55− check T.bigProduct
56− check G.bigProduct
57− check T.bigSum
58− check G.bigSum
59−
60−check :: (Show a, Eq a, FromJSON a, ToJSON a)
61− => a -> IO ()
62−check x = do
63− unless (Success x == (fromJSON . toJSON) x) $ fail $ "toJSON: " ++ show x
64− unless (Success x == (decode_ . encode) x) $ fail $ "encode: " ++ show x
65− where
66− decode_ s = case decode s of
67− Just v -> fromJSON v
68− Nothing -> fail ""
69−
70−main :: IO ()
71−main = do
72− sanityCheck
73− runBench
benchmarks/Compare.hs+5−10
@@ -1,25 +1,22 @@
1−{-# LANGUAGE CPP #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
1+{-# LANGUAGE PackageImports #-}
32{-# LANGUAGE ScopedTypeVariables #-}
43
54module Main (main) where
65
6+import Prelude ()
77import Prelude.Compat
88
99import Compare.BufferBuilder ()
10+import Compare.JsonBuilder ()
1011import Criterion.Main
1112import Data.BufferBuilder.Json
13+import Data.Json.Builder
1214import Twitter
1315import Twitter.Manual ()
1416import Typed.Common
15−import qualified Data.Aeson as Aeson
17+import qualified "aeson-benchmarks" Data.Aeson as Aeson
1618import qualified Compare.JsonBench as JsonBench
1719
18−#ifdef MIN_VERSION_json_builder
19−import Data.Json.Builder
20−import Compare.JsonBuilder ()
21−#endif
22−
2320main :: IO ()
2421main =
2522 defaultMain [
@@ -27,9 +24,7 @@ main =
2724 bgroup "twitter" [
2825 bench "aeson" $ nf Aeson.encode twtr
2926 , bench "buffer-builder" $ nf encodeJson twtr
30−#ifdef MIN_VERSION_json_builder
3127 , bench "json-builder" $ nf toJsonLBS twtr
32−#endif
3328 ]
3429 , JsonBench.benchmarks
3530 ]
benchmarks/Compare/BufferBuilder.hs+3−2
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21{-# LANGUAGE OverloadedStrings #-}
32{-# LANGUAGE RecordWildCards #-}
43
@@ -7,11 +6,13 @@
76
87module Compare.BufferBuilder () where
98
10−import Prelude.Compat hiding ((<>))
9+import Prelude ()
10+import Prelude.Compat
1111
1212import Data.BufferBuilder.Json
1313import Data.Int (Int64)
1414import Data.Monoid ((<>))
15+import Prelude hiding (id)
1516import Twitter
1617import qualified Data.BufferBuilder.Utf8 as UB
1718
benchmarks/Compare/JsonBench.hs+10−18
@@ -1,18 +1,18 @@
1−{-# LANGUAGE CPP #-}
1+-- Adapted from a buffer-builder benchmark:
2+--
3+-- https://github.com/chadaustin/buffer-builder/blob/master/test.json
4+
25{-# LANGUAGE BangPatterns #-}
6+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
37{-# LANGUAGE MagicHash #-}
4−{-# LANGUAGE NoImplicitPrelude #-}
58{-# LANGUAGE OverloadedStrings #-}
69{-# LANGUAGE RecordWildCards #-}
710{-# LANGUAGE ScopedTypeVariables #-}
811
9−-- Adapted from a buffer-builder benchmark:
10−--
11−-- https://github.com/chadaustin/buffer-builder/blob/master/test.json
12−
1312module Compare.JsonBench (benchmarks) where
1413
15−import Prelude.Compat hiding ((<>))
14+import Prelude ()
15+import Prelude.Compat
1616
1717import Control.DeepSeq (NFData(..))
1818import Criterion
@@ -20,13 +20,9 @@ import Data.Aeson ((.:))
2020import Data.Monoid ((<>))
2121import Data.Text (Text)
2222import Typed.Common (load)
23−import qualified Control.Monad.Fail as Fail
2423import qualified Data.Aeson as Aeson
2524import qualified Data.BufferBuilder.Json as Json
26−
27−#ifdef MIN_VERSION_json_builder
2825import qualified Data.Json.Builder as JB
29−#endif
3026
3127data EyeColor = Green | Blue | Brown
3228 deriving (Eq, Show)
@@ -69,10 +65,10 @@ instance NFData Gender where rnf !_ = ()
6965instance NFData Fruit where rnf !_ = ()
7066
7167instance NFData Friend where
72− rnf Friend {..} = rnf fId `seq` rnf fName
68+ rnf Friend {..} = (rnf fId) `seq` (rnf fName) `seq` ()
7369
7470instance NFData User where
75− rnf User {..} = rnf uId `seq` rnf uIndex `seq` rnf uGuid `seq` rnf uIsActive `seq` rnf uBalance `seq` rnf uPicture `seq` rnf uAge `seq` rnf uEyeColor `seq` rnf uName `seq` rnf uGender `seq` rnf uCompany `seq` rnf uEmail `seq` rnf uPhone `seq` rnf uAddress `seq` rnf uAbout `seq` rnf uRegistered `seq` rnf uLatitude `seq` rnf uLongitude `seq` rnf uTags `seq` rnf uFriends `seq` rnf uGreeting `seq` rnf uFavouriteFruit
71+ rnf User {..} = (rnf uId) `seq` (rnf uIndex) `seq` (rnf uGuid) `seq` (rnf uIsActive) `seq` (rnf uBalance) `seq` (rnf uPicture) `seq` (rnf uAge) `seq` (rnf uEyeColor) `seq` (rnf uName) `seq` (rnf uGender) `seq` (rnf uCompany) `seq` (rnf uEmail) `seq` (rnf uPhone) `seq` (rnf uAddress) `seq` (rnf uAbout) `seq` (rnf uRegistered) `seq` (rnf uLatitude) `seq` (rnf uLongitude) `seq` (rnf uTags) `seq` (rnf uFriends) `seq` (rnf uGreeting) `seq` (rnf uFavouriteFruit) `seq` ()
7672
7773eyeColorTable :: [(Text, EyeColor)]
7874eyeColorTable = [("brown", Brown), ("green", Green), ("blue", Blue)]
@@ -83,7 +79,7 @@ genderTable = [("male", Male), ("female", Female)]
8379fruitTable :: [(Text, Fruit)]
8480fruitTable = [("apple", Apple), ("strawberry", Strawberry), ("banana", Banana)]
8581
86−enumFromJson :: Fail.MonadFail m => String -> [(Text, enum)] -> (json -> m Text) -> json -> m enum
82+enumFromJson :: Monad m => String -> [(Text, enum)] -> (json -> m Text) -> json -> m enum
8783enumFromJson enumName table extract v = do
8884 s <- extract v
8985 case lookup s table of
@@ -273,7 +269,6 @@ instance Json.ToJson User where
273269 <> "greeting"# Json..=# uGreeting
274270 <> "favoriteFruit"# Json..=# uFavouriteFruit
275271
276−#ifdef MIN_VERSION_json_builder
277272---- json-builder instances ----
278273
279274instance JB.Value EyeColor where
@@ -325,7 +320,6 @@ instance JB.Value User where
325320 <> t "friends" `JB.row` uFriends
326321 <> t "greeting" `JB.row` uGreeting
327322 <> t "favoriteFruit" `JB.row` uFavouriteFruit
328−#endif
329323
330324benchmarks :: Benchmark
331325benchmarks = env (load "json-data/buffer-builder.json") $
@@ -333,7 +327,5 @@ benchmarks = env (load "json-data/buffer-builder.json") $
333327 bgroup "json-bench" [
334328 bench "aeson" $ nf Aeson.encode parsedUserList
335329 , bench "buffer-builder" $ nf Json.encodeJson parsedUserList
336−#ifdef MIN_VERSION_json_builder
337330 , bench "json-builder" $ nf JB.toJsonLBS parsedUserList
338−#endif
339331 ]
benchmarks/Compare/JsonBuilder.hs+3−2
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21{-# LANGUAGE RecordWildCards #-}
32
43{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
@@ -6,10 +5,12 @@
65
76module Compare.JsonBuilder () where
87
9−import Prelude.Compat hiding ((<>))
8+import Prelude ()
9+import Prelude.Compat
1010
1111import Data.Json.Builder
1212import Data.Monoid ((<>))
13+import Prelude hiding (id)
1314import Twitter
1415
1516instance JsObject Metadata where
benchmarks/CompareWithJSON.hs+21−33
@@ -1,20 +1,16 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−
31{-# OPTIONS_GHC -fno-warn-orphans #-}
42
53module Main (main) where
64
5+import Prelude ()
76import Prelude.Compat
87
98import Blaze.ByteString.Builder (toLazyByteString)
109import Blaze.ByteString.Builder.Char.Utf8 (fromString)
1110import Control.DeepSeq (NFData(rnf))
1211import Criterion.Main
13−import Data.Maybe (fromMaybe)
1412import qualified Data.Aeson as A
1513import qualified Data.Aeson.Text as A
16−import qualified Data.Aeson.Parser.Internal as I
17−import qualified Data.ByteString as BS
1814import qualified Data.ByteString.Lazy as BL
1915import qualified Data.Text.Lazy as TL
2016import qualified Data.Text.Lazy.Builder as TLB
@@ -27,7 +23,7 @@ instance (NFData v) => NFData (J.JSObject v) where
2723instance NFData J.JSValue where
2824 rnf J.JSNull = ()
2925 rnf (J.JSBool b) = rnf b
30− rnf (J.JSRational a b) = rnf a `seq` rnf b
26+ rnf (J.JSRational a b) = rnf a `seq` rnf b `seq` ()
3127 rnf (J.JSString s) = rnf (J.fromJSString s)
3228 rnf (J.JSArray lst) = rnf lst
3329 rnf (J.JSObject o) = rnf o
@@ -38,18 +34,15 @@ decodeJ s =
3834 J.Ok v -> v
3935 J.Error _ -> error "fail to parse via JSON"
4036
41−decode :: BL.ByteString -> A.Value
42−decode s = fromMaybe (error "fail to parse via Aeson") $ A.decode s
43−
44−decode' :: BL.ByteString -> A.Value
45−decode' s = fromMaybe (error "fail to parse via Aeson") $ A.decode' s
46−
47−decodeS :: BS.ByteString -> A.Value
48−decodeS s = fromMaybe (error "fail to parse via Aeson") $ A.decodeStrict' s
37+decodeA :: BL.ByteString -> A.Value
38+decodeA s = case A.decode s of
39+ Just v -> v
40+ Nothing -> error "fail to parse via Aeson"
4941
50−decodeIP :: BL.ByteString -> A.Value
51−decodeIP s = fromMaybe (error "fail to parse via Parser.decodeWith") $
52− I.decodeWith I.jsonEOF A.fromJSON s
42+decodeA' :: BL.ByteString -> A.Value
43+decodeA' s = case A.decode' s of
44+ Just v -> v
45+ Nothing -> error "fail to parse via Aeson"
5346
5447encodeJ :: J.JSValue -> BL.ByteString
5548encodeJ = toLazyByteString . fromString . J.encode
@@ -65,37 +58,32 @@ main = do
6558 let enFile = "json-data/twitter100.json"
6659 jpFile = "json-data/jp100.json"
6760 enA <- BL.readFile enFile
68− enS <- BS.readFile enFile
6961 enJ <- readFile enFile
7062 jpA <- BL.readFile jpFile
71− jpS <- BS.readFile jpFile
7263 jpJ <- readFile jpFile
7364 defaultMain [
7465 bgroup "decode" [
7566 bgroup "en" [
76− bench "aeson/lazy" $ nf decode enA
77− , bench "aeson/strict" $ nf decode' enA
78− , bench "aeson/stricter" $ nf decodeS enS
79− , bench "aeson/parser" $ nf decodeIP enA
80− , bench "json" $ nf decodeJ enJ
67+ bench "aeson/lazy" $ nf decodeA enA
68+ , bench "aeson/strict" $ nf decodeA' enA
69+ , bench "json" $ nf decodeJ enJ
8170 ]
8271 , bgroup "jp" [
83− bench "aeson" $ nf decode jpA
84− , bench "aeson/stricter" $ nf decodeS jpS
85− , bench "json" $ nf decodeJ jpJ
72+ bench "aeson" $ nf decodeA jpA
73+ , bench "json" $ nf decodeJ jpJ
8674 ]
8775 ]
8876 , bgroup "encode" [
8977 bgroup "en" [
90− bench "aeson-to-bytestring" $ nf A.encode (decode enA)
91− , bench "aeson-via-text-to-bytestring" $ nf encodeViaText (decode enA)
92− , bench "aeson-to-text" $ nf encodeToText (decode enA)
78+ bench "aeson-to-bytestring" $ nf A.encode (decodeA enA)
79+ , bench "aeson-via-text-to-bytestring" $ nf encodeViaText (decodeA enA)
80+ , bench "aeson-to-text" $ nf encodeToText (decodeA enA)
9381 , bench "json" $ nf encodeJ (decodeJ enJ)
9482 ]
9583 , bgroup "jp" [
96− bench "aeson-to-bytestring" $ nf A.encode (decode jpA)
97− , bench "aeson-via-text-to-bytestring" $ nf encodeViaText (decode jpA)
98− , bench "aeson-to-text" $ nf encodeToText (decode jpA)
84+ bench "aeson-to-bytestring" $ nf A.encode (decodeA jpA)
85+ , bench "aeson-via-text-to-bytestring" $ nf encodeViaText (decodeA jpA)
86+ , bench "aeson-to-text" $ nf encodeToText (decodeA jpA)
9987 , bench "json" $ nf encodeJ (decodeJ jpJ)
10088 ]
10189 ]
benchmarks/Dates.hs+9−10
@@ -1,7 +1,6 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−
31module Main (main) where
42
3+import Prelude ()
54import Prelude.Compat
65
76import Criterion.Main
@@ -23,22 +22,22 @@ main = do
2322 defaultMain [
2423 bgroup "decode" [
2524 bgroup "UTCTime" [
26− env file1 $ \bs -> bench "whole" $ nf utcTime bs
27− , env file2 $ \bs -> bench "fractional" $ nf utcTime bs
25+ env file1 $ \ ~bs -> bench "whole" $ nf utcTime bs
26+ , env file2 $ \ ~bs -> bench "fractional" $ nf utcTime bs
2827 ]
2928 , bgroup "ZonedTime" [
30− env file1 $ \bs -> bench "whole" $ nf zTime bs
31− , env file2 $ \bs -> bench "fractional" $ nf zTime bs
29+ env file1 $ \ ~bs -> bench "whole" $ nf zTime bs
30+ , env file2 $ \ ~bs -> bench "fractional" $ nf zTime bs
3231 ]
3332 ]
3433 , bgroup "encode" [
3534 bgroup "UTCTime" [
36− env (utcTime <$> file1) $ \ts -> bench "whole" $ nf encode ts
37− , env (utcTime <$> file2) $ \ts -> bench "fractional" $ nf encode ts
35+ env (utcTime <$> file1) $ \ ~ts -> bench "whole" $ nf encode ts
36+ , env (utcTime <$> file2) $ \ ~ts -> bench "fractional" $ nf encode ts
3837 ]
3938 , bgroup "ZonedTime" [
40− env (zTime <$> file1) $ \ts -> bench "whole" $ nf encode ts
41− , env (zTime <$> file2) $ \ts -> bench "fractional" $ nf encode ts
39+ env (zTime <$> file1) $ \ ~ts -> bench "whole" $ nf encode ts
40+ , env (zTime <$> file2) $ \ ~ts -> bench "fractional" $ nf encode ts
4241 ]
4342 ]
4443 ]
benchmarks/Escape.hsdeleted−32
@@ -1,32 +0,0 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
4−{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
5−
6−module Main (main) where
7−
8−import Prelude.Compat
9−
10−import Criterion.Main
11−import qualified Data.Aeson.Parser.UnescapeFFI as FFI
12−import qualified Data.Aeson.Parser.UnescapePure as Pure
13−
14−import qualified Data.ByteString.Char8 as BS
15−import System.Environment (getArgs, withArgs)
16−
17−main :: IO ()
18−main = do
19− args_ <- getArgs
20− let (args, p, n) =
21− case args_ of
22− "--pattern" : p : args_ -> k p args_
23− _ -> k "\\\"" args_
24− k p args_ =
25− case args_ of
26− "--repeat" : n : args_ -> (args_, p, read n)
27− args_ -> (args_, p, 10000)
28− input = BS.concat $ replicate n $ BS.pack p
29− withArgs args $ defaultMain
30− [ bench "ffi" $ whnf FFI.unescapeText input
31− , bench "pure" $ whnf Pure.unescapeText input
32− ]
benchmarks/Issue673.hsdeleted−165
@@ -1,165 +0,0 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−{-# LANGUAGE OverloadedStrings #-}
3−
4−module Main (
5− main,
6− input17,
7− input32,
8− input64,
9− input128,
10− input256,
11− input2048,
12− input4096,
13− input8192,
14− input16384,
15− ) where
16−
17−import Criterion.Main
18−import Prelude.Compat
19−import Data.Int (Int64)
20−import Data.Scientific (Scientific)
21−import Data.Semigroup ((<>))
22−import Data.Aeson.Parser (scientific)
23−
24−import qualified Data.Attoparsec.ByteString.Lazy as AttoL
25−import qualified Data.Attoparsec.ByteString.Char8 as Atto8
26−import qualified Data.Aeson as A
27−import qualified Data.ByteString as BS
28−import qualified Data.ByteString.Lazy as LBS
29−import qualified Data.ByteString.Lazy.Char8 as LBS8
30−
31−decodeInt :: LBS.ByteString -> Maybe Int
32−decodeInt = A.decode
33−
34−decodeString :: LBS.ByteString -> Maybe String
35−decodeString = A.decode
36−
37−decodeScientific :: LBS.ByteString -> Maybe Scientific
38−decodeScientific = A.decode
39−
40−decodeViaRead :: LBS.ByteString -> Integer
41−decodeViaRead = read . LBS8.unpack
42−
43−decodeAtto :: LBS.ByteString -> Maybe Scientific
44−decodeAtto
45− = parseOnly (scientific <* AttoL.endOfInput)
46− where
47− parseOnly p lbs = case AttoL.parse p lbs of
48− AttoL.Done _ r -> Just r
49− AttoL.Fail {} -> Nothing
50−
51−decodeAtto8 :: LBS.ByteString -> Maybe Scientific
52−decodeAtto8
53− = parseOnly (Atto8.scientific <* AttoL.endOfInput)
54− where
55− parseOnly p lbs = case AttoL.parse p lbs of
56− AttoL.Done _ r -> Just r
57− AttoL.Fail {} -> Nothing
58−
59−generate :: Int64 -> LBS.ByteString
60−generate n = LBS8.replicate n '1'
61−
62−input17 :: LBS.ByteString
63−input17 = generate 17
64−
65−input32 :: LBS.ByteString
66−input32 = generate 32
67−
68−input64 :: LBS.ByteString
69−input64 = generate 64
70−
71−input128 :: LBS.ByteString
72−input128 = generate 128
73−
74−input256 :: LBS.ByteString
75−input256 = generate 256
76−
77−input2048 :: LBS.ByteString
78−input2048 = generate 2048
79−
80−input4096 :: LBS.ByteString
81−input4096 = generate 4096
82−
83−input8192 :: LBS.ByteString
84−input8192 = generate 8192
85−
86−input16384 :: LBS.ByteString
87−input16384 = generate 16384
88−
89−
90−main :: IO ()
91−main = defaultMain
92− -- works on 64bit
93− [ benchPair "17" input17
94− -- , benchPair "32" input32
95− -- , benchPair "64" input64
96− -- , benchPair "128" input128
97− -- , benchPair "256" input256
98− , benchPair "2048" input2048
99− , benchPair "4096" input4096
100− , benchPair "8192" input8192
101− , benchPair "16384" input16384
102− ]
103− where
104− benchPair name input = bgroup name
105− [ bench "Int" $ whnf decodeInt input
106− , bench "Simple" $ whnf bsToIntegerSimple (LBS.toStrict input)
107− , bench "Optim" $ whnf bsToInteger (LBS.toStrict input)
108− , bench "Read" $ whnf decodeViaRead input
109− , bench "Scientific" $ whnf decodeScientific input
110− , bench "parserA" $ whnf decodeAtto input
111− , bench "parserS" $ whnf decodeAtto8 input
112− , bench "String" $ whnf decodeString $ "\"" <> input <> "\""
113− ]
114−
115−-------------------------------------------------------------------------------
116−-- better fromInteger
117−-------------------------------------------------------------------------------
118−
119−bsToInteger :: BS.ByteString -> Integer
120−bsToInteger bs
121− | l > 40 = valInteger 10 l [ fromIntegral (w - 48) | w <- BS.unpack bs ]
122− | otherwise = bsToIntegerSimple bs
123− where
124− l = BS.length bs
125−
126−bsToIntegerSimple :: BS.ByteString -> Integer
127−bsToIntegerSimple = BS.foldl' step 0 where
128− step a b = a * 10 + fromIntegral (b - 48) -- 48 = '0'
129−
130−-- A sub-quadratic algorithm for Integer. Pairs of adjacent radix b
131−-- digits are combined into a single radix b^2 digit. This process is
132−-- repeated until we are left with a single digit. This algorithm
133−-- performs well only on large inputs, so we use the simple algorithm
134−-- for smaller inputs.
135−valInteger :: Integer -> Int -> [Integer] -> Integer
136−valInteger = go
137− where
138− go :: Integer -> Int -> [Integer] -> Integer
139− go _ _ [] = 0
140− go _ _ [d] = d
141− go b l ds
142− | l > 40 = b' `seq` go b' l' (combine b ds')
143− | otherwise = valSimple b ds
144− where
145− -- ensure that we have an even number of digits
146− -- before we call combine:
147− ds' = if even l then ds else 0 : ds
148− b' = b * b
149− l' = (l + 1) `quot` 2
150−
151− combine b (d1 : d2 : ds) = d `seq` (d : combine b ds)
152− where
153− d = d1 * b + d2
154− combine _ [] = []
155− combine _ [_] = errorWithoutStackTrace "this should not happen"
156−
157−-- The following algorithm is only linear for types whose Num operations
158−-- are in constant time.
159−valSimple :: Integer -> [Integer] -> Integer
160−valSimple base = go 0
161− where
162− go r [] = r
163− go r (d : ds) = r' `seq` go r' ds
164− where
165− r' = r * base + fromIntegral d
benchmarks/JsonParse.hs+2−3
@@ -1,11 +1,10 @@
11{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
32{-# LANGUAGE ScopedTypeVariables #-}
4−
53{-# OPTIONS_GHC -fno-warn-orphans #-}
64
75module Main (main) where
86
7+import Prelude ()
98import Prelude.Compat
109
1110import Control.DeepSeq
@@ -17,7 +16,7 @@ import Text.JSON
1716instance NFData JSValue where
1817 rnf JSNull = ()
1918 rnf (JSBool b) = rnf b
20− rnf (JSRational b r) = rnf b `seq` rnf r
19+ rnf (JSRational b r) = rnf b `seq` rnf r `seq` ()
2120 rnf (JSString s) = rnf (fromJSString s)
2221 rnf (JSArray vs) = rnf vs
2322 rnf (JSObject kvs) = rnf (fromJSObject kvs)
benchmarks/Micro.hs+6−8
@@ -1,13 +1,11 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−
31module Main (main) where
42
3+import Prelude ()
54import Prelude.Compat
65
76import Criterion.Main
8−
9−-- Encoding is a newtype wrapper around Builder
10−import Data.Aeson.Encoding (text, string, encodingToLazyByteString)
7+import qualified Data.Aeson.Encoding.Builder as AB
8+import qualified Data.ByteString.Builder as B
119import qualified Data.Text as T
1210
1311main :: IO ()
@@ -15,8 +13,8 @@ main = do
1513 let txt = "append (append b (primBounded w1 x1)) (primBounded w2 x2)"
1614 defaultMain [
1715 bgroup "string" [
18− bench "text" $ nf (encodingToLazyByteString . text) (T.pack txt)
19− , bench "string direct" $ nf (encodingToLazyByteString . string) txt
20− , bench "string via text" $ nf (encodingToLazyByteString . text . T.pack) txt
16+ bench "text" $ nf (B.toLazyByteString . AB.text) (T.pack txt)
17+ , bench "string direct" $ nf (B.toLazyByteString . AB.string) txt
18+ , bench "string via text" $ nf (B.toLazyByteString . AB.text . T.pack) txt
2119 ]
2220 ]
benchmarks/Options.hs+4−1
@@ -1,4 +1,7 @@
1−module Options (opts) where
1+module Options () where
2+
3+import Prelude ()
4+import Prelude.Compat
25
36import Data.Aeson.Types
47
benchmarks/ReadFile.hs+2−2
@@ -1,9 +1,9 @@
11{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
32{-# LANGUAGE OverloadedStrings #-}
43
54module Main (main) where
65
6+import Prelude ()
77import Prelude.Compat
88
99import Control.DeepSeq
@@ -20,7 +20,7 @@ import qualified Data.ByteString as B
2020main = do
2121 (cnt:args) <- getArgs
2222 let count = read cnt :: Int
23− forM_ args $ \arg -> withFile arg ReadMode $ \h -> do
23+ forM_ args $ \arg -> bracket (openFile arg ReadMode) hClose $ \h -> do
2424 putStrLn $ arg ++ ":"
2525 start <- getCurrentTime
2626 let loop !n
benchmarks/Typed.hs+1−5
@@ -1,7 +1,6 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−
31module Main (main) where
42
3+import Prelude ()
54import Prelude.Compat
65
76import Criterion.Main
@@ -14,7 +13,4 @@ main = defaultMain [
1413 Generic.benchmarks
1514 , Manual.benchmarks
1615 , TH.benchmarks
17− , Generic.decodeBenchmarks
18− , Manual.decodeBenchmarks
19− , TH.decodeBenchmarks
2016 ]
benchmarks/Typed/Common.hs+8−1
@@ -1,16 +1,23 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
1+{-# LANGUAGE CPP #-}
2+{-# LANGUAGE PackageImports #-}
23
34{-# OPTIONS_GHC -fno-warn-unused-imports #-}
45
56module Typed.Common (load) where
67
8+import Prelude ()
79import Prelude.Compat
810
911import Data.ByteString.Lazy as L
1012import System.Exit
1113import System.IO
1214
15+#ifndef HAS_BOTH_AESON_AND_BENCHMARKS
1316import Data.Aeson hiding (Result)
17+#else
18+import "aeson" Data.Aeson hiding (Result)
19+import qualified "aeson-benchmarks" Data.Aeson as B
20+#endif
1421
1522load :: FromJSON a => FilePath -> IO a
1623load fileName = do
benchmarks/Typed/Generic.hs+25−27
@@ -1,44 +1,42 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−
3−module Typed.Generic (benchmarks, decodeBenchmarks) where
1+{-# LANGUAGE PackageImports #-}
2+module Typed.Generic (benchmarks) where
43
4+import Prelude ()
55import Prelude.Compat
66
7−import Data.Aeson hiding (Result)
7+import "aeson" Data.Aeson hiding (Result)
88import Criterion
99import Data.ByteString.Lazy as L
10−import Twitter.Generic
10+import Twitter.TH
1111import Typed.Common
12+import qualified "aeson-benchmarks" Data.Aeson as B
13+
14+encodeDirectA :: Result -> L.ByteString
15+encodeDirectA = encode
1216
13−encodeDirect :: Result -> L.ByteString
14−encodeDirect = encode
17+encodeViaValueA :: Result -> L.ByteString
18+encodeViaValueA = encode . toJSON
1519
16−encodeViaValue :: Result -> L.ByteString
17−encodeViaValue = encode . toJSON
20+encodeDirectB :: Result -> L.ByteString
21+encodeDirectB = B.encode
22+
23+encodeViaValueB :: Result -> L.ByteString
24+encodeViaValueB = B.encode . B.toJSON
1825
1926benchmarks :: Benchmark
2027benchmarks =
2128 env ((,) <$> load "json-data/twitter100.json" <*> load "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
22− bgroup "encodeGeneric" [
29+ bgroup "generic" [
2330 bgroup "direct" [
24− bench "twitter100" $ nf encodeDirect twitter100
25− , bench "jp100" $ nf encodeDirect jp100
31+ bench "twitter100" $ nf encodeDirectB twitter100
32+ , bench "jp100" $ nf encodeDirectB jp100
33+ , bench "twitter100 baseline" $ nf encodeDirectA twitter100
34+ , bench "jp100 baseline" $ nf encodeDirectA jp100
2635 ]
2736 , bgroup "viaValue" [
28− bench "twitter100" $ nf encodeViaValue twitter100
29− , bench "jp100" $ nf encodeViaValue jp100
30− ]
31− ]
32−
33−decodeDirect :: L.ByteString -> Maybe Result
34−decodeDirect = decode
35−
36−decodeBenchmarks :: Benchmark
37−decodeBenchmarks =
38− env ((,) <$> L.readFile "json-data/twitter100.json" <*> L.readFile "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
39− bgroup "decodeGeneric"
40− [ bgroup "direct"
41− [ bench "twitter100" $ nf decodeDirect twitter100
42− , bench "jp100" $ nf decodeDirect jp100
37+ bench "twitter100" $ nf encodeViaValueB twitter100
38+ , bench "jp100" $ nf encodeViaValueB jp100
39+ , bench "twitter100 baseline" $ nf encodeViaValueA twitter100
40+ , bench "jp100 baseline" $ nf encodeViaValueA jp100
4341 ]
4442 ]
benchmarks/Typed/Manual.hs+24−26
@@ -1,44 +1,42 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−
3−module Typed.Manual (benchmarks, decodeBenchmarks) where
1+{-# LANGUAGE PackageImports #-}
2+module Typed.Manual (benchmarks) where
43
4+import Prelude ()
55import Prelude.Compat
66
7−import Data.Aeson hiding (Result)
7+import "aeson" Data.Aeson hiding (Result)
88import Criterion
99import Data.ByteString.Lazy as L
1010import Twitter.Manual
1111import Typed.Common
12+import qualified "aeson-benchmarks" Data.Aeson as B
13+
14+encodeDirectA :: Result -> L.ByteString
15+encodeDirectA = encode
1216
13−encodeDirect :: Result -> L.ByteString
14−encodeDirect = encode
17+encodeViaValueA :: Result -> L.ByteString
18+encodeViaValueA = encode . toJSON
1519
16−encodeViaValue :: Result -> L.ByteString
17−encodeViaValue = encode . toJSON
20+encodeDirectB :: Result -> L.ByteString
21+encodeDirectB = B.encode
22+
23+encodeViaValueB :: Result -> L.ByteString
24+encodeViaValueB = B.encode . B.toJSON
1825
1926benchmarks :: Benchmark
2027benchmarks =
2128 env ((,) <$> load "json-data/twitter100.json" <*> load "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
22− bgroup "encodeManual" [
29+ bgroup "manual" [
2330 bgroup "direct" [
24− bench "twitter100" $ nf encodeDirect twitter100
25− , bench "jp100" $ nf encodeDirect jp100
31+ bench "twitter100" $ nf encodeDirectB twitter100
32+ , bench "jp100" $ nf encodeDirectB jp100
33+ , bench "twitter100 baseline" $ nf encodeDirectA twitter100
34+ , bench "jp100 baseline" $ nf encodeDirectA jp100
2635 ]
2736 , bgroup "viaValue" [
28− bench "twitter100" $ nf encodeViaValue twitter100
29− , bench "jp100" $ nf encodeViaValue jp100
30− ]
31− ]
32−
33−decodeDirect :: L.ByteString -> Maybe Result
34−decodeDirect = decode
35−
36−decodeBenchmarks :: Benchmark
37−decodeBenchmarks =
38− env ((,) <$> L.readFile "json-data/twitter100.json" <*> L.readFile "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
39− bgroup "decodeManual"
40− [ bgroup "direct"
41− [ bench "twitter100" $ nf decodeDirect twitter100
42− , bench "jp100" $ nf decodeDirect jp100
37+ bench "twitter100" $ nf encodeViaValueB twitter100
38+ , bench "jp100" $ nf encodeViaValueB jp100
39+ , bench "twitter100 baseline" $ nf encodeViaValueA twitter100
40+ , bench "jp100 baseline" $ nf encodeViaValueA jp100
4341 ]
4442 ]
benchmarks/Typed/TH.hs+24−26
@@ -1,44 +1,42 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−
3−module Typed.TH (benchmarks, decodeBenchmarks) where
1+{-# LANGUAGE PackageImports #-}
2+module Typed.TH (benchmarks) where
43
4+import Prelude ()
55import Prelude.Compat
66
7−import Data.Aeson hiding (Result)
7+import "aeson" Data.Aeson hiding (Result)
88import Criterion
99import Data.ByteString.Lazy as L
1010import Twitter.TH
1111import Typed.Common
12+import qualified "aeson-benchmarks" Data.Aeson as B
13+
14+encodeDirectA :: Result -> L.ByteString
15+encodeDirectA = encode
1216
13−encodeDirect :: Result -> L.ByteString
14−encodeDirect = encode
17+encodeViaValueA :: Result -> L.ByteString
18+encodeViaValueA = encode . toJSON
1519
16−encodeViaValue :: Result -> L.ByteString
17−encodeViaValue = encode . toJSON
20+encodeDirectB :: Result -> L.ByteString
21+encodeDirectB = B.encode
22+
23+encodeViaValueB :: Result -> L.ByteString
24+encodeViaValueB = B.encode . B.toJSON
1825
1926benchmarks :: Benchmark
2027benchmarks =
2128 env ((,) <$> load "json-data/twitter100.json" <*> load "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
22− bgroup "encodeTH" [
29+ bgroup "th" [
2330 bgroup "direct" [
24− bench "twitter100" $ nf encodeDirect twitter100
25− , bench "jp100" $ nf encodeDirect jp100
31+ bench "twitter100" $ nf encodeDirectB twitter100
32+ , bench "jp100" $ nf encodeDirectB jp100
33+ , bench "twitter100 baseline" $ nf encodeDirectA twitter100
34+ , bench "jp100 baseline" $ nf encodeDirectA jp100
2635 ]
2736 , bgroup "viaValue" [
28− bench "twitter100" $ nf encodeViaValue twitter100
29− , bench "jp100" $ nf encodeViaValue jp100
30− ]
31− ]
32−
33−decodeDirect :: L.ByteString -> Maybe Result
34−decodeDirect = decode
35−
36−decodeBenchmarks :: Benchmark
37−decodeBenchmarks =
38− env ((,) <$> L.readFile "json-data/twitter100.json" <*> L.readFile "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
39− bgroup "decodeTH"
40− [ bgroup "direct"
41− [ bench "twitter100" $ nf decodeDirect twitter100
42− , bench "jp100" $ nf decodeDirect jp100
37+ bench "twitter100" $ nf encodeViaValueA twitter100
38+ , bench "jp100" $ nf encodeViaValueA jp100
39+ , bench "twitter100 baseline" $ nf encodeViaValueB twitter100
40+ , bench "jp100 baseline" $ nf encodeViaValueB jp100
4341 ]
4442 ]
benchmarks/aeson-benchmarks.cabal+62−183
@@ -1,21 +1,60 @@
11name: aeson-benchmarks
22version: 0
33build-type: Simple
4−cabal-version: >=1.10
4+
5+cabal-version: >=1.8
56
67flag bytestring-builder
78 description: Depend on the bytestring-builder package for backwards compatibility.
89 default: False
910 manual: False
1011
11−flag local-aeson
12− description: Build the local version of aeson, to avoid rebuilding aeson's
13− reverse dependencies for benchmarking (statistics, criterion).
14− default: True
15− manual: True
16−
1712library
18− default-language: Haskell2010
13+ hs-source-dirs: .. .
14+ c-sources: ../cbits/unescape_string.c
15+ exposed-modules:
16+ Data.Aeson
17+ Data.Aeson.Encoding
18+ Data.Aeson.Parser
19+ Data.Aeson.Text
20+ Data.Aeson.Types
21+ Data.Aeson.TH
22+
23+ Data.Aeson.Encoding.Internal
24+ Data.Aeson.Internal
25+ Data.Aeson.Internal.Time
26+
27+ Data.Aeson.Encoding.Builder
28+ Data.Aeson.Internal.Functions
29+ Data.Aeson.Parser.Internal
30+ Data.Aeson.Parser.Time
31+ Data.Aeson.Types.FromJSON
32+ Data.Aeson.Types.Generic
33+ Data.Aeson.Types.ToJSON
34+ Data.Aeson.Types.Class
35+ Data.Aeson.Types.Internal
36+
37+ build-depends:
38+ attoparsec >= 0.13.0.1,
39+ base == 4.*,
40+ base-compat >= 0.9.1 && <0.10,
41+ time-locale-compat >=0.1.1 && <0.2,
42+ containers,
43+ deepseq,
44+ dlist >= 0.2,
45+ fail == 4.9.*,
46+ ghc-prim >= 0.2,
47+ hashable >= 1.1.2.0,
48+ mtl,
49+ scientific >= 0.3.4.7 && < 0.4,
50+ syb,
51+ tagged >=0.8.3 && <0.9,
52+ template-haskell >= 2.4,
53+ text >= 1.1.1.0,
54+ time,
55+ transformers,
56+ unordered-containers >= 0.2.3.0,
57+ vector >= 0.7.1
1958
2059 if flag(bytestring-builder)
2160 build-depends: bytestring >= 0.9 && < 0.10.4,
@@ -23,142 +62,22 @@ library
2362 else
2463 build-depends: bytestring >= 0.10.4
2564
26− if flag(local-aeson)
27−
28− hs-source-dirs: .. ../ffi ../pure ../attoparsec-iso8601
29− c-sources: ../cbits/unescape_string.c
30− build-depends:
31− attoparsec,
32− base,
33− base-compat,
34− containers,
35− deepseq,
36− dlist,
37− fail,
38− ghc-prim,
39− hashable,
40− mtl,
41− primitive,
42− scientific,
43− syb,
44− tagged,
45− template-haskell,
46− text,
47− th-abstraction,
48− time-compat,
49− time,
50− transformers,
51− unordered-containers,
52− uuid-types,
53− vector
54−
55− if !impl(ghc >= 8.6)
56− build-depends: contravariant
57−
58− if !impl(ghc >= 8.0)
59− -- `Data.Semigroup` is available in base only since GHC 8.0 / base 4.9
60− build-depends: semigroups,
61− transformers-compat
65+ if impl(ghc >=7.8)
66+ cpp-options: -DHAS_COERCIBLE
6267
63− if !impl(ghc >= 7.10)
64− -- `Numeric.Natural` is available in base only since GHC 7.10 / base 4.8
65− build-depends: nats,
66− void
68+ if !impl(ghc >= 8.0)
69+ -- `Data.Semigroup` is available in base only since GHC 8.0 / base 4.9
70+ build-depends: semigroups >= 0.18.2 && < 0.19
6771
68− include-dirs: ../include
72+ include-dirs: ../include
6973
70− ghc-options: -O2 -Wall
71− cpp-options: -DGENERICS
72−
73− exposed-modules:
74− Data.Aeson
75− Data.Aeson.Encoding
76− Data.Aeson.Encoding.Builder
77− Data.Aeson.Encoding.Internal
78− Data.Aeson.Internal
79− Data.Aeson.Internal.Functions
80− Data.Aeson.Internal.Time
81− Data.Aeson.Parser
82− Data.Aeson.Parser.Internal
83− Data.Aeson.Parser.Time
84− Data.Aeson.Parser.Unescape
85− Data.Aeson.Parser.UnescapeFFI
86− Data.Aeson.Parser.UnescapePure
87− Data.Aeson.TH
88− Data.Aeson.Text
89− Data.Aeson.Types
90− Data.Aeson.Types.Class
91− Data.Aeson.Types.FromJSON
92− Data.Aeson.Types.Generic
93− Data.Aeson.Types.Internal
94− Data.Aeson.Types.ToJSON
95− Data.Attoparsec.Time
96− Data.Attoparsec.Time.Internal
97−
98− else
99−
100− build-depends: aeson
101−
102− reexported-modules:
103− Data.Aeson,
104− Data.Aeson.Encoding,
105− Data.Aeson.Parser.Internal,
106− Data.Aeson.Text,
107− Data.Aeson.TH,
108− Data.Aeson.Types
109−
110−executable aeson-benchmark-auto-compare
111− default-language: Haskell2010
112− main-is: AutoCompare.hs
113− hs-source-dirs: .
114− ghc-options: -Wall -O2 -rtsopts
115− other-modules:
116− Auto.T.D
117− Auto.T.BigRecord
118− Auto.T.BigProduct
119− Auto.T.BigSum
120− Auto.G.D
121− Auto.G.BigRecord
122− Auto.G.BigProduct
123− Auto.G.BigSum
124− Options
125− build-depends:
126− aeson-benchmarks,
127− base,
128− criterion,
129− deepseq,
130− template-haskell
131−
132−executable aeson-benchmark-escape
133− default-language: Haskell2010
134− main-is: Escape.hs
135− hs-source-dirs: ../examples .
136− ghc-options: -Wall -O2 -rtsopts
137− if flag(local-aeson)
138− build-depends:
139− aeson-benchmarks,
140− base,
141− base-compat,
142− bytestring,
143− criterion >= 1.0,
144− deepseq,
145− ghc-prim,
146− text
147− else
148− -- Disabled because of inaccessible internals
149− buildable: False
74+ ghc-options: -O2 -Wall
75+ cpp-options: -DGENERICS
15076
15177executable aeson-benchmark-compare
152− default-language: Haskell2010
15378 main-is: Compare.hs
15479 hs-source-dirs: ../examples .
15580 ghc-options: -Wall -O2 -rtsopts
156− other-modules:
157− Compare.BufferBuilder
158− Compare.JsonBench
159− Twitter
160− Twitter.Manual
161− Typed.Common
16281 build-depends:
16382 aeson-benchmarks,
16483 base,
@@ -168,19 +87,10 @@ executable aeson-benchmark-compare
16887 criterion >= 1.0,
16988 deepseq,
17089 ghc-prim,
90+ json-builder,
17191 text
17292
173− if impl(ghc < 8.4)
174− other-modules:
175− Compare.JsonBuilder
176− build-depends:
177− json-builder
178− if impl(ghc < 8.0)
179− build-depends:
180− semigroups
181−
18293executable aeson-benchmark-micro
183− default-language: Haskell2010
18494 main-is: Micro.hs
18595 hs-source-dirs: ../examples .
18696 ghc-options: -Wall -O2 -rtsopts
@@ -195,21 +105,14 @@ executable aeson-benchmark-micro
195105 text
196106
197107executable aeson-benchmark-typed
198− default-language: Haskell2010
199108 main-is: Typed.hs
200109 hs-source-dirs: ../examples .
201110 ghc-options: -Wall -O2 -rtsopts
202− other-modules:
203− Twitter
204− Twitter.Generic
205− Twitter.Manual
206− Twitter.Options
207− Twitter.TH
208− Typed.Common
209− Typed.Generic
210− Typed.Manual
211− Typed.TH
111+ -- We must help ourself in situations when there is both
112+ -- aeson and aeson-benchmakrs
113+ cpp-options: -DHAS_BOTH_AESON_AND_BENCHMARKS
212114 build-depends:
115+ aeson,
213116 aeson-benchmarks,
214117 base,
215118 base-compat,
@@ -224,11 +127,8 @@ executable aeson-benchmark-typed
224127 bytestring-builder >= 0.10.4 && < 1
225128 else
226129 build-depends: bytestring >= 0.10.4
227− if impl(ghc < 8.0)
228− build-depends: semigroups
229130
230131executable aeson-benchmark-compare-with-json
231− default-language: Haskell2010
232132 main-is: CompareWithJSON.hs
233133 ghc-options: -Wall -O2 -rtsopts
234134 build-depends:
@@ -243,7 +143,6 @@ executable aeson-benchmark-compare-with-json
243143 text
244144
245145executable aeson-benchmark-aeson-encode
246− default-language: Haskell2010
247146 main-is: AesonEncode.hs
248147 ghc-options: -Wall -O2 -rtsopts
249148 build-depends:
@@ -256,7 +155,6 @@ executable aeson-benchmark-aeson-encode
256155 time
257156
258157executable aeson-benchmark-aeson-parse
259− default-language: Haskell2010
260158 main-is: AesonParse.hs
261159 ghc-options: -Wall -O2 -rtsopts
262160 build-depends:
@@ -268,7 +166,6 @@ executable aeson-benchmark-aeson-parse
268166 time
269167
270168executable aeson-benchmark-json-parse
271− default-language: Haskell2010
272169 main-is: JsonParse.hs
273170 ghc-options: -Wall -O2 -rtsopts
274171 build-depends:
@@ -279,7 +176,6 @@ executable aeson-benchmark-json-parse
279176 time
280177
281178executable aeson-benchmark-dates
282− default-language: Haskell2010
283179 main-is: Dates.hs
284180 ghc-options: -Wall -O2 -rtsopts
285181 build-depends:
@@ -291,14 +187,12 @@ executable aeson-benchmark-dates
291187 aeson-benchmarks,
292188 text,
293189 time
294− if impl(ghc >= 8.2)
295− ghc-options: -Wno-simplifiable-class-constraints
296190
297191executable aeson-benchmark-map
298− default-language: Haskell2010
299192 main-is: AesonMap.hs
300193 ghc-options: -Wall -O2 -rtsopts
301194 build-depends:
195+ aeson,
302196 aeson-benchmarks,
303197 base,
304198 base-compat,
@@ -312,10 +206,10 @@ executable aeson-benchmark-map
312206 unordered-containers
313207
314208executable aeson-benchmark-foldable
315− default-language: Haskell2010
316209 main-is: AesonFoldable.hs
317210 ghc-options: -Wall -O2 -rtsopts
318211 build-depends:
212+ aeson,
319213 aeson-benchmarks,
320214 base,
321215 base-compat,
@@ -328,18 +222,3 @@ executable aeson-benchmark-foldable
328222 text,
329223 unordered-containers,
330224 vector
331−
332−executable aeson-issue-673
333− default-language: Haskell2010
334− main-is: Issue673.hs
335− ghc-options: -Wall -O1 -rtsopts
336− build-depends:
337− aeson-benchmarks,
338− attoparsec,
339− base,
340− bytestring,
341− scientific,
342− base-compat,
343− criterion >= 1.0
344− if impl(ghc < 8.0)
345− build-depends: semigroups
cabal.projectdeleted−5
@@ -1,5 +0,0 @@
1−with-compiler: ghc
2−packages: .
3−packages: attoparsec-iso8601
4−-- packages: benchmarks
5−tests: true
cbits/unescape_string.c+2−1
@@ -130,7 +130,7 @@ int _js_decode_string(uint16_t *const dest, size_t *destoff,
130130 *d++ = (uint16_t) unidata;
131131
132132 if (surrogate) {
133− if (unidata < 0xDC00 || unidata > 0xDFFF) // is not low surrogate
133+ if (unidata <= 0xDC00 || unidata >= 0xDFFF) // is not low surrogate
134134 return -1;
135135 surrogate = 0;
136136 } else if (unidata >= 0xD800 && unidata <= 0xDBFF ) { // is high surrogate
@@ -147,3 +147,4 @@ int _js_decode_string(uint16_t *const dest, size_t *destoff,
147147 if (codepoint != 'u') { return -1; }
148148 DISPATCH_ASCII(unicode1)
149149}
150+
changelog.md+3−252
@@ -1,258 +1,9 @@
11For the latest version of this document, please see [https://github.com/bos/aeson/blob/master/changelog.md](https://github.com/bos/aeson/blob/master/changelog.md).
22
3−### upcoming
3+# Upcoming
44
5−* `FromJSON` instance of `Ratio a` now parses numbers in addtion to
6− standard `{numerator=..., denumerator=...}` encoding.
7−
8−### 1.4.6.0
9−
10−* Provide a clearer error message when a required tagKey for a constructor is missing, thanks to Guru Devanla.
11− The error message now looks like this: `Error in $: parsing Types.SomeType failed, expected Object with key "tag" containing one of ["nullary","unary","product","record","list"], key "tag" not found`
12−
13−* Add `formatPath` and `formatRelativePath` functions to turn a `JSONPath` into a `String`, thanks to Robbie McMichael
14−
15−
16−### 1.4.5.0
17−
18−* Expose `(<?>)`, `JSONPath` and `JSONPathElement(..)` from `Data.Aeson.Types`. Previously only available through internal modules. Thanks to Luke Clifton.
19−
20−* Support for base-compat 0.11, thanks to Ryan Scott.
21−
22−* Travis build for GHC 8.8, thanks to Oleg Grenrus.
23−
24−### 1.4.4.0
25−
26−**New features**:
27−
28−* Adds a parameterized parser `jsonWith` that can be used to choose how to handle duplicate keys in objects, thanks to Xia Li-Yao.
29−
30−* Add generic implementations of `FromJSONKey` and `ToJSONKey`, thanks to Xia Li-Yao. Example:
31−
32−```haskell
33−data Foo = Bar
34− deriving Generic
35−
36−opts :: JSONKeyOptions
37−opts = defaultJSONKeyOptions { keyModifier = toLower }
38−
39−instance ToJSONKey Foo where
40− toJSONKey = genericToJSONKey opts
41−
42−instance FromJSONKey Foo where
43− fromJSONKey = genericFromJSONKey opts
44−```
45−
46−**Minor**:
47−* aeson now uses `time-compat` instead of `time-locale-compat`, thanks to Oleg Grenrus.
48−* Prepare for `MonadFail` breakages in GHC 8.8, thanks to Oleg Grenrus.
49−* Require `bytestring >= 0.10.8.1` for newer GHCs to avoid build failures, thanks to Oleg Grenrus.
50−* Support `primitive 0.7.*`, thanks to Adam Bergmark.
51−* Allow `semigroups 0.19.*` and `hashable 1.3.*`, thanks to Oleg Grenrus.
52−* Fix a typo in the error message when parsing `NonEmpty`, thanks to Colin Woodbury.
53−* Document surprising behavior when using `omitNothingFields` with type variables, thanks to Xia Li-Yao.
54−
55−**Internal changes**:
56−* Code cleanup by Oleg Grenrus
57−* Fix dependencies of the benchmarks on older GHC's, thanks to Xia Li-Yao.
58−
59−### 1.4.3.0
60−* Improve error messages for FromJSON in existing instances and GHC Generic implementation. Thanks to Xia Li-Yao & Igor Pashev.
61−* Tweak error-reporting combinators and their documentation. Thanks to Xia Li-Yao.
62− * `typeMismatch` is now about comparing JSON types (i.e., the expected and actual names of the Value constructor).
63− * `withObject` and other `with*` combinators now also mention the JSON types they expect
64− * New `unexpected` and `prependFailure` combinators.
65−* Add `Contravariant` `ToJSONKeyFunction` instance. Thanks to Oleg Grenrus.
66−* Add `KeyValue` instance for `Object`. Thanks to Robert Hensing.
67−* Improve performance when parsing certain large numbers, thanks to Oleg Grenrus.
68−* Add `Data.Aeson.QQ.Simple` - A limited version of aeson-qq. Thanks to Oleg Grenrus.
69−* Exposes internal helper functions like `<?>`, `JSONPath`, and `parseIndexedJSON` from `Data.Aeson` module. Thanks to Abid Uzair.
70−* Better error messages when there are syntax errors parsing objects and arrays. Thanks to Fintan Halpenny.
71−* Support building with `th-abstraction-0.3.0.0` or later. Thanks to Ryan Scott.
72−
73−### 1.4.2.0
74−
75−* Add `Data.Aeson.QQ.Simple` which is a simpler version of the `aeson-qq` package, it does not support interpolation, thanks to Oleg Grenrus.
76−* Add `Contravariant ToJSONKeyFunction` instance, thanks to Oleg Grenrus.
77−* Add `KeyValue Object` instance, thanks to Robert Hensing
78−* Improved performance when parsing large numbers, thanks to Oleg Grenrus.
79−
80−### 1.4.1.0
81−
82−* Optimizations of generics, thanks to Rémy Oudompheng, here are some numbers for GHC 8.4:
83− * Compilation time: G/BigProduct.hs is 25% faster, G/BigRecord.hs is 2x faster.
84− * Runtime performance: BigRecord/toJSON/generic and BigProduct/encode/generic are more than 2x faster.
85−* Added To/FromJSON instances for `Void` and Generics's `V1`, thanks to Will Yager
86−* Added To/FromJSON instances for `primitive`'s `Array`, `SmallArray`, `PrimArray` and `UnliftedArray`, thanks to Andrew Thad.
87−* Fixes handling of `UTCTime` wrt. leap seconds , thanks to Adam Schønemann
88−* Warning and documentation fixes thanks to tom-bop, Gabor Greif, Ian Jeffries, and Mateusz Curyło.
89−
90−## 1.4.0.0
91−
92−This release introduces bounds on the size of `Scientific` numbers when they are converted to other arbitrary precision types that do not represent them efficiently in memory.
93−
94−This means that trying to decode a number such as `1e1000000000` into an `Integer` will now fail instead of using a lot of memory. If you need to represent large numbers you can add a newtype (preferably over `Scientific`) and providing a parser using `withScientific`.
95−
96−The following instances are affected by this:
97−* `FromJSON Natural`
98−* `FromJSONKey Natural`
99−* `FromJSON Integer`
100−* `FromJSONKey Integer`
101−* `FromJSON NominalDiffTime`
102−
103−For the same reasons the following instances & functions have been removed:
104−* Remove `FromJSON Data.Attoparsec.Number` instance. Note that `Data.Attoparsec.Number` is deprecated.
105−* Remove deprecated `withNumber`, use `withScientific` instead.
106−
107−Finally, encoding integral values with large exponents now uses scientific notation, this saves space for large numbers.
108−
109−#### 1.3.1.1
110−
111−* Catch 0 denominators when parsing Ratio
112−
113−### 1.3.1.0
114−
115−* Fix bug in generically derived `FromJSON` instances that are using `unwrapUnaryRecords`, thanks to Xia Li-yao
116−* Allow base-compat 0.10.*, thanks to Oleg Grenrus
117−
118−## 1.3.0.0
119−
120−Breaking changes:
121−* `GKeyValue` has been renamed to `KeyValuePair`, thanks to Xia Li-yao
122−* Removed unused `FromJSON` constraint in `withEmbeddedJson`, thanks to Tristan Seligmann
123−
124−Other improvements:
125−* Optimizations of TH toEncoding, thanks to Xia Li-yao
126−* Optimizations of hex decoding when using the default/pure unescape implementation, thanks to Xia Li-yao
127−* Improved error message on `Day` parse failures, thanks to Gershom Bazerman
128−* Add `encodeFile` as well as `decodeFile*` variants, thanks to Markus Hauck
129−* Documentation fixes, thanks to Lennart Spitzner
130−* CPP cleanup, thanks to Ryan Scott
131−
132−### 1.2.4.0
133−
134−* Add `Ord` instance for `JSONPathElement`, thanks to Simon Hengel.
135−
136−
137−### 1.2.3.0
138−
139−* Added `withEmbeddedJSON` to help parse JSON embedded inside a JSON string, thanks to Jesse Kempf.
140−* Memory usage improvements to the default (pure) parser, thanks to Jonathan Paugh. Also thanks to Neil Mitchell & Oleg Grenrus for contributing a benchmark.
141−* `omitNothingFields` now works for the `Option` newtype, thanks to Xia Li-yao.
142−* Some documentation fixes, thanks to Jonathan Paug & Philippe Crama.
143−
144−### 1.2.2.0
145−
146−* Add `FromJSON` and `ToJSON` instances for
147− * `DiffTime`, thanks to Víctor López Juan.
148− * `CTime`, thanks to Daniel Díaz.
149−* Fix handling of fractions when parsing Natural, thanks to Yuriy Syrovetskiy.
150−* Change text in error messages for Integral types to make them follow the common pattern, thanks to Yuriy Syrovetskiy.
151−* Add missing `INCOHERENT` pragma for `RecordToPair`, thanks to Xia Li-yao.
152−* Everything related to `Options` is now exported from `Data.Aeson`, thanks to Xia Li-yao.
153−* Optimizations to not escape text in clear cases, thanks to Oleg Grenrus.
154−* Some documentation fixes, thanks to Phil de Joux & Xia Li-yao.
155−
156−### 1.2.1.0
157−
158−* Add `parserThrowError` and `parserCatchError` combinators, thanks to Oleg Grenrus.
159−
160−* Add `Generic` instance for `Value`, thanks to Xia Li-yao.
161−
162−* Fix a mistake in the 1.2.0.0 changelog, the `cffi` flag is disabled by default! Thanks to dbaynard.
163−
164−## 1.2.0.0
165−
166−* `tagSingleConstructors`, an option to encode single-constructor types as tagged sums was added to `Options`. It is disabled by default for backward compatibility.
167−
168−* The `cffi` flag is now turned off (`False`) by default, this means C FFI code is no longer used by default. You can flip the flag to get C implementation.
169−
170−* The `Options` constructor is no longer exposed to prevent new options from being breaking changes, use `defaultOptions` instead.
171−
172−* The contents of `GToJSON` and `GToEncoding` are no longer exposed.
173−
174−* Some INLINE pragmas were removed to avoid GHC running out of simplifier ticks.
175−
176−### 1.1.2.0
177−
178−* Fix an accidental change in the format of `deriveJSON`. Thanks to Xia Li-yao!
179−
180−* Documentation improvements regarding `ToJSON`, `FromJSON`, and `SumEncoding`. Thanks to Xia Li-yao and Lennart Spitzner!
181−
182−### 1.1.1.0
183−
184−* Added a pure implementation of the C FFI code, the C FFI code. If you wish to use the pure haskell version set the `cffi` flag to `False`. This should make aeson compile when C isn't available, such as for GHCJS. Thanks to James Parker & Marcin Tolysz!
185−
186−* Using the `fast` flag can no longer cause a test case to fail. As far as we know this didn't affect any users of the library itself. Thanks to Xia Li-yao!
187−
188−## 1.1.0.0
189−
190−* Added instances for `UUID`.
191−
192−* The operators for parsing fields now have named aliases:
193− - `.:` => `parseField`
194− - `.:?` => `parseFieldMaybe`
195− - `.:!` => `parseFieldMaybe'`
196− - These functions now also have variants with explicit parser functions: `explicitParseField`, `explicitParseFieldMaybe`, "explicitParseFieldMaybe'`
197−Thanks to Oleg Grenrus.
198−
199−* `ToJSONKey (Identity a)` and `FromJSONKey (Identity a)` no longer require the unnecessary `FromJSON a` constraint. Thanks to Oleg Grenrus.
200−
201−* Added `Data.Aeson.Encoding.pair'` which is a more general version of `Data.Aeson.Encoding.pair`. Thanks to Andrew Martin.
202−
203−* `Day`s BCE are properly encoded and `+` is now a valid prefix for `Day`s CE. Thanks to Matt Parsons.
204−
205−* Some commonly used ToJSON instances are now specialized in order to improve compile time. Thanks to Bartosz Nitka.
206−
207−
208−[JSONTestSuite](https://github.com/nst/JSONTestSuite) cleanups, all
209−motivated by tighter RFC 7159 compliance:
210−
211−* The parser now rejects numbers for which
212− [the integer portion contains a leading zero](https://github.com/bos/aeson/commit/3fb7c155f2255482b1b9566ec5c1eaf9895d630e).
213−* The parser now rejects numbers for which
214− [a decimal point is not followed by at least one digit](https://github.com/bos/aeson/commit/ecfca35a45286dbe2bbaf5f62354be393bc59b66),
215−* The parser now rejects documents that contain [whitespace outside the
216− set {space, newline, carriage return, tab}](https://github.com/bos/aeson/commit/8ef622c2ad8d4a109884e17c2792238a2a320e44).
217−
218−Over 90% of JSONTestSuite tests currently pass. The remainder can be
219−categorised as follows:
220−
221−* The string parser is strict with Unicode compliance where the RFC
222− leaves room for implementation-defined behaviour (tests prefixed
223− with "`i_string_`". (This is necessary because the `text` library
224− cannot accommodate invalid Unicode.)
225−
226−* The parser does not (and will not) support UTF-16, UTF-32, or byte
227− order marks (BOM).
228−* The parser accepts unescaped control characters, even though the RFC
229− states that control characters must be escaped. (This may change at
230− some point, but doesn't seem important.)
231−
232−#### 1.0.2.1
233−
234−* Fixes a regression where a bunch of valid characters caused an
235− "Invalid UTF8-Stream" error when decoding. Thanks to Vladimir
236− Shabanov who investigated and fixed this.
237−
238−### 1.0.2.0
239−
240−* Fixes a regression where it was no longer possible to derive
241− instances for types such as `data T a = T { f1 :: a, f2 :: Maybe a
242− }`.
243−
244−Thanks to Sean Leather for fixing this, and to Ryan Scott for helping out.
245−
246−### 1.0.1.0
247−
248−* Decoding performance has been significantly improved (see
249− https://github.com/bos/aeson/pull/452). Thanks to @winterland1989.
250−
251−* Add `ToJSON`/`FromJSON` instances for newtypes from
252− `Data.Semigroup`: `Min`, `Max`, `First`, `Last`, `WrappedMonoid`,
253− `Option`. Thanks to Lennart Spitzner.
254−
255−* Make the documentation for `.:!` more accurate. Thanks to Ian Jeffries.
5+* Add `ToJSON`/`FromJSON` instances for newtypes from `Data.Semigroup`:
6+ `Min`, `Max`, `First`, `Last`, `WrappedMonoid`, `Option`.
2567
2578# 1.0.0.0
2589
examples/Generic.hs+1−1
@@ -6,11 +6,11 @@
66-- automatically derive the Generic class for us.
77
88{-# LANGUAGE DeriveGeneric #-}
9−{-# LANGUAGE NoImplicitPrelude #-}
109{-# LANGUAGE OverloadedStrings #-}
1110
1211module Main (main) where
1312
13+import Prelude ()
1414import Prelude.Compat
1515
1616import Data.Aeson (FromJSON, ToJSON, decode, encode)
examples/Simplest.hs+1−1
@@ -1,9 +1,9 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21{-# LANGUAGE OverloadedStrings #-}
32{-# LANGUAGE RecordWildCards #-}
43
54module Main (main) where
65
6+import Prelude ()
77import Prelude.Compat
88
99import Control.Applicative (empty)
examples/TemplateHaskell.hs+1−1
@@ -1,12 +1,12 @@
11-- We can use Template Haskell (TH) to generate instances of the
22-- FromJSON and ToJSON classes automatically. This is the fastest way
33-- to add JSON support for a type.
4−{-# LANGUAGE NoImplicitPrelude #-}
54{-# LANGUAGE OverloadedStrings #-}
65{-# LANGUAGE TemplateHaskell #-}
76
87module Main (main) where
98
9+import Prelude ()
1010import Prelude.Compat
1111
1212import Data.Aeson (decode, encode)
examples/Twitter.hs+2−4
@@ -10,7 +10,6 @@
1010
1111{-# LANGUAGE DeriveDataTypeable #-}
1212{-# LANGUAGE DeriveGeneric #-}
13−{-# LANGUAGE NoImplicitPrelude #-}
1413
1514module Twitter
1615 (
@@ -20,6 +19,7 @@ module Twitter
2019 , Result(..)
2120 ) where
2221
22+import Prelude ()
2323import Prelude.Compat
2424
2525import Control.DeepSeq
@@ -27,9 +27,7 @@ import Data.Data (Typeable, Data)
2727import Data.Int (Int64)
2828import Data.Text (Text)
2929import GHC.Generics (Generic)
30−
31−{-# ANN module "Hlint: ignore Use camelCase" #-}
32−{-# ANN module "Hlint: ignore Use newtype instead of data" #-}
30+import Prelude hiding (id)
3331
3432data Metadata = Metadata {
3533 result_type :: Text
examples/Twitter/Generic.hs+37−31
@@ -1,7 +1,6 @@
11-- Use GHC generics to automatically generate good instances.
2−
3−{-# LANGUAGE NoImplicitPrelude #-}
4−
2+{-# LANGUAGE CPP #-}
3+{-# LANGUAGE PackageImports #-}
54{-# OPTIONS_GHC -fno-warn-orphans #-}
65
76module Twitter.Generic
@@ -12,33 +11,40 @@ module Twitter.Generic
1211 , Result(..)
1312 ) where
1413
15−import Prelude.Compat ()
14+import Prelude ()
15+import Prelude.Compat
1616
1717import Twitter
18−import Twitter.Options
19−
20−import Data.Aeson (ToJSON (..), FromJSON (..), genericToJSON, genericToEncoding, genericParseJSON)
21−
22−instance ToJSON Metadata where
23− toJSON = genericToJSON twitterOptions
24− toEncoding = genericToEncoding twitterOptions
25−instance FromJSON Metadata where
26− parseJSON = genericParseJSON twitterOptions
27−
28−instance ToJSON Geo where
29− toJSON = genericToJSON twitterOptions
30− toEncoding = genericToEncoding twitterOptions
31−instance FromJSON Geo where
32− parseJSON = genericParseJSON twitterOptions
33−
34−instance ToJSON Story where
35− toJSON = genericToJSON twitterOptions
36− toEncoding = genericToEncoding twitterOptions
37−instance FromJSON Story where
38− parseJSON = genericParseJSON twitterOptions
39−
40−instance ToJSON Result where
41− toJSON = genericToJSON twitterOptions
42− toEncoding = genericToEncoding twitterOptions
43−instance FromJSON Result where
44− parseJSON = genericParseJSON twitterOptions
18+
19+#ifndef HAS_BOTH_AESON_AND_BENCHMARKS
20+import Data.Aeson (ToJSON, FromJSON)
21+#else
22+import "aeson" Data.Aeson (ToJSON, FromJSON)
23+import qualified "aeson-benchmarks" Data.Aeson as B
24+#endif
25+
26+instance ToJSON Metadata
27+instance FromJSON Metadata
28+
29+instance ToJSON Geo
30+instance FromJSON Geo
31+
32+instance ToJSON Story
33+instance FromJSON Story
34+
35+instance ToJSON Result
36+instance FromJSON Result
37+
38+#ifdef HAS_BOTH_AESON_AND_BENCHMARKS
39+instance B.ToJSON Metadata
40+instance B.FromJSON Metadata
41+
42+instance B.ToJSON Geo
43+instance B.FromJSON Geo
44+
45+instance B.ToJSON Story
46+instance B.FromJSON Story
47+
48+instance B.ToJSON Result
49+instance B.FromJSON Result
50+#endif
examples/Twitter/Manual.hs+136−3
@@ -1,8 +1,9 @@
11-- Manually write instances.
2−{-# LANGUAGE NoImplicitPrelude #-}
2+
3+{-# LANGUAGE CPP #-}
4+{-# LANGUAGE PackageImports #-}
35{-# LANGUAGE OverloadedStrings #-}
46{-# LANGUAGE RecordWildCards #-}
5−
67{-# OPTIONS_GHC -fno-warn-orphans #-}
78
89module Twitter.Manual
@@ -13,13 +14,20 @@ module Twitter.Manual
1314 , Result(..)
1415 ) where
1516
17+import Prelude ()
1618import Prelude.Compat
1719
1820import Control.Applicative
19−import Data.Semigroup ((<>))
21+import Data.Monoid ((<>))
22+import Prelude hiding (id)
2023import Twitter
2124
25+#ifndef HAS_BOTH_AESON_AND_BENCHMARKS
2226import Data.Aeson hiding (Result)
27+#else
28+import "aeson" Data.Aeson hiding (Result)
29+import qualified "aeson-benchmarks" Data.Aeson as B
30+#endif
2331
2432instance ToJSON Metadata where
2533
@@ -144,3 +152,128 @@ instance FromJSON Result where
144152 <*> v .: "max_id_str"
145153 <*> v .: "query"
146154 parseJSON _ = empty
155+
156+#ifdef HAS_BOTH_AESON_AND_BENCHMARKS
157+instance B.ToJSON Metadata where
158+ toJSON Metadata{..} = B.object [
159+ "result_type" B..= result_type
160+ ]
161+
162+ toEncoding Metadata{..} = B.pairs $
163+ "result_type" B..= result_type
164+
165+instance B.FromJSON Metadata where
166+ parseJSON (B.Object v) = Metadata <$> v B..: "result_type"
167+ parseJSON _ = empty
168+
169+instance B.ToJSON Geo where
170+ toJSON Geo{..} = B.object [
171+ "type_" B..= type_
172+ , "coordinates" B..= coordinates
173+ ]
174+
175+ toEncoding Geo{..} = B.pairs $
176+ "type_" B..= type_
177+ <> "coordinates" B..= coordinates
178+
179+instance B.FromJSON Geo where
180+ parseJSON (B.Object v) = Geo <$>
181+ v B..: "type_"
182+ <*> v B..: "coordinates"
183+ parseJSON _ = empty
184+
185+instance B.ToJSON Story where
186+ toJSON Story{..} = B.object [
187+ "from_user_id_str" B..= from_user_id_str
188+ , "profile_image_url" B..= profile_image_url
189+ , "created_at" B..= created_at
190+ , "from_user" B..= from_user
191+ , "id_str" B..= id_str
192+ , "metadata" B..= metadata
193+ , "to_user_id" B..= to_user_id
194+ , "text" B..= text
195+ , "id" B..= id_
196+ , "from_user_id" B..= from_user_id
197+ , "geo" B..= geo
198+ , "iso_language_code" B..= iso_language_code
199+ , "to_user_id_str" B..= to_user_id_str
200+ , "source" B..= source
201+ ]
202+
203+ toEncoding Story{..} = B.pairs $
204+ "from_user_id_str" B..= from_user_id_str
205+ <> "profile_image_url" B..= profile_image_url
206+ <> "created_at" B..= created_at
207+ <> "from_user" B..= from_user
208+ <> "id_str" B..= id_str
209+ <> "metadata" B..= metadata
210+ <> "to_user_id" B..= to_user_id
211+ <> "text" B..= text
212+ <> "id" B..= id_
213+ <> "from_user_id" B..= from_user_id
214+ <> "geo" B..= geo
215+ <> "iso_language_code" B..= iso_language_code
216+ <> "to_user_id_str" B..= to_user_id_str
217+ <> "source" B..= source
218+
219+instance B.FromJSON Story where
220+ parseJSON (B.Object v) = Story <$>
221+ v B..: "from_user_id_str"
222+ <*> v B..: "profile_image_url"
223+ <*> v B..: "created_at"
224+ <*> v B..: "from_user"
225+ <*> v B..: "id_str"
226+ <*> v B..: "metadata"
227+ <*> v B..: "to_user_id"
228+ <*> v B..: "text"
229+ <*> v B..: "id"
230+ <*> v B..: "from_user_id"
231+ <*> v B..: "geo"
232+ <*> v B..: "iso_language_code"
233+ <*> v B..: "to_user_id_str"
234+ <*> v B..: "source"
235+ parseJSON _ = empty
236+
237+instance B.ToJSON Result where
238+ toJSON Result{..} = B.object [
239+ "results" B..= results
240+ , "max_id" B..= max_id
241+ , "since_id" B..= since_id
242+ , "refresh_url" B..= refresh_url
243+ , "next_page" B..= next_page
244+ , "results_per_page" B..= results_per_page
245+ , "page" B..= page
246+ , "completed_in" B..= completed_in
247+ , "since_id_str" B..= since_id_str
248+ , "max_id_str" B..= max_id_str
249+ , "query" B..= query
250+ ]
251+
252+ toEncoding Result{..} = B.pairs $
253+ "results" B..= results
254+ <> "max_id" B..= max_id
255+ <> "since_id" B..= since_id
256+ <> "refresh_url" B..= refresh_url
257+ <> "next_page" B..= next_page
258+ <> "results_per_page" B..= results_per_page
259+ <> "page" B..= page
260+ <> "completed_in" B..= completed_in
261+ <> "since_id_str" B..= since_id_str
262+ <> "max_id_str" B..= max_id_str
263+ <> "query" B..= query
264+
265+instance B.FromJSON Result where
266+ parseJSON (B.Object v) = Result <$>
267+ v B..: "results"
268+ <*> v B..: "max_id"
269+ <*> v B..: "since_id"
270+ <*> v B..: "refresh_url"
271+ <*> v B..: "next_page"
272+ <*> v B..: "results_per_page"
273+ <*> v B..: "page"
274+ <*> v B..: "completed_in"
275+ <*> v B..: "since_id_str"
276+ <*> v B..: "max_id_str"
277+ <*> v B..: "query"
278+ parseJSON _ = empty
279+#endif
examples/Twitter/Options.hsdeleted−10
@@ -1,10 +0,0 @@
1−module Twitter.Options (module Twitter.Options) where
2−
3−import Data.Aeson
4−
5−twitterOptions :: Options
6−twitterOptions = defaultOptions
7− { fieldLabelModifier = \x -> case x of
8− "id_" -> "id"
9− _ -> x
10− }
examples/Twitter/TH.hs+19−7
@@ -1,8 +1,8 @@
11-- Use Template Haskell to generate good instances.
22
3−{-# LANGUAGE NoImplicitPrelude #-}
3+{-# LANGUAGE CPP #-}
4+{-# LANGUAGE PackageImports #-}
45{-# LANGUAGE TemplateHaskell #-}
5−
66{-# OPTIONS_GHC -fno-warn-orphans #-}
77
88module Twitter.TH
@@ -13,13 +13,25 @@ module Twitter.TH
1313 , Result(..)
1414 ) where
1515
16+import Prelude ()
1617
1718import Twitter
18−import Twitter.Options
1919
20+#ifndef HAS_BOTH_AESON_AND_BENCHMARKS
2021import Data.Aeson.TH
22+#else
23+import "aeson" Data.Aeson.TH
24+import qualified "aeson-benchmarks" Data.Aeson.TH as B
25+#endif
26+
27+$(deriveJSON defaultOptions ''Metadata)
28+$(deriveJSON defaultOptions ''Geo)
29+$(deriveJSON defaultOptions ''Story)
30+$(deriveJSON defaultOptions ''Result)
2131
22−$(deriveJSON twitterOptions ''Metadata)
23−$(deriveJSON twitterOptions ''Geo)
24−$(deriveJSON twitterOptions ''Story)
25−$(deriveJSON twitterOptions ''Result)
32+#ifdef HAS_BOTH_AESON_AND_BENCHMARKS
33+$(B.deriveJSON B.defaultOptions ''Metadata)
34+$(B.deriveJSON B.defaultOptions ''Geo)
35+$(B.deriveJSON B.defaultOptions ''Story)
36+$(B.deriveJSON B.defaultOptions ''Result)
37+#endif
ffi/Data/Aeson/Parser/UnescapeFFI.hsdeleted−52
@@ -1,52 +0,0 @@
1−{-# LANGUAGE ForeignFunctionInterface #-}
2−{-# LANGUAGE MagicHash #-}
3−{-# LANGUAGE UnliftedFFITypes #-}
4−
5−module Data.Aeson.Parser.UnescapeFFI
6− (
7− unescapeText
8− ) where
9−
10−import Control.Exception (evaluate, throw, try)
11−import Control.Monad.ST.Unsafe (unsafeIOToST, unsafeSTToIO)
12−import Data.ByteString as B
13−import Data.ByteString.Internal as B
14−import Data.Text.Encoding.Error (UnicodeException (..))
15−import Data.Text.Internal (Text (..))
16−import Data.Text.Internal.Private (runText)
17−import Data.Text.Unsafe (unsafeDupablePerformIO)
18−import Data.Word (Word8)
19−import Foreign.C.Types (CInt (..), CSize (..))
20−import Foreign.ForeignPtr (withForeignPtr)
21−import Foreign.Marshal.Utils (with)
22−import Foreign.Ptr (Ptr, plusPtr)
23−import Foreign.Storable (peek)
24−import GHC.Base (MutableByteArray#)
25−import qualified Data.Text.Array as A
26−
27−foreign import ccall unsafe "_js_decode_string" c_js_decode
28− :: MutableByteArray# s -> Ptr CSize
29− -> Ptr Word8 -> Ptr Word8 -> IO CInt
30−
31−unescapeText' :: ByteString -> Text
32−unescapeText' (PS fp off len) = runText $ \done -> do
33− let go dest = withForeignPtr fp $ \ptr ->
34− with (0::CSize) $ \destOffPtr -> do
35− let end = ptr `plusPtr` (off + len)
36− loop curPtr = do
37− res <- c_js_decode (A.maBA dest) destOffPtr curPtr end
38− case res of
39− 0 -> do
40− n <- peek destOffPtr
41− unsafeSTToIO (done dest (fromIntegral n))
42− _ ->
43− throw (DecodeError desc Nothing)
44− loop (ptr `plusPtr` off)
45− (unsafeIOToST . go) =<< A.new len
46− where
47− desc = "Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream"
48−{-# INLINE unescapeText' #-}
49−
50−unescapeText :: ByteString -> Either UnicodeException Text
51−unescapeText = unsafeDupablePerformIO . try . evaluate . unescapeText'
52−{-# INLINE unescapeText #-}
include/incoherent-compat.hdeleted−7
@@ -1,7 +0,0 @@
1−#if __GLASGOW_HASKELL__ >= 710
2−#define INCOHERENT_ {-# INCOHERENT #-}
3−#else
4−-- This causes some type class instances to break:
5−-- {-# LANGUAGE IncoherentInstances #-}
6−#define INCOHERENT_
7−#endif
pure/Data/Aeson/Parser/UnescapePure.hsdeleted−254
@@ -1,254 +0,0 @@
1−-- WARNING: This file is security sensitive as it uses unsafeWrite which does
2−-- not check bounds. Any changes should be made with care and we would love to
3−-- get informed about them, just cc us in any PR targetting this file: @eskimor @jprider63
4−-- We would be happy to review the changes!
5−
6−-- The security check at the end (pos > length) only works if pos grows
7−-- monotonously, if this condition does not hold, the check is flawed.
8−module Data.Aeson.Parser.UnescapePure
9− (
10− unescapeText
11− ) where
12−
13−import Control.Exception (evaluate, throw, try)
14−import Control.Monad (when)
15−import Data.ByteString as B
16−import Data.Bits (Bits, shiftL, shiftR, (.&.), (.|.))
17−import Data.Text (Text)
18−import qualified Data.Text.Array as A
19−import Data.Text.Encoding.Error (UnicodeException (..))
20−import Data.Text.Internal.Private (runText)
21−import Data.Text.Unsafe (unsafeDupablePerformIO)
22−import Data.Word (Word8, Word16, Word32)
23−import GHC.ST (ST)
24−
25−-- Different UTF states.
26−data Utf =
27− UtfGround
28− | UtfTail1
29− | UtfU32e0
30− | UtfTail2
31− | UtfU32ed
32− | Utf843f0
33− | UtfTail3
34− | Utf843f4
35− deriving (Eq)
36−
37−data State =
38− StateNone
39− | StateUtf !Utf !Word32
40− | StateBackslash
41− | StateU0
42− | StateU1 !Word16
43− | StateU2 !Word16
44− | StateU3 !Word16
45− | StateS0
46− | StateS1
47− | StateSU0
48− | StateSU1 !Word16
49− | StateSU2 !Word16
50− | StateSU3 !Word16
51− deriving (Eq)
52−
53−-- References:
54−-- http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
55−-- https://github.com/jwilm/vte/blob/master/utf8parse/src/table.rs.in
56−
57−setByte1 :: (Num a, Bits b, Bits a, Integral b) => a -> b -> a
58−setByte1 point word = point .|. fromIntegral (word .&. 0x3f)
59−{-# INLINE setByte1 #-}
60−
61−setByte2 :: (Num a, Bits b, Bits a, Integral b) => a -> b -> a
62−setByte2 point word = point .|. (fromIntegral (word .&. 0x3f) `shiftL` 6)
63−{-# INLINE setByte2 #-}
64−
65−setByte2Top :: (Num a, Bits b, Bits a, Integral b) => a -> b -> a
66−setByte2Top point word = point .|. (fromIntegral (word .&. 0x1f) `shiftL` 6)
67−{-# INLINE setByte2Top #-}
68−
69−setByte3 :: (Num a, Bits b, Bits a, Integral b) => a -> b -> a
70−setByte3 point word = point .|. (fromIntegral (word .&. 0x3f) `shiftL` 12)
71−{-# INLINE setByte3 #-}
72−
73−setByte3Top :: (Num a, Bits b, Bits a, Integral b) => a -> b -> a
74−setByte3Top point word = point .|. (fromIntegral (word .&. 0xf) `shiftL` 12)
75−{-# INLINE setByte3Top #-}
76−
77−setByte4 :: (Num a, Bits b, Bits a, Integral b) => a -> b -> a
78−setByte4 point word = point .|. (fromIntegral (word .&. 0x7) `shiftL` 18)
79−{-# INLINE setByte4 #-}
80−
81−decode :: Utf -> Word32 -> Word8 -> (Utf, Word32)
82−decode UtfGround point word = case word of
83− w | 0x00 <= w && w <= 0x7f -> (UtfGround, fromIntegral word)
84− w | 0xc2 <= w && w <= 0xdf -> (UtfTail1, setByte2Top point word)
85− 0xe0 -> (UtfU32e0, setByte3Top point word)
86− w | 0xe1 <= w && w <= 0xec -> (UtfTail2, setByte3Top point word)
87− 0xed -> (UtfU32ed, setByte3Top point word)
88− w | 0xee <= w && w <= 0xef -> (UtfTail2, setByte3Top point word)
89− 0xf0 -> (Utf843f0, setByte4 point word)
90− w | 0xf1 <= w && w <= 0xf3 -> (UtfTail3, setByte4 point word)
91− 0xf4 -> (Utf843f4, setByte4 point word)
92− _ -> throwDecodeError
93−
94−decode UtfU32e0 point word = case word of
95− w | 0xa0 <= w && w <= 0xbf -> (UtfTail1, setByte2 point word)
96− _ -> throwDecodeError
97−
98−decode UtfU32ed point word = case word of
99− w | 0x80 <= w && w <= 0x9f -> (UtfTail1, setByte2 point word)
100− _ -> throwDecodeError
101−
102−decode Utf843f0 point word = case word of
103− w | 0x90 <= w && w <= 0xbf -> (UtfTail2, setByte3 point word)
104− _ -> throwDecodeError
105−
106−decode Utf843f4 point word = case word of
107− w | 0x80 <= w && w <= 0x8f -> (UtfTail2, setByte3 point word)
108− _ -> throwDecodeError
109−
110−decode UtfTail3 point word = case word of
111− w | 0x80 <= w && w <= 0xbf -> (UtfTail2, setByte3 point word)
112− _ -> throwDecodeError
113−
114−decode UtfTail2 point word = case word of
115− w | 0x80 <= w && w <= 0xbf -> (UtfTail1, setByte2 point word)
116− _ -> throwDecodeError
117−
118−decode UtfTail1 point word = case word of
119− w | 0x80 <= w && w <= 0xbf -> (UtfGround, setByte1 point word)
120− _ -> throwDecodeError
121−
122−decodeHex :: Word8 -> Word16
123−decodeHex x
124− | 48 <= x && x <= 57 = fromIntegral x - 48 -- 0-9
125− | 65 <= x && x <= 70 = fromIntegral x - 55 -- A-F
126− | 97 <= x && x <= 102 = fromIntegral x - 87 -- a-f
127− | otherwise = throwDecodeError
128−
129−unescapeText' :: ByteString -> Text
130−unescapeText' bs = runText $ \done -> do
131− dest <- A.new len
132−
133− (pos, finalState) <- loop dest (0, StateNone) 0
134−
135− -- Check final state. Currently pos gets only increased over time, so this check should catch overflows.
136− when ( finalState /= StateNone || pos > len)
137− throwDecodeError
138−
139− done dest pos -- TODO: pos, pos-1??? XXX
140−
141− where
142− len = B.length bs
143−
144− runUtf dest pos st point c = case decode st point c of
145− (UtfGround, 92) -> -- Backslash
146− return (pos, StateBackslash)
147− (UtfGround, w) | w <= 0xffff ->
148− writeAndReturn dest pos (fromIntegral w) StateNone
149− (UtfGround, w) -> do
150− write dest pos (0xd7c0 + fromIntegral (w `shiftR` 10))
151− writeAndReturn dest (pos + 1) (0xdc00 + fromIntegral (w .&. 0x3ff)) StateNone
152− (st', p) ->
153− return (pos, StateUtf st' p)
154−
155− loop :: A.MArray s -> (Int, State) -> Int -> ST s (Int, State)
156− loop _ ps i | i >= len = return ps
157− loop dest ps i = do
158− let c = B.index bs i -- JP: We can use unsafe index once we prove bounds with Liquid Haskell.
159− ps' <- f dest ps c
160− loop dest ps' $ i+1
161−
162− -- No pending state.
163− f dest (pos, StateNone) c = runUtf dest pos UtfGround 0 c
164−
165− -- In the middle of parsing a UTF string.
166− f dest (pos, StateUtf st point) c = runUtf dest pos st point c
167−
168− -- In the middle of escaping a backslash.
169− f dest (pos, StateBackslash) 34 = writeAndReturn dest pos 34 StateNone -- "
170− f dest (pos, StateBackslash) 92 = writeAndReturn dest pos 92 StateNone -- Backslash
171− f dest (pos, StateBackslash) 47 = writeAndReturn dest pos 47 StateNone -- /
172− f dest (pos, StateBackslash) 98 = writeAndReturn dest pos 8 StateNone -- b
173− f dest (pos, StateBackslash) 102 = writeAndReturn dest pos 12 StateNone -- f
174− f dest (pos, StateBackslash) 110 = writeAndReturn dest pos 10 StateNone -- n
175− f dest (pos, StateBackslash) 114 = writeAndReturn dest pos 13 StateNone -- r
176− f dest (pos, StateBackslash) 116 = writeAndReturn dest pos 9 StateNone -- t
177− f _ (pos, StateBackslash) 117 = return (pos, StateU0) -- u
178− f _ ( _, StateBackslash) _ = throwDecodeError
179−
180− -- Processing '\u'.
181− f _ (pos, StateU0) c =
182− let w = decodeHex c in
183− return (pos, StateU1 (w `shiftL` 12))
184−
185− f _ (pos, StateU1 w') c =
186− let w = decodeHex c in
187− return (pos, StateU2 (w' .|. (w `shiftL` 8)))
188−
189− f _ (pos, StateU2 w') c =
190− let w = decodeHex c in
191− return (pos, StateU3 (w' .|. (w `shiftL` 4)))
192−
193− f dest (pos, StateU3 w') c =
194− let w = decodeHex c in
195− let u = w' .|. w in
196−
197− -- Get next state based on surrogates.
198− let st
199− | u >= 0xd800 && u <= 0xdbff = -- High surrogate.
200− StateS0
201− | u >= 0xdc00 && u <= 0xdfff = -- Low surrogate.
202− throwDecodeError
203− | otherwise =
204− StateNone
205− in
206− writeAndReturn dest pos u st
207−
208− -- Handle surrogates.
209− f _ (pos, StateS0) 92 = return (pos, StateS1) -- Backslash
210− f _ ( _, StateS0) _ = throwDecodeError
211−
212− f _ (pos, StateS1) 117 = return (pos, StateSU0) -- u
213− f _ ( _, StateS1) _ = throwDecodeError
214−
215− f _ (pos, StateSU0) c =
216− let w = decodeHex c in
217− return (pos, StateSU1 (w `shiftL` 12))
218−
219− f _ (pos, StateSU1 w') c =
220− let w = decodeHex c in
221− return (pos, StateSU2 (w' .|. (w `shiftL` 8)))
222−
223− f _ (pos, StateSU2 w') c =
224− let w = decodeHex c in
225− return (pos, StateSU3 (w' .|. (w `shiftL` 4)))
226−
227− f dest (pos, StateSU3 w') c =
228− let w = decodeHex c in
229− let u = w' .|. w in
230−
231− -- Check if not low surrogate.
232− if u < 0xdc00 || u > 0xdfff then
233− throwDecodeError
234− else
235− writeAndReturn dest pos u StateNone
236−
237−write :: A.MArray s -> Int -> Word16 -> ST s ()
238−write dest pos char =
239− A.unsafeWrite dest pos char
240−{-# INLINE write #-}
241−
242−writeAndReturn :: A.MArray s -> Int -> Word16 -> t -> ST s (Int, t)
243−writeAndReturn dest pos char res = do
244− write dest pos char
245− return (pos + 1, res)
246−{-# INLINE writeAndReturn #-}
247−
248−throwDecodeError :: a
249−throwDecodeError =
250− let desc = "Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream" in
251− throw (DecodeError desc Nothing)
252−
253−unescapeText :: ByteString -> Either UnicodeException Text
254−unescapeText = unsafeDupablePerformIO . try . evaluate . unescapeText'
run-hlint.shdeleted−7
@@ -1,7 +0,0 @@
1−#!/bin/bash
2−
3−if hash hlint 2>/dev/null; then
4− hlint "$@"
5−else
6− ./hlint.sh "$@"
7−fi
stack-bench.yaml+6−10
@@ -1,12 +1,8 @@
1−resolver: nightly-2019-09-21
2−# We use aeson in the snapshot to
3−# - avoid recompilation of criterion
4−# - compare against it
5−# - '.'
6−#
7−# Also we use separate working directory to avoid "unregistering aeson"
8−# caused recompilations
9−work-dir: .stack-work-bench
1+resolver: lts-6.5
102packages:
113- benchmarks
12−extra-deps: []
4+extra-deps:
5+- semigroups-0.18.2
6+flags:
7+ semigroups:
8+ bytestring-builder: false
stack-ffi-unescape.yamldeleted−9
@@ -1,9 +0,0 @@
1−resolver: nightly-2019-09-21
2−packages:
3−- '.'
4−flags:
5− aeson:
6− fast: true
7− cffi: true
8−extra-deps:
9−- Diff-0.4.0
stack-lts12.yamldeleted−15
@@ -1,15 +0,0 @@
1−resolver: lts-12.26
2−packages:
3−- '.'
4−- attoparsec-iso8601
5−flags:
6− aeson:
7− fast: true
8− cffi: true
9−extra-deps:
10−- base-orphans-0.8.1
11−- hashable-time-0.2.0.1
12−- QuickCheck-2.13.1
13−- quickcheck-instances-0.3.21
14−- splitmix-0.0.2
15−- time-compat-1.9.2.2
stack-lts6.yamlnew file+12
@@ -0,0 +1,12 @@
1+resolver: lts-6.9
2+packages:
3+- '.'
4+- benchmarks
5+- examples
6+extra-deps:
7+- semigroups-0.18.2
8+flags:
9+ aeson:
10+ fast: true
11+ semigroups:
12+ bytestring-builder: false
stack-nightly.yaml+7−6
@@ -1,11 +1,12 @@
1−resolver: nightly-2019-10-14
1+resolver: nightly-2016-07-30
22packages:
33- '.'
4−- attoparsec-iso8601
4+- benchmarks
5+- examples
6+extra-deps:
7+- buffer-builder-0.2.4.3
8+- json-0.9.1
9+- json-builder-0.3
510flags:
611 aeson:
712 fast: true
8− attoparsec-iso8601:
9− fast: true
10−extra-deps:
11−- generic-deriving-1.12.4
tests/DataFamilies/Encoders.hs+2−2
@@ -1,10 +1,10 @@
11{-# LANGUAGE CPP #-}
22{-# LANGUAGE GADTs #-}
3−{-# LANGUAGE NoImplicitPrelude #-}
43{-# LANGUAGE TemplateHaskell #-}
54
6−module DataFamilies.Encoders (module DataFamilies.Encoders) where
5+module DataFamilies.Encoders where
76
7+import Prelude ()
88import Prelude.Compat
99
1010import Data.Aeson.TH
tests/DataFamilies/Instances.hs+1−2
@@ -1,13 +1,12 @@
11{-# LANGUAGE FlexibleInstances #-}
22{-# LANGUAGE GADTs #-}
3−{-# LANGUAGE NoImplicitPrelude #-}
43{-# LANGUAGE TemplateHaskell #-}
54{-# LANGUAGE TypeFamilies #-}
6−
75{-# OPTIONS_GHC -fno-warn-orphans #-}
86
97module DataFamilies.Instances () where
108
9+import Prelude ()
1110import Prelude.Compat
1211
1312import Data.Aeson.TH
tests/DataFamilies/Properties.hs+5−6
@@ -1,21 +1,20 @@
11{-# LANGUAGE CPP #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
32
43module DataFamilies.Properties (tests) where
54
5+import Prelude ()
66import Prelude.Compat
77
88import DataFamilies.Encoders
99import DataFamilies.Instances ()
10−import PropUtils
10+import Properties hiding (tests)
1111
12−
13−import Test.Tasty (TestTree, testGroup)
14−import Test.Tasty.QuickCheck (testProperty)
12+import Test.Framework (Test, testGroup)
13+import Test.Framework.Providers.QuickCheck2 (testProperty)
1514
1615--------------------------------------------------------------------------------
1716
18−tests :: TestTree
17+tests :: Test
1918tests = testGroup "data families" [
2019 testGroup "template-haskell" [
2120 testGroup "toJSON" [
tests/DataFamilies/Types.hs+2−2
@@ -4,13 +4,13 @@
44{-# LANGUAGE FlexibleInstances #-}
55{-# LANGUAGE GADTs #-}
66{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7−{-# LANGUAGE NoImplicitPrelude #-}
87{-# LANGUAGE StandaloneDeriving #-}
98{-# LANGUAGE TemplateHaskell #-}
109{-# LANGUAGE TypeFamilies #-}
1110
12−module DataFamilies.Types (module DataFamilies.Types) where
11+module DataFamilies.Types where
1312
13+import Prelude ()
1414import Prelude.Compat
1515
1616import Generics.Deriving.TH (deriveAll0)
tests/Encoders.hs+8−142
@@ -1,12 +1,11 @@
11{-# LANGUAGE CPP #-}
22{-# LANGUAGE GADTs #-}
3−{-# LANGUAGE NoImplicitPrelude #-}
43{-# LANGUAGE TemplateHaskell #-}
54
6−module Encoders (module Encoders) where
5+module Encoders where
76
7+import Prelude ()
88import Prelude.Compat
9−import Data.Text (Text)
109
1110import Data.Aeson.TH
1211import Data.Aeson.Types
@@ -97,18 +96,6 @@ gNullaryToEncodingObjectWithSingleField = genericToEncoding optsObjectWithSingle
9796gNullaryParseJSONObjectWithSingleField :: Value -> Parser Nullary
9897gNullaryParseJSONObjectWithSingleField = genericParseJSON optsObjectWithSingleField
9998
100−keyOptions :: JSONKeyOptions
101−keyOptions = defaultJSONKeyOptions { keyModifier = ('k' :) }
102−
103−gNullaryToJSONKey :: Nullary -> Either String Text
104−gNullaryToJSONKey x = case genericToJSONKey keyOptions of
105− ToJSONKeyText p _ -> Right (p x)
106− _ -> Left "Should be a ToJSONKeyText"
107−
108−gNullaryFromJSONKey :: Text -> Parser Nullary
109−gNullaryFromJSONKey t = case genericFromJSONKey keyOptions of
110− FromJSONKeyTextParser p -> p t
111− _ -> fail "Not a TextParser"
11299
113100--------------------------------------------------------------------------------
114101-- SomeType encoders/decoders
@@ -188,6 +175,7 @@ gSomeTypeToEncoding2ElemArray = genericToEncoding opts2ElemArray
188175gSomeTypeParseJSON2ElemArray :: Value -> Parser (SomeType Int)
189176gSomeTypeParseJSON2ElemArray = genericParseJSON opts2ElemArray
190177
178+#if __GLASGOW_HASKELL__ >= 706
191179gSomeTypeLiftToEncoding2ElemArray :: LiftToEncoding SomeType a
192180gSomeTypeLiftToEncoding2ElemArray = genericLiftToEncoding opts2ElemArray
193181
@@ -196,6 +184,7 @@ gSomeTypeLiftToJSON2ElemArray = genericLiftToJSON opts2ElemArray
196184
197185gSomeTypeLiftParseJSON2ElemArray :: LiftParseJSON SomeType a
198186gSomeTypeLiftParseJSON2ElemArray = genericLiftParseJSON opts2ElemArray
187+#endif
199188
200189
201190gSomeTypeToJSONTaggedObject :: SomeType Int -> Value
@@ -207,6 +196,7 @@ gSomeTypeToEncodingTaggedObject = genericToEncoding optsTaggedObject
207196gSomeTypeParseJSONTaggedObject :: Value -> Parser (SomeType Int)
208197gSomeTypeParseJSONTaggedObject = genericParseJSON optsTaggedObject
209198
199+#if __GLASGOW_HASKELL__ >= 706
210200gSomeTypeLiftToEncodingTaggedObject :: LiftToEncoding SomeType a
211201gSomeTypeLiftToEncodingTaggedObject = genericLiftToEncoding optsTaggedObject
212202
@@ -215,6 +205,7 @@ gSomeTypeLiftToJSONTaggedObject = genericLiftToJSON optsTaggedObject
215205
216206gSomeTypeLiftParseJSONTaggedObject :: LiftParseJSON SomeType a
217207gSomeTypeLiftParseJSONTaggedObject = genericLiftParseJSON optsTaggedObject
208+#endif
218209
219210
220211gSomeTypeToJSONObjectWithSingleField :: SomeType Int -> Value
@@ -226,6 +217,7 @@ gSomeTypeToEncodingObjectWithSingleField = genericToEncoding optsObjectWithSingl
226217gSomeTypeParseJSONObjectWithSingleField :: Value -> Parser (SomeType Int)
227218gSomeTypeParseJSONObjectWithSingleField = genericParseJSON optsObjectWithSingleField
228219
220+#if __GLASGOW_HASKELL__ >= 706
229221gSomeTypeLiftToEncodingObjectWithSingleField :: LiftToEncoding SomeType a
230222gSomeTypeLiftToEncodingObjectWithSingleField = genericLiftToEncoding optsObjectWithSingleField
231223
@@ -234,6 +226,7 @@ gSomeTypeLiftToJSONObjectWithSingleField = genericLiftToJSON optsObjectWithSingl
234226
235227gSomeTypeLiftParseJSONObjectWithSingleField :: LiftParseJSON SomeType a
236228gSomeTypeLiftParseJSONObjectWithSingleField = genericLiftParseJSON optsObjectWithSingleField
229+#endif
237230
238231
239232gSomeTypeToJSONOmitNothingFields :: SomeType Int -> Value
@@ -242,82 +235,6 @@ gSomeTypeToJSONOmitNothingFields = genericToJSON optsOmitNothingFields
242235gSomeTypeToEncodingOmitNothingFields :: SomeType Int -> Encoding
243236gSomeTypeToEncodingOmitNothingFields = genericToEncoding optsOmitNothingFields
244237
245−
246−thSomeTypeParseJSONRejectUnknownFields :: Value -> Parser (SomeType Int)
247−thSomeTypeParseJSONRejectUnknownFields = $(mkParseJSON optsRejectUnknownFields ''SomeType)
248−
249−gSomeTypeParseJSONRejectUnknownFields :: Value -> Parser (SomeType Int)
250−gSomeTypeParseJSONRejectUnknownFields = genericParseJSON optsRejectUnknownFields
251−
252−
253−--------------------------------------------------------------------------------
254−-- Foo decoders
255−--------------------------------------------------------------------------------
256−
257−thFooParseJSONRejectUnknownFields :: Value -> Parser Foo
258−thFooParseJSONRejectUnknownFields = $(mkParseJSON optsRejectUnknownFields ''Foo)
259−
260−gFooParseJSONRejectUnknownFields :: Value -> Parser Foo
261−gFooParseJSONRejectUnknownFields = genericParseJSON optsRejectUnknownFields
262−
263−
264−thFooParseJSONRejectUnknownFieldsTagged :: Value -> Parser Foo
265−thFooParseJSONRejectUnknownFieldsTagged = $(mkParseJSON optsRejectUnknownFieldsTagged ''Foo)
266−
267−gFooParseJSONRejectUnknownFieldsTagged :: Value -> Parser Foo
268−gFooParseJSONRejectUnknownFieldsTagged = genericParseJSON optsRejectUnknownFieldsTagged
269−
270−
271−--------------------------------------------------------------------------------
272−-- Option fields
273−--------------------------------------------------------------------------------
274−
275−thOptionFieldToJSON :: OptionField -> Value
276−thOptionFieldToJSON = $(mkToJSON optsOptionField 'OptionField)
277−
278−thOptionFieldToEncoding :: OptionField -> Encoding
279−thOptionFieldToEncoding = $(mkToEncoding optsOptionField 'OptionField)
280−
281−thOptionFieldParseJSON :: Value -> Parser OptionField
282−thOptionFieldParseJSON = $(mkParseJSON optsOptionField 'OptionField)
283−
284−gOptionFieldToJSON :: OptionField -> Value
285−gOptionFieldToJSON = genericToJSON optsOptionField
286−
287−gOptionFieldToEncoding :: OptionField -> Encoding
288−gOptionFieldToEncoding = genericToEncoding optsOptionField
289−
290−gOptionFieldParseJSON :: Value -> Parser OptionField
291−gOptionFieldParseJSON = genericParseJSON optsOptionField
292−
293−thMaybeFieldToJSON :: MaybeField -> Value
294−thMaybeFieldToJSON = $(mkToJSON optsOptionField 'MaybeField)
295−
296−
297−--------------------------------------------------------------------------------
298−-- IncoherentInstancesNeeded
299−--------------------------------------------------------------------------------
300−
301−-- | This test demonstrates the need for IncoherentInstances. See the definition
302−-- of 'IncoherentInstancesNeeded' for a discussion of the issue.
303−--
304−-- NOTE 1: We only need to compile this test. We do not need to run it.
305−--
306−-- NOTE 2: We actually only use the INCOHERENT pragma on specific instances
307−-- instead of the IncoherentInstances language extension. Therefore, this is
308−-- only supported on GHC versions >= 7.10.
309−#if __GLASGOW_HASKELL__ >= 710
310−incoherentInstancesNeededParseJSONString :: FromJSON a => Value -> Parser (IncoherentInstancesNeeded a)
311−incoherentInstancesNeededParseJSONString = case () of
312− _ | True -> $(mkParseJSON defaultOptions ''IncoherentInstancesNeeded)
313− | False -> genericParseJSON defaultOptions
314−
315−incoherentInstancesNeededToJSON :: ToJSON a => IncoherentInstancesNeeded a -> Value
316−incoherentInstancesNeededToJSON = case () of
317− _ | True -> $(mkToJSON defaultOptions ''IncoherentInstancesNeeded)
318− | False -> genericToJSON defaultOptions
319−#endif
320−
321238-------------------------------------------------------------------------------
322239-- EitherTextInt encoders/decodes
323240-------------------------------------------------------------------------------
@@ -405,54 +322,3 @@ thGADTToEncodingDefault = $(mkToEncoding defaultOptions ''GADT)
405322
406323thGADTParseJSONDefault :: Value -> Parser (GADT String)
407324thGADTParseJSONDefault = $(mkParseJSON defaultOptions ''GADT)
408−
409−--------------------------------------------------------------------------------
410−-- OneConstructor encoders/decoders
411−--------------------------------------------------------------------------------
412−
413−thOneConstructorToJSONDefault :: OneConstructor -> Value
414−thOneConstructorToJSONDefault = $(mkToJSON defaultOptions ''OneConstructor)
415−
416−thOneConstructorToEncodingDefault :: OneConstructor -> Encoding
417−thOneConstructorToEncodingDefault = $(mkToEncoding defaultOptions ''OneConstructor)
418−
419−thOneConstructorParseJSONDefault :: Value -> Parser OneConstructor
420−thOneConstructorParseJSONDefault = $(mkParseJSON defaultOptions ''OneConstructor)
421−
422−thOneConstructorToJSONTagged :: OneConstructor -> Value
423−thOneConstructorToJSONTagged = $(mkToJSON optsTagSingleConstructors ''OneConstructor)
424−
425−thOneConstructorToEncodingTagged :: OneConstructor -> Encoding
426−thOneConstructorToEncodingTagged = $(mkToEncoding optsTagSingleConstructors ''OneConstructor)
427−
428−thOneConstructorParseJSONTagged :: Value -> Parser OneConstructor
429−thOneConstructorParseJSONTagged = $(mkParseJSON optsTagSingleConstructors ''OneConstructor)
430−
431−
432−gOneConstructorToJSONDefault :: OneConstructor -> Value
433−gOneConstructorToJSONDefault = genericToJSON defaultOptions
434−
435−gOneConstructorToEncodingDefault :: OneConstructor -> Encoding
436−gOneConstructorToEncodingDefault = genericToEncoding defaultOptions
437−
438−gOneConstructorParseJSONDefault :: Value -> Parser OneConstructor
439−gOneConstructorParseJSONDefault = genericParseJSON defaultOptions
440−
441−gOneConstructorToJSONTagged :: OneConstructor -> Value
442−gOneConstructorToJSONTagged = genericToJSON optsTagSingleConstructors
443−
444−gOneConstructorToEncodingTagged :: OneConstructor -> Encoding
445−gOneConstructorToEncodingTagged = genericToEncoding optsTagSingleConstructors
446−
447−gOneConstructorParseJSONTagged :: Value -> Parser OneConstructor
448−gOneConstructorParseJSONTagged = genericParseJSON optsTagSingleConstructors
449−
450−--------------------------------------------------------------------------------
451−-- Product2 encoders/decoders
452−--------------------------------------------------------------------------------
453−
454−thProduct2ParseJSON :: Value -> Parser (Product2 Int Bool)
455−thProduct2ParseJSON = $(mkParseJSON defaultOptions ''Product2)
456−
457−gProduct2ParseJSON :: Value -> Parser (Product2 Int Bool)
458−gProduct2ParseJSON = genericParseJSON defaultOptions
tests/ErrorMessages.hsdeleted−224
@@ -1,224 +0,0 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
4−
5−module ErrorMessages
6− (
7− tests
8− ) where
9−
10−import Prelude.Compat
11−
12−import Data.Aeson (FromJSON(..), Value, json)
13−import Data.Aeson.Types (Parser)
14−import Data.Aeson.Parser (eitherDecodeWith)
15−import Data.Aeson.Internal (formatError, iparse)
16−import Data.Algorithm.Diff (PolyDiff (..), getGroupedDiff)
17−import Data.Proxy (Proxy(..))
18−import Data.Semigroup ((<>))
19−import Data.Sequence (Seq)
20−import Instances ()
21−import Numeric.Natural (Natural)
22−import Test.Tasty (TestTree, TestName)
23−import Test.Tasty.Golden.Advanced (goldenTest)
24−import qualified Data.ByteString.Lazy.Char8 as L
25−import qualified Data.HashMap.Strict as HM
26−
27−import Encoders
28−import Types
29−
30−tests :: [TestTree]
31−tests =
32− [ aesonGoldenTest "simple" "tests/golden/simple.expected" output
33− , aesonGoldenTest "generic" "tests/golden/generic.expected" (outputGeneric G)
34− ]
35−
36−output :: Output
37−output = concat
38− [ testFor "Int" (Proxy :: Proxy Int)
39− [ "\"\""
40− , "[]"
41− , "{}"
42− , "null"
43− ]
44−
45− , testFor "Integer" (Proxy :: Proxy Integer)
46− [ "44.44"
47− ]
48−
49− , testFor "Natural" (Proxy :: Proxy Natural)
50− [ "44.44"
51− , "-50"
52− ]
53−
54− , testFor "String" (Proxy :: Proxy String)
55− [ "1"
56− , "[]"
57− , "{}"
58− , "null"
59− ]
60−
61− , testFor "HashMap" (Proxy :: Proxy (HM.HashMap String Int))
62− [ "\"\""
63− , "[]"
64− ]
65−
66− -- issue #356
67− , testFor "Either" (Proxy :: Proxy (Int, Either (Int, Bool) ()))
68− [ "[1,{\"Left\":[2,3]}]"
69− ]
70−
71− -- issue #358
72− , testFor "Seq" (Proxy :: Proxy (Seq Int))
73− [ "[0,1,true]"
74− ]
75− ]
76−
77−data Choice = TH | G
78−
79−outputGeneric :: Choice -> Output
80−outputGeneric choice = concat
81− [ testWith "OneConstructor"
82− (select
83− thOneConstructorParseJSONDefault
84− gOneConstructorParseJSONDefault)
85− [ "\"X\""
86− , "[0]"
87− ]
88−
89− , testWith "Nullary"
90− (select
91− thNullaryParseJSONString
92− gNullaryParseJSONString)
93− [ "\"X\""
94− , "[]"
95− ]
96−
97− , testWithSomeType "SomeType (tagged)"
98− (select
99− thSomeTypeParseJSONTaggedObject
100− gSomeTypeParseJSONTaggedObject)
101− [ "{\"tag\": \"unary\", \"contents\": true}"
102− , "{\"tag\": \"unary\"}"
103− , "{\"tag\": \"record\"}"
104− , "{\"tag\": \"record\", \"testone\": true, \"testtwo\": null, \"testthree\": null}"
105− , "{\"tag\": \"X\"}"
106− , "{}"
107− , "[]"
108− ]
109−
110− , testWithSomeType "SomeType (single-field)"
111− (select
112− thSomeTypeParseJSONObjectWithSingleField
113− gSomeTypeParseJSONObjectWithSingleField)
114− [ "{\"unary\": {}}"
115− , "{\"unary\": []}"
116− , "{\"X\": []}"
117− , "{\"record\": {}, \"W\":{}}"
118− , "{}"
119− , "[]"
120− , "{\"unary\""
121− , "{\"unary\":"
122− , "{\"unary\":1"
123− ]
124−
125− , testWithSomeType "SomeType (two-element array)"
126− (select
127− thSomeTypeParseJSON2ElemArray
128− gSomeTypeParseJSON2ElemArray)
129− [ "[\"unary\", true]"
130− , "[\"record\", null]"
131− , "[\"X\", 0]"
132− , "[null, 0]"
133− , "[]"
134− , "{}"
135− , "[1"
136− , "[1,"
137− ]
138−
139− , testWithSomeType "SomeType (reject unknown fields)"
140− (select
141− thSomeTypeParseJSONRejectUnknownFields
142− gSomeTypeParseJSONRejectUnknownFields)
143− [ "{\"tag\": \"record\", \"testOne\": 1.0, \"testZero\": 1}"
144− , "{\"testZero\": 1}"
145− , "{\"tag\": \"record\", \"testone\": true, \"testtwo\": null, \"testthree\": null}"
146− ]
147−
148− , testWithFoo "Foo (reject unknown fields)"
149− (select
150− thFooParseJSONRejectUnknownFields
151− gFooParseJSONRejectUnknownFields)
152− [ "{\"tag\": \"foo\"}"
153− ]
154−
155− , testWithFoo "Foo (reject unknown fields, tagged single)"
156− (select
157− thFooParseJSONRejectUnknownFieldsTagged
158− gFooParseJSONRejectUnknownFieldsTagged)
159− [ "{\"tag\": \"foo\", \"unknownField\": 0}"
160− ]
161−
162− , testWith "EitherTextInt"
163− (select
164− thEitherTextIntParseJSONUntaggedValue
165− gEitherTextIntParseJSONUntaggedValue)
166− [ "\"X\""
167− , "[]"
168− ]
169−
170− , testWith "Product2 Int Bool"
171− (select
172− thProduct2ParseJSON
173− gProduct2ParseJSON)
174− [ "[1, null]"
175− , "[]"
176− , "{}"
177− ]
178− ]
179− where
180− select a b = case choice of
181− TH -> a
182− G -> b
183−
184−-- Test infrastructure
185−
186−type Output = [String]
187−
188−outputLine :: String -> Output
189−outputLine = pure
190−
191−aesonGoldenTest :: TestName -> FilePath -> Output -> TestTree
192−aesonGoldenTest name ref out = goldenTest name (L.readFile ref) act cmp upd
193− where
194− act = pure (L.pack (unlines out))
195− upd = L.writeFile ref
196− cmp x y | x == y = return Nothing
197− cmp x y = return $ Just $ unlines $
198− concatMap f (getGroupedDiff (L.lines x) (L.lines y))
199− where
200− f (First xs) = map (cons3 '-' . L.unpack) xs
201− f (Second ys) = map (cons3 '+' . L.unpack) ys
202− -- we print unchanged lines too. It shouldn't be a problem while we have
203− -- reasonably small examples
204− f (Both xs _) = map (cons3 ' ' . L.unpack) xs
205− -- we add three characters, so the changed lines are easier to spot
206− cons3 c cs = c : c : c : ' ' : cs
207−
208−testWith :: Show a => String -> (Value -> Parser a) -> [L.ByteString] -> Output
209−testWith name parser ts =
210− outputLine name <>
211− foldMap (\s ->
212− case eitherDecodeWith json (iparse parser) s of
213− Left err -> outputLine $ uncurry formatError err
214− Right a -> outputLine $ show a) ts
215−
216−testFor :: forall a proxy. (FromJSON a, Show a)
217− => String -> proxy a -> [L.ByteString] -> Output
218−testFor name _ = testWith name (parseJSON :: Value -> Parser a)
219−
220−testWithSomeType :: String -> (Value -> Parser (SomeType Int)) -> [L.ByteString] -> Output
221−testWithSomeType = testWith
222−
223−testWithFoo :: String -> (Value -> Parser Foo) -> [L.ByteString] -> Output
224−testWithFoo = testWith
tests/Functions.hs+1−2
@@ -1,11 +1,10 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−
31module Functions
42 (
53 approxEq
64 , approxEqWith
75 ) where
86
7+import Prelude ()
98import Prelude.Compat
109
1110approxEq :: (Fractional a, Ord a) => a -> a -> Bool
tests/Instances.hs+55−9
@@ -1,35 +1,48 @@
1+{-# LANGUAGE CPP #-}
12{-# LANGUAGE FlexibleContexts #-}
23{-# LANGUAGE FlexibleInstances #-}
3−{-# LANGUAGE NoImplicitPrelude #-}
44{-# LANGUAGE OverloadedStrings #-}
55{-# LANGUAGE RecordWildCards #-}
6−
6+{-# LANGUAGE StandaloneDeriving #-}
77{-# OPTIONS_GHC -fno-warn-orphans #-}
88
99module Instances () where
1010
11+import Prelude ()
1112import Prelude.Compat
1213
13−import Control.Applicative (empty)
14+import Control.Applicative (Const(..), empty)
1415import Control.Monad
1516import Data.Aeson.Types
1617import Data.Function (on)
18+import Data.Functor.Compose (Compose (..))
19+import Data.Functor.Identity (Identity (..))
20+import Data.List.NonEmpty (NonEmpty(..))
21+import Data.Proxy (Proxy(..))
22+import Data.Tagged (Tagged(..))
1723import Data.Time (ZonedTime(..), TimeZone(..))
1824import Data.Time.Clock (UTCTime(..))
25+import Data.Version
1926import Functions
20−import Test.QuickCheck (Arbitrary(..), elements, oneof)
27+import Test.QuickCheck (Arbitrary(..), getNonNegative, elements, listOf1, oneof, resize)
2128import Types
2229import qualified Data.DList as DList
2330import qualified Data.HashMap.Strict as HM
2431
2532import Data.Orphans ()
2633import Test.QuickCheck.Instances ()
34+#if MIN_VERSION_base(4,7,0)
2735import Data.Hashable.Time ()
36+#endif
37+
38+#if !MIN_VERSION_base(4,8,0) && !MIN_VERSION_QuickCheck(2,8,3)
39+import Numeric.Natural
40+#endif
2841
2942-- "System" types.
3043
3144instance Arbitrary DotNetTime where
32− arbitrary = DotNetTime `fmap` arbitrary
45+ arbitrary = DotNetTime `liftM` arbitrary
3346 shrink = map DotNetTime . shrink . fromDotNetTime
3447
3548-- | Compare timezone part only on 'timeZoneMinutes'
@@ -153,15 +166,48 @@ instance Arbitrary EitherTextInt where
153166instance Arbitrary (GADT String) where
154167 arbitrary = GADT <$> arbitrary
155168
156−instance Arbitrary OptionField where
157− arbitrary = OptionField <$> arbitrary
158−
159−
160169instance ApproxEq Char where
161170 (=~) = (==)
162171
163172instance (ApproxEq a) => ApproxEq [a] where
164173 a =~ b = length a == length b && all (uncurry (=~)) (zip a b)
165174
175+instance Arbitrary Version where
176+ arbitrary = makeVersion . fmap getNonNegative <$> resize 4 (listOf1 arbitrary)
177+
178+instance Arbitrary a => Arbitrary (NonEmpty a) where
179+ arbitrary = (:|) <$> arbitrary <*> arbitrary
180+
181+-- Version tags are deprecated, so we avoid using them in the Arbitrary
182+-- instance. However, the recommended constructor 'makeVersion' is not
183+-- exported by "Data.Version" until base-4.8.0.0. For previous versions,
184+-- a definition is given below.
185+
186+#if !MIN_VERSION_base(4,8,0)
187+makeVersion :: [Int] -> Version
188+makeVersion b = Version b []
189+#endif
190+
191+#if !MIN_VERSION_base(4,8,0) && !MIN_VERSION_QuickCheck(2,8,3)
192+instance Arbitrary Natural where
193+ arbitrary = fromInteger . abs <$> arbitrary
194+#endif
195+
196+instance Arbitrary (Proxy a) where
197+ arbitrary = pure Proxy
198+
199+instance Arbitrary b => Arbitrary (Tagged a b) where
200+ arbitrary = Tagged <$> arbitrary
201+
202+instance Arbitrary a => Arbitrary (Const a b) where
203+ arbitrary = Const <$> arbitrary
204+
166205instance Arbitrary a => Arbitrary (DList.DList a) where
167206 arbitrary = DList.fromList <$> arbitrary
207+
208+-- would like to have -- https://github.com/nick8325/quickcheck/issues/73
209+instance Arbitrary a => Arbitrary (Identity a) where
210+ arbitrary = Identity <$> arbitrary
211+
212+instance Arbitrary (f (g a)) => Arbitrary (Compose f g a) where
213+ arbitrary = Compose <$> arbitrary
tests/JSONTestSuite/LICENSEdeleted−21
@@ -1,21 +0,0 @@
1−MIT License
2−
3−Copyright (c) 2016 Nicolas Seriot
4−
5−Permission is hereby granted, free of charge, to any person obtaining a copy
6−of this software and associated documentation files (the "Software"), to deal
7−in the Software without restriction, including without limitation the rights
8−to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9−copies of the Software, and to permit persons to whom the Software is
10−furnished to do so, subject to the following conditions:
11−
12−The above copyright notice and this permission notice shall be included in all
13−copies or substantial portions of the Software.
14−
15−THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16−IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17−FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18−AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19−LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20−OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21−SOFTWARE.
tests/JSONTestSuite/README.mddeleted−50
@@ -1,50 +0,0 @@
1−# JSON Parsing Test Suite
2−A comprehensive test suite for RFC 7159 compliant JSON parsers
3−
4−This repository was created as an appendix to the article [Parsing JSON is a Minefield 💣](http://seriot.ch/parsing_json.php).
5−
6−**/parsers/**
7−
8−This directory contains several parsers and tiny wrappers to turn the parsers into JSON validators, by returning a specific value.
9−
10−- `0` the parser did accept the content
11−- `1` the parser did reject the content
12−- `>=1` the process did crash
13−- `timeout` happens after 5 seconds
14−
15−**/test\_parsing/**
16−
17−The name of these files tell if their contents should be accepted or rejected.
18−
19−- `y_` content must be accepted by parsers
20−- `n_` content must be rejected by parsers
21−- `i_` parsers are free to accept or reject content
22−
23−**/test\_transform/**
24−
25−These files contain weird structures and characters that parsers may understand differently, eg:
26−
27−- huge numbers
28−- dictionaries with similar keys
29−- NULL characters
30−- escaped invalid strings
31−
32−These files were used to produce `results/transform.html`.
33−
34−**/run_tests.py**
35−
36−Run all parsers with all files:
37−
38− $ python3 run_tests.py
39−
40−Run all parsers with a specific file:
41−
42− $ python3 run_tests.py file.json
43−
44−The script writes logs in `results/logs.txt`.
45−
46−The script then reads `logs.txt` and generates `results/parsing.html`.
47−
48−**/results/**
49−
50−<img src="results/pruned_results.png" alt="JSON Parsing Tests" />
tests/JSONTestSuite/parsers/test-AppleJSONSerialization/bin/test-AppleJSONSerializationdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization.xcodeproj/project.pbxprojdeleted−260
@@ -1,260 +0,0 @@
1−// !$*UTF8*$!
2−{
3− archiveVersion = 1;
4− classes = {
5− };
6− objectVersion = 46;
7− objects = {
8−
9−/* Begin PBXBuildFile section */
10− 03997F941D70CE0C0001C89F /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03997F931D70CE0C0001C89F /* main.swift */; };
11−/* End PBXBuildFile section */
12−
13−/* Begin PBXCopyFilesBuildPhase section */
14− 03997F8E1D70CE0C0001C89F /* CopyFiles */ = {
15− isa = PBXCopyFilesBuildPhase;
16− buildActionMask = 2147483647;
17− dstPath = /usr/share/man/man1/;
18− dstSubfolderSpec = 0;
19− files = (
20− );
21− runOnlyForDeploymentPostprocessing = 1;
22− };
23−/* End PBXCopyFilesBuildPhase section */
24−
25−/* Begin PBXFileReference section */
26− 03997F901D70CE0C0001C89F /* test-AppleJSONSerialization */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "test-AppleJSONSerialization"; sourceTree = BUILT_PRODUCTS_DIR; };
27− 03997F931D70CE0C0001C89F /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
28−/* End PBXFileReference section */
29−
30−/* Begin PBXFrameworksBuildPhase section */
31− 03997F8D1D70CE0C0001C89F /* Frameworks */ = {
32− isa = PBXFrameworksBuildPhase;
33− buildActionMask = 2147483647;
34− files = (
35− );
36− runOnlyForDeploymentPostprocessing = 0;
37− };
38−/* End PBXFrameworksBuildPhase section */
39−
40−/* Begin PBXGroup section */
41− 03997F871D70CE0C0001C89F = {
42− isa = PBXGroup;
43− children = (
44− 03997F921D70CE0C0001C89F /* test-AppleJSONSerialization */,
45− 03997F911D70CE0C0001C89F /* Products */,
46− );
47− sourceTree = "<group>";
48− };
49− 03997F911D70CE0C0001C89F /* Products */ = {
50− isa = PBXGroup;
51− children = (
52− 03997F901D70CE0C0001C89F /* test-AppleJSONSerialization */,
53− );
54− name = Products;
55− sourceTree = "<group>";
56− };
57− 03997F921D70CE0C0001C89F /* test-AppleJSONSerialization */ = {
58− isa = PBXGroup;
59− children = (
60− 03997F931D70CE0C0001C89F /* main.swift */,
61− );
62− path = "test-AppleJSONSerialization";
63− sourceTree = "<group>";
64− };
65−/* End PBXGroup section */
66−
67−/* Begin PBXNativeTarget section */
68− 03997F8F1D70CE0C0001C89F /* test-AppleJSONSerialization */ = {
69− isa = PBXNativeTarget;
70− buildConfigurationList = 03997F971D70CE0C0001C89F /* Build configuration list for PBXNativeTarget "test-AppleJSONSerialization" */;
71− buildPhases = (
72− 03997F8C1D70CE0C0001C89F /* Sources */,
73− 03997F8D1D70CE0C0001C89F /* Frameworks */,
74− 03997F8E1D70CE0C0001C89F /* CopyFiles */,
75− );
76− buildRules = (
77− );
78− dependencies = (
79− );
80− name = "test-AppleJSONSerialization";
81− productName = "test-AppleJSONSerialization";
82− productReference = 03997F901D70CE0C0001C89F /* test-AppleJSONSerialization */;
83− productType = "com.apple.product-type.tool";
84− };
85−/* End PBXNativeTarget section */
86−
87−/* Begin PBXProject section */
88− 03997F881D70CE0C0001C89F /* Project object */ = {
89− isa = PBXProject;
90− attributes = {
91− LastSwiftUpdateCheck = 0800;
92− LastUpgradeCheck = 0800;
93− ORGANIZATIONNAME = "Nicolas Seriot";
94− TargetAttributes = {
95− 03997F8F1D70CE0C0001C89F = {
96− CreatedOnToolsVersion = 8.0;
97− DevelopmentTeam = VBYRKYS73S;
98− ProvisioningStyle = Automatic;
99− };
100− };
101− };
102− buildConfigurationList = 03997F8B1D70CE0C0001C89F /* Build configuration list for PBXProject "test-AppleJSONSerialization" */;
103− compatibilityVersion = "Xcode 3.2";
104− developmentRegion = English;
105− hasScannedForEncodings = 0;
106− knownRegions = (
107− en,
108− );
109− mainGroup = 03997F871D70CE0C0001C89F;
110− productRefGroup = 03997F911D70CE0C0001C89F /* Products */;
111− projectDirPath = "";
112− projectRoot = "";
113− targets = (
114− 03997F8F1D70CE0C0001C89F /* test-AppleJSONSerialization */,
115− );
116− };
117−/* End PBXProject section */
118−
119−/* Begin PBXSourcesBuildPhase section */
120− 03997F8C1D70CE0C0001C89F /* Sources */ = {
121− isa = PBXSourcesBuildPhase;
122− buildActionMask = 2147483647;
123− files = (
124− 03997F941D70CE0C0001C89F /* main.swift in Sources */,
125− );
126− runOnlyForDeploymentPostprocessing = 0;
127− };
128−/* End PBXSourcesBuildPhase section */
129−
130−/* Begin XCBuildConfiguration section */
131− 03997F951D70CE0C0001C89F /* Debug */ = {
132− isa = XCBuildConfiguration;
133− buildSettings = {
134− ALWAYS_SEARCH_USER_PATHS = NO;
135− CLANG_ANALYZER_NONNULL = YES;
136− CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
137− CLANG_CXX_LIBRARY = "libc++";
138− CLANG_ENABLE_MODULES = YES;
139− CLANG_ENABLE_OBJC_ARC = YES;
140− CLANG_WARN_BOOL_CONVERSION = YES;
141− CLANG_WARN_CONSTANT_CONVERSION = YES;
142− CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
143− CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
144− CLANG_WARN_EMPTY_BODY = YES;
145− CLANG_WARN_ENUM_CONVERSION = YES;
146− CLANG_WARN_INFINITE_RECURSION = YES;
147− CLANG_WARN_INT_CONVERSION = YES;
148− CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
149− CLANG_WARN_SUSPICIOUS_MOVES = YES;
150− CLANG_WARN_UNREACHABLE_CODE = YES;
151− CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
152− CODE_SIGN_IDENTITY = "-";
153− COPY_PHASE_STRIP = NO;
154− DEBUG_INFORMATION_FORMAT = dwarf;
155− ENABLE_STRICT_OBJC_MSGSEND = YES;
156− ENABLE_TESTABILITY = YES;
157− GCC_C_LANGUAGE_STANDARD = gnu99;
158− GCC_DYNAMIC_NO_PIC = NO;
159− GCC_NO_COMMON_BLOCKS = YES;
160− GCC_OPTIMIZATION_LEVEL = 0;
161− GCC_PREPROCESSOR_DEFINITIONS = (
162− "DEBUG=1",
163− "$(inherited)",
164− );
165− GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
166− GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
167− GCC_WARN_UNDECLARED_SELECTOR = YES;
168− GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
169− GCC_WARN_UNUSED_FUNCTION = YES;
170− GCC_WARN_UNUSED_VARIABLE = YES;
171− MACOSX_DEPLOYMENT_TARGET = 10.11;
172− MTL_ENABLE_DEBUG_INFO = YES;
173− ONLY_ACTIVE_ARCH = YES;
174− SDKROOT = macosx;
175− SWIFT_OPTIMIZATION_LEVEL = "-Onone";
176− };
177− name = Debug;
178− };
179− 03997F961D70CE0C0001C89F /* Release */ = {
180− isa = XCBuildConfiguration;
181− buildSettings = {
182− ALWAYS_SEARCH_USER_PATHS = NO;
183− CLANG_ANALYZER_NONNULL = YES;
184− CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
185− CLANG_CXX_LIBRARY = "libc++";
186− CLANG_ENABLE_MODULES = YES;
187− CLANG_ENABLE_OBJC_ARC = YES;
188− CLANG_WARN_BOOL_CONVERSION = YES;
189− CLANG_WARN_CONSTANT_CONVERSION = YES;
190− CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
191− CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
192− CLANG_WARN_EMPTY_BODY = YES;
193− CLANG_WARN_ENUM_CONVERSION = YES;
194− CLANG_WARN_INFINITE_RECURSION = YES;
195− CLANG_WARN_INT_CONVERSION = YES;
196− CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
197− CLANG_WARN_SUSPICIOUS_MOVES = YES;
198− CLANG_WARN_UNREACHABLE_CODE = YES;
199− CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
200− CODE_SIGN_IDENTITY = "-";
201− COPY_PHASE_STRIP = NO;
202− DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
203− ENABLE_NS_ASSERTIONS = NO;
204− ENABLE_STRICT_OBJC_MSGSEND = YES;
205− GCC_C_LANGUAGE_STANDARD = gnu99;
206− GCC_NO_COMMON_BLOCKS = YES;
207− GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
208− GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
209− GCC_WARN_UNDECLARED_SELECTOR = YES;
210− GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
211− GCC_WARN_UNUSED_FUNCTION = YES;
212− GCC_WARN_UNUSED_VARIABLE = YES;
213− MACOSX_DEPLOYMENT_TARGET = 10.11;
214− MTL_ENABLE_DEBUG_INFO = NO;
215− SDKROOT = macosx;
216− };
217− name = Release;
218− };
219− 03997F981D70CE0C0001C89F /* Debug */ = {
220− isa = XCBuildConfiguration;
221− buildSettings = {
222− DEVELOPMENT_TEAM = VBYRKYS73S;
223− PRODUCT_NAME = "$(TARGET_NAME)";
224− SWIFT_VERSION = 3.0;
225− };
226− name = Debug;
227− };
228− 03997F991D70CE0C0001C89F /* Release */ = {
229− isa = XCBuildConfiguration;
230− buildSettings = {
231− DEVELOPMENT_TEAM = VBYRKYS73S;
232− PRODUCT_NAME = "$(TARGET_NAME)";
233− SWIFT_VERSION = 3.0;
234− };
235− name = Release;
236− };
237−/* End XCBuildConfiguration section */
238−
239−/* Begin XCConfigurationList section */
240− 03997F8B1D70CE0C0001C89F /* Build configuration list for PBXProject "test-AppleJSONSerialization" */ = {
241− isa = XCConfigurationList;
242− buildConfigurations = (
243− 03997F951D70CE0C0001C89F /* Debug */,
244− 03997F961D70CE0C0001C89F /* Release */,
245− );
246− defaultConfigurationIsVisible = 0;
247− defaultConfigurationName = Release;
248− };
249− 03997F971D70CE0C0001C89F /* Build configuration list for PBXNativeTarget "test-AppleJSONSerialization" */ = {
250− isa = XCConfigurationList;
251− buildConfigurations = (
252− 03997F981D70CE0C0001C89F /* Debug */,
253− 03997F991D70CE0C0001C89F /* Release */,
254− );
255− defaultConfigurationIsVisible = 0;
256− };
257−/* End XCConfigurationList section */
258− };
259− rootObject = 03997F881D70CE0C0001C89F /* Project object */;
260−}
tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7
@@ -1,7 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<Workspace
3− version = "1.0">
4− <FileRef
5− location = "self:test-AppleJSONSerialization.xcodeproj">
6− </FileRef>
7−</Workspace>
tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test-AppleJSONSerialization.xcschemedeleted−91
@@ -1,91 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<Scheme
3− LastUpgradeVersion = "0800"
4− version = "1.3">
5− <BuildAction
6− parallelizeBuildables = "YES"
7− buildImplicitDependencies = "YES">
8− <BuildActionEntries>
9− <BuildActionEntry
10− buildForTesting = "YES"
11− buildForRunning = "YES"
12− buildForProfiling = "YES"
13− buildForArchiving = "YES"
14− buildForAnalyzing = "YES">
15− <BuildableReference
16− BuildableIdentifier = "primary"
17− BlueprintIdentifier = "03997F8F1D70CE0C0001C89F"
18− BuildableName = "test-AppleJSONSerialization"
19− BlueprintName = "test-AppleJSONSerialization"
20− ReferencedContainer = "container:test-AppleJSONSerialization.xcodeproj">
21− </BuildableReference>
22− </BuildActionEntry>
23− </BuildActionEntries>
24− </BuildAction>
25− <TestAction
26− buildConfiguration = "Debug"
27− selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28− selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29− shouldUseLaunchSchemeArgsEnv = "YES">
30− <Testables>
31− </Testables>
32− <MacroExpansion>
33− <BuildableReference
34− BuildableIdentifier = "primary"
35− BlueprintIdentifier = "03997F8F1D70CE0C0001C89F"
36− BuildableName = "test-AppleJSONSerialization"
37− BlueprintName = "test-AppleJSONSerialization"
38− ReferencedContainer = "container:test-AppleJSONSerialization.xcodeproj">
39− </BuildableReference>
40− </MacroExpansion>
41− <AdditionalOptions>
42− </AdditionalOptions>
43− </TestAction>
44− <LaunchAction
45− buildConfiguration = "Debug"
46− selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
47− selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
48− launchStyle = "0"
49− useCustomWorkingDirectory = "NO"
50− ignoresPersistentStateOnLaunch = "NO"
51− debugDocumentVersioning = "YES"
52− debugServiceExtension = "internal"
53− allowLocationSimulation = "YES">
54− <BuildableProductRunnable
55− runnableDebuggingMode = "0">
56− <BuildableReference
57− BuildableIdentifier = "primary"
58− BlueprintIdentifier = "03997F8F1D70CE0C0001C89F"
59− BuildableName = "test-AppleJSONSerialization"
60− BlueprintName = "test-AppleJSONSerialization"
61− ReferencedContainer = "container:test-AppleJSONSerialization.xcodeproj">
62− </BuildableReference>
63− </BuildableProductRunnable>
64− <AdditionalOptions>
65− </AdditionalOptions>
66− </LaunchAction>
67− <ProfileAction
68− buildConfiguration = "Release"
69− shouldUseLaunchSchemeArgsEnv = "YES"
70− savedToolIdentifier = ""
71− useCustomWorkingDirectory = "NO"
72− debugDocumentVersioning = "YES">
73− <BuildableProductRunnable
74− runnableDebuggingMode = "0">
75− <BuildableReference
76− BuildableIdentifier = "primary"
77− BlueprintIdentifier = "03997F8F1D70CE0C0001C89F"
78− BuildableName = "test-AppleJSONSerialization"
79− BlueprintName = "test-AppleJSONSerialization"
80− ReferencedContainer = "container:test-AppleJSONSerialization.xcodeproj">
81− </BuildableReference>
82− </BuildableProductRunnable>
83− </ProfileAction>
84− <AnalyzeAction
85− buildConfiguration = "Debug">
86− </AnalyzeAction>
87− <ArchiveAction
88− buildConfiguration = "Release"
89− revealArchiveInOrganizer = "YES">
90− </ArchiveAction>
91−</Scheme>
tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22
@@ -1,22 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3−<plist version="1.0">
4−<dict>
5− <key>SchemeUserState</key>
6− <dict>
7− <key>test-AppleJSONSerialization.xcscheme</key>
8− <dict>
9− <key>orderHint</key>
10− <integer>0</integer>
11− </dict>
12− </dict>
13− <key>SuppressBuildableAutocreation</key>
14− <dict>
15− <key>03997F8F1D70CE0C0001C89F</key>
16− <dict>
17− <key>primary</key>
18− <true/>
19− </dict>
20− </dict>
21−</dict>
22−</plist>
tests/JSONTestSuite/parsers/test-AppleJSONSerialization/test-AppleJSONSerialization/main.swiftdeleted−34
@@ -1,34 +0,0 @@
1−//
2−// main.swift
3−// test-AppleJSONSerialization
4−//
5−// Created by nst on 26/08/16.
6−// Copyright © 2016 Nicolas Seriot. All rights reserved.
7−//
8−
9−import Foundation
10−
11−func main() {
12−
13− guard ProcessInfo.processInfo.arguments.count == 2 else {
14− let url = NSURL(fileURLWithPath: ProcessInfo.processInfo.arguments[0])
15− guard let programName = url.lastPathComponent else { exit(1) }
16− print("Usage: ./\(programName) file.json")
17− exit(1)
18− }
19−
20− let path = ProcessInfo.processInfo.arguments[1]
21− let url = NSURL.fileURL(withPath:path)
22−
23− do {
24− let data = try Data(contentsOf:url)
25−
26− let _ = try JSONSerialization.jsonObject(with: data, options: [.allowFragments])
27−
28− exit(0)
29− } catch {
30− exit(1)
31− }
32−}
33−
34−main()
tests/JSONTestSuite/parsers/test_Bash_JSON/JSON.shdeleted−208
@@ -1,208 +0,0 @@
1−#!/bin/sh
2−
3−throw() {
4− echo "$*" >&2
5− exit 1
6−}
7−
8−BRIEF=0
9−LEAFONLY=0
10−PRUNE=0
11−NO_HEAD=0
12−NORMALIZE_SOLIDUS=0
13−
14−usage() {
15− echo
16− echo "Usage: JSON.sh [-b] [-l] [-p] [-s] [-h]"
17− echo
18− echo "-p - Prune empty. Exclude fields with empty values."
19− echo "-l - Leaf only. Only show leaf nodes, which stops data duplication."
20− echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options."
21− echo "-n - No-head. Do not show nodes that have no path (lines that start with [])."
22− echo "-s - Remove escaping of the solidus symbol (straight slash)."
23− echo "-h - This help text."
24− echo
25−}
26−
27−parse_options() {
28− set -- "$@"
29− local ARGN=$#
30− while [ "$ARGN" -ne 0 ]
31− do
32− case $1 in
33− -h) usage
34− exit 0
35− ;;
36− -b) BRIEF=1
37− LEAFONLY=1
38− PRUNE=1
39− ;;
40− -l) LEAFONLY=1
41− ;;
42− -p) PRUNE=1
43− ;;
44− -n) NO_HEAD=1
45− ;;
46− -s) NORMALIZE_SOLIDUS=1
47− ;;
48− ?*) echo "ERROR: Unknown option."
49− usage
50− exit 0
51− ;;
52− esac
53− shift 1
54− ARGN=$((ARGN-1))
55− done
56−}
57−
58−awk_egrep () {
59− local pattern_string=$1
60−
61− gawk '{
62− while ($0) {
63− start=match($0, pattern);
64− token=substr($0, start, RLENGTH);
65− print token;
66− $0=substr($0, start+RLENGTH);
67− }
68− }' pattern="$pattern_string"
69−}
70−
71−tokenize () {
72− local GREP
73− local ESCAPE
74− local CHAR
75−
76− if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1
77− then
78− GREP='egrep -ao --color=never'
79− else
80− GREP='egrep -ao'
81− fi
82−
83− if echo "test string" | egrep -o "test" >/dev/null 2>&1
84− then
85− ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
86− CHAR='[^[:cntrl:]"\\]'
87− else
88− GREP=awk_egrep
89− ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
90− CHAR='[^[:cntrl:]"\\\\]'
91− fi
92−
93− local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
94− local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
95− local KEYWORD='null|false|true'
96− local SPACE='[[:space:]]+'
97−
98− # Force zsh to expand $A into multiple words
99− local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$')
100− if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi
101− $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$"
102− if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi
103−}
104−
105−parse_array () {
106− local index=0
107− local ary=''
108− read -r token
109− case "$token" in
110− ']') ;;
111− *)
112− while :
113− do
114− parse_value "$1" "$index"
115− index=$((index+1))
116− ary="$ary""$value"
117− read -r token
118− case "$token" in
119− ']') break ;;
120− ',') ary="$ary," ;;
121− *) throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
122− esac
123− read -r token
124− done
125− ;;
126− esac
127− [ "$BRIEF" -eq 0 ] && value=$(printf '[%s]' "$ary") || value=
128− :
129−}
130−
131−parse_object () {
132− local key
133− local obj=''
134− read -r token
135− case "$token" in
136− '}') ;;
137− *)
138− while :
139− do
140− case "$token" in
141− '"'*'"') key=$token ;;
142− *) throw "EXPECTED string GOT ${token:-EOF}" ;;
143− esac
144− read -r token
145− case "$token" in
146− ':') ;;
147− *) throw "EXPECTED : GOT ${token:-EOF}" ;;
148− esac
149− read -r token
150− parse_value "$1" "$key"
151− obj="$obj$key:$value"
152− read -r token
153− case "$token" in
154− '}') break ;;
155− ',') obj="$obj," ;;
156− *) throw "EXPECTED , or } GOT ${token:-EOF}" ;;
157− esac
158− read -r token
159− done
160− ;;
161− esac
162− [ "$BRIEF" -eq 0 ] && value=$(printf '{%s}' "$obj") || value=
163− :
164−}
165−
166−parse_value () {
167− local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0
168− case "$token" in
169− '{') parse_object "$jpath" ;;
170− '[') parse_array "$jpath" ;;
171− # At this point, the only valid single-character tokens are digits.
172− ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;;
173− *) value=$token
174− # if asked, replace solidus ("\/") in json strings with normalized value: "/"
175− [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g')
176− isleaf=1
177− [ "$value" = '""' ] && isempty=1
178− ;;
179− esac
180− [ "$value" = '' ] && return
181− [ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return
182−
183− [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1
184− [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1
185− [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1
186− [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \
187− [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1
188− [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value"
189− :
190−}
191−
192−parse () {
193− read -r token
194− parse_value
195− read -r token
196− case "$token" in
197− '') ;;
198− *) throw "EXPECTED EOF GOT $token" ;;
199− esac
200−}
201−
202−if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]);
203−then
204− parse_options "$@"
205− tokenize | parse
206−fi
207−
208−# vi: expandtab sw=2 ts=2
tests/JSONTestSuite/parsers/test_Freddy_20160830/bin/test_Freddydeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/project.pbxprojdeleted−300
@@ -1,300 +0,0 @@
1−// !$*UTF8*$!
2−{
3− archiveVersion = 1;
4− classes = {
5− };
6− objectVersion = 46;
7− objects = {
8−
9−/* Begin PBXBuildFile section */
10− 03D84ABB1D5B0A1000776402 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D84ABA1D5B0A1000776402 /* main.swift */; };
11− 03F8F7811D5B75600021630C /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F7781D5B75600021630C /* JSON.swift */; };
12− 03F8F7821D5B75600021630C /* JSONDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F7791D5B75600021630C /* JSONDecodable.swift */; };
13− 03F8F7831D5B75600021630C /* JSONEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77A1D5B75600021630C /* JSONEncodable.swift */; };
14− 03F8F7841D5B75600021630C /* JSONEncodingDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77B1D5B75600021630C /* JSONEncodingDetector.swift */; };
15− 03F8F7851D5B75600021630C /* JSONLiteralConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77C1D5B75600021630C /* JSONLiteralConvertible.swift */; };
16− 03F8F7861D5B75600021630C /* JSONParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77D1D5B75600021630C /* JSONParser.swift */; };
17− 03F8F7871D5B75600021630C /* JSONParsing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77E1D5B75600021630C /* JSONParsing.swift */; };
18− 03F8F7881D5B75600021630C /* JSONSerializing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77F1D5B75600021630C /* JSONSerializing.swift */; };
19− 03F8F7891D5B75600021630C /* JSONSubscripting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F7801D5B75600021630C /* JSONSubscripting.swift */; };
20−/* End PBXBuildFile section */
21−
22−/* Begin PBXCopyFilesBuildPhase section */
23− 03D84AB51D5B0A1000776402 /* CopyFiles */ = {
24− isa = PBXCopyFilesBuildPhase;
25− buildActionMask = 2147483647;
26− dstPath = /usr/share/man/man1;
27− dstSubfolderSpec = 0;
28− files = (
29− );
30− runOnlyForDeploymentPostprocessing = 1;
31− };
32−/* End PBXCopyFilesBuildPhase section */
33−
34−/* Begin PBXFileReference section */
35− 03D84AB71D5B0A1000776402 /* test_Freddy */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = test_Freddy; sourceTree = BUILT_PRODUCTS_DIR; };
36− 03D84ABA1D5B0A1000776402 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
37− 03F8F7781D5B75600021630C /* JSON.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSON.swift; path = test_Freddy/JSON.swift; sourceTree = "<group>"; };
38− 03F8F7791D5B75600021630C /* JSONDecodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONDecodable.swift; path = test_Freddy/JSONDecodable.swift; sourceTree = "<group>"; };
39− 03F8F77A1D5B75600021630C /* JSONEncodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONEncodable.swift; path = test_Freddy/JSONEncodable.swift; sourceTree = "<group>"; };
40− 03F8F77B1D5B75600021630C /* JSONEncodingDetector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONEncodingDetector.swift; path = test_Freddy/JSONEncodingDetector.swift; sourceTree = "<group>"; };
41− 03F8F77C1D5B75600021630C /* JSONLiteralConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONLiteralConvertible.swift; path = test_Freddy/JSONLiteralConvertible.swift; sourceTree = "<group>"; };
42− 03F8F77D1D5B75600021630C /* JSONParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONParser.swift; path = test_Freddy/JSONParser.swift; sourceTree = "<group>"; };
43− 03F8F77E1D5B75600021630C /* JSONParsing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONParsing.swift; path = test_Freddy/JSONParsing.swift; sourceTree = "<group>"; };
44− 03F8F77F1D5B75600021630C /* JSONSerializing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONSerializing.swift; path = test_Freddy/JSONSerializing.swift; sourceTree = "<group>"; };
45− 03F8F7801D5B75600021630C /* JSONSubscripting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONSubscripting.swift; path = test_Freddy/JSONSubscripting.swift; sourceTree = "<group>"; };
46−/* End PBXFileReference section */
47−
48−/* Begin PBXFrameworksBuildPhase section */
49− 03D84AB41D5B0A1000776402 /* Frameworks */ = {
50− isa = PBXFrameworksBuildPhase;
51− buildActionMask = 2147483647;
52− files = (
53− );
54− runOnlyForDeploymentPostprocessing = 0;
55− };
56−/* End PBXFrameworksBuildPhase section */
57−
58−/* Begin PBXGroup section */
59− 03D84AAE1D5B0A1000776402 = {
60− isa = PBXGroup;
61− children = (
62− 03F8F7781D5B75600021630C /* JSON.swift */,
63− 03F8F7791D5B75600021630C /* JSONDecodable.swift */,
64− 03F8F77A1D5B75600021630C /* JSONEncodable.swift */,
65− 03F8F77B1D5B75600021630C /* JSONEncodingDetector.swift */,
66− 03F8F77C1D5B75600021630C /* JSONLiteralConvertible.swift */,
67− 03F8F77D1D5B75600021630C /* JSONParser.swift */,
68− 03F8F77E1D5B75600021630C /* JSONParsing.swift */,
69− 03F8F77F1D5B75600021630C /* JSONSerializing.swift */,
70− 03F8F7801D5B75600021630C /* JSONSubscripting.swift */,
71− 03D84AB91D5B0A1000776402 /* test_Freddy */,
72− 03D84AB81D5B0A1000776402 /* Products */,
73− );
74− sourceTree = "<group>";
75− };
76− 03D84AB81D5B0A1000776402 /* Products */ = {
77− isa = PBXGroup;
78− children = (
79− 03D84AB71D5B0A1000776402 /* test_Freddy */,
80− );
81− name = Products;
82− sourceTree = "<group>";
83− };
84− 03D84AB91D5B0A1000776402 /* test_Freddy */ = {
85− isa = PBXGroup;
86− children = (
87− 03D84ABA1D5B0A1000776402 /* main.swift */,
88− );
89− path = test_Freddy;
90− sourceTree = "<group>";
91− };
92−/* End PBXGroup section */
93−
94−/* Begin PBXNativeTarget section */
95− 03D84AB61D5B0A1000776402 /* test_Freddy */ = {
96− isa = PBXNativeTarget;
97− buildConfigurationList = 03D84ABE1D5B0A1000776402 /* Build configuration list for PBXNativeTarget "test_Freddy" */;
98− buildPhases = (
99− 03D84AB31D5B0A1000776402 /* Sources */,
100− 03D84AB41D5B0A1000776402 /* Frameworks */,
101− 03D84AB51D5B0A1000776402 /* CopyFiles */,
102− );
103− buildRules = (
104− );
105− dependencies = (
106− );
107− name = test_Freddy;
108− productName = test_Freddy;
109− productReference = 03D84AB71D5B0A1000776402 /* test_Freddy */;
110− productType = "com.apple.product-type.tool";
111− };
112−/* End PBXNativeTarget section */
113−
114−/* Begin PBXProject section */
115− 03D84AAF1D5B0A1000776402 /* Project object */ = {
116− isa = PBXProject;
117− attributes = {
118− LastSwiftUpdateCheck = 0800;
119− LastUpgradeCheck = 0800;
120− ORGANIZATIONNAME = "Nicolas Seriot";
121− TargetAttributes = {
122− 03D84AB61D5B0A1000776402 = {
123− CreatedOnToolsVersion = 8.0;
124− DevelopmentTeam = VBYRKYS73S;
125− DevelopmentTeamName = "Nicolas Seriot";
126− ProvisioningStyle = Automatic;
127− };
128− };
129− };
130− buildConfigurationList = 03D84AB21D5B0A1000776402 /* Build configuration list for PBXProject "test_Freddy" */;
131− compatibilityVersion = "Xcode 3.2";
132− developmentRegion = English;
133− hasScannedForEncodings = 0;
134− knownRegions = (
135− en,
136− );
137− mainGroup = 03D84AAE1D5B0A1000776402;
138− productRefGroup = 03D84AB81D5B0A1000776402 /* Products */;
139− projectDirPath = "";
140− projectRoot = "";
141− targets = (
142− 03D84AB61D5B0A1000776402 /* test_Freddy */,
143− );
144− };
145−/* End PBXProject section */
146−
147−/* Begin PBXSourcesBuildPhase section */
148− 03D84AB31D5B0A1000776402 /* Sources */ = {
149− isa = PBXSourcesBuildPhase;
150− buildActionMask = 2147483647;
151− files = (
152− 03F8F7881D5B75600021630C /* JSONSerializing.swift in Sources */,
153− 03F8F7821D5B75600021630C /* JSONDecodable.swift in Sources */,
154− 03F8F7851D5B75600021630C /* JSONLiteralConvertible.swift in Sources */,
155− 03F8F7871D5B75600021630C /* JSONParsing.swift in Sources */,
156− 03F8F7861D5B75600021630C /* JSONParser.swift in Sources */,
157− 03F8F7831D5B75600021630C /* JSONEncodable.swift in Sources */,
158− 03D84ABB1D5B0A1000776402 /* main.swift in Sources */,
159− 03F8F7811D5B75600021630C /* JSON.swift in Sources */,
160− 03F8F7891D5B75600021630C /* JSONSubscripting.swift in Sources */,
161− 03F8F7841D5B75600021630C /* JSONEncodingDetector.swift in Sources */,
162− );
163− runOnlyForDeploymentPostprocessing = 0;
164− };
165−/* End PBXSourcesBuildPhase section */
166−
167−/* Begin XCBuildConfiguration section */
168− 03D84ABC1D5B0A1000776402 /* Debug */ = {
169− isa = XCBuildConfiguration;
170− buildSettings = {
171− ALWAYS_SEARCH_USER_PATHS = NO;
172− CLANG_ANALYZER_NONNULL = YES;
173− CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
174− CLANG_CXX_LIBRARY = "libc++";
175− CLANG_ENABLE_MODULES = YES;
176− CLANG_ENABLE_OBJC_ARC = YES;
177− CLANG_WARN_BOOL_CONVERSION = YES;
178− CLANG_WARN_CONSTANT_CONVERSION = YES;
179− CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
180− CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
181− CLANG_WARN_EMPTY_BODY = YES;
182− CLANG_WARN_ENUM_CONVERSION = YES;
183− CLANG_WARN_INT_CONVERSION = YES;
184− CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
185− CLANG_WARN_UNREACHABLE_CODE = YES;
186− CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
187− CODE_SIGN_IDENTITY = "-";
188− COPY_PHASE_STRIP = NO;
189− DEBUG_INFORMATION_FORMAT = dwarf;
190− ENABLE_STRICT_OBJC_MSGSEND = YES;
191− ENABLE_TESTABILITY = YES;
192− GCC_C_LANGUAGE_STANDARD = gnu99;
193− GCC_DYNAMIC_NO_PIC = NO;
194− GCC_NO_COMMON_BLOCKS = YES;
195− GCC_OPTIMIZATION_LEVEL = 0;
196− GCC_PREPROCESSOR_DEFINITIONS = (
197− "DEBUG=1",
198− "$(inherited)",
199− );
200− GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
201− GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
202− GCC_WARN_UNDECLARED_SELECTOR = YES;
203− GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
204− GCC_WARN_UNUSED_FUNCTION = YES;
205− GCC_WARN_UNUSED_VARIABLE = YES;
206− MACOSX_DEPLOYMENT_TARGET = 10.11;
207− MTL_ENABLE_DEBUG_INFO = YES;
208− ONLY_ACTIVE_ARCH = YES;
209− SDKROOT = macosx;
210− SWIFT_OPTIMIZATION_LEVEL = "-Onone";
211− };
212− name = Debug;
213− };
214− 03D84ABD1D5B0A1000776402 /* Release */ = {
215− isa = XCBuildConfiguration;
216− buildSettings = {
217− ALWAYS_SEARCH_USER_PATHS = NO;
218− CLANG_ANALYZER_NONNULL = YES;
219− CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
220− CLANG_CXX_LIBRARY = "libc++";
221− CLANG_ENABLE_MODULES = YES;
222− CLANG_ENABLE_OBJC_ARC = YES;
223− CLANG_WARN_BOOL_CONVERSION = YES;
224− CLANG_WARN_CONSTANT_CONVERSION = YES;
225− CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
226− CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
227− CLANG_WARN_EMPTY_BODY = YES;
228− CLANG_WARN_ENUM_CONVERSION = YES;
229− CLANG_WARN_INT_CONVERSION = YES;
230− CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
231− CLANG_WARN_UNREACHABLE_CODE = YES;
232− CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
233− CODE_SIGN_IDENTITY = "-";
234− COPY_PHASE_STRIP = NO;
235− DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
236− ENABLE_NS_ASSERTIONS = NO;
237− ENABLE_STRICT_OBJC_MSGSEND = YES;
238− GCC_C_LANGUAGE_STANDARD = gnu99;
239− GCC_NO_COMMON_BLOCKS = YES;
240− GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
241− GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
242− GCC_WARN_UNDECLARED_SELECTOR = YES;
243− GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
244− GCC_WARN_UNUSED_FUNCTION = YES;
245− GCC_WARN_UNUSED_VARIABLE = YES;
246− MACOSX_DEPLOYMENT_TARGET = 10.11;
247− MTL_ENABLE_DEBUG_INFO = NO;
248− SDKROOT = macosx;
249− };
250− name = Release;
251− };
252− 03D84ABF1D5B0A1000776402 /* Debug */ = {
253− isa = XCBuildConfiguration;
254− buildSettings = {
255− FRAMEWORK_SEARCH_PATHS = (
256− "$(inherited)",
257− "$(PROJECT_DIR)",
258− );
259− PRODUCT_NAME = "$(TARGET_NAME)";
260− SWIFT_VERSION = 2.3;
261− };
262− name = Debug;
263− };
264− 03D84AC01D5B0A1000776402 /* Release */ = {
265− isa = XCBuildConfiguration;
266− buildSettings = {
267− FRAMEWORK_SEARCH_PATHS = (
268− "$(inherited)",
269− "$(PROJECT_DIR)",
270− );
271− PRODUCT_NAME = "$(TARGET_NAME)";
272− SWIFT_VERSION = 2.3;
273− };
274− name = Release;
275− };
276−/* End XCBuildConfiguration section */
277−
278−/* Begin XCConfigurationList section */
279− 03D84AB21D5B0A1000776402 /* Build configuration list for PBXProject "test_Freddy" */ = {
280− isa = XCConfigurationList;
281− buildConfigurations = (
282− 03D84ABC1D5B0A1000776402 /* Debug */,
283− 03D84ABD1D5B0A1000776402 /* Release */,
284− );
285− defaultConfigurationIsVisible = 0;
286− defaultConfigurationName = Release;
287− };
288− 03D84ABE1D5B0A1000776402 /* Build configuration list for PBXNativeTarget "test_Freddy" */ = {
289− isa = XCConfigurationList;
290− buildConfigurations = (
291− 03D84ABF1D5B0A1000776402 /* Debug */,
292− 03D84AC01D5B0A1000776402 /* Release */,
293− );
294− defaultConfigurationIsVisible = 0;
295− defaultConfigurationName = Release;
296− };
297−/* End XCConfigurationList section */
298− };
299− rootObject = 03D84AAF1D5B0A1000776402 /* Project object */;
300−}
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7
@@ -1,7 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<Workspace
3− version = "1.0">
4− <FileRef
5− location = "self:test_Freddy.xcodeproj">
6− </FileRef>
7−</Workspace>
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/project.xcworkspace/xcshareddata/test_Freddy.xcscmblueprintdeleted−30
@@ -1,30 +0,0 @@
1−{
2− "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A",
3− "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4−
5− },
6− "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
7− "6ADA245F937D8ED6D99F5A7865E19F5267A169E2" : 0,
8− "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A" : 0
9− },
10− "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "7B3DFA55-F9BF-41D8-8FD5-204D3162EB03",
11− "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
12− "6ADA245F937D8ED6D99F5A7865E19F5267A169E2" : "dropbox\/JSON\/test_Freddy\/Vendor\/Freddy\/",
13− "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A" : "dropbox\/"
14− },
15− "DVTSourceControlWorkspaceBlueprintNameKey" : "test_Freddy",
16− "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17− "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "JSON\/test_Freddy\/test_Freddy.xcodeproj",
18− "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19− {
20− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/bignerdranch\/Freddy.git",
21− "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
22− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "6ADA245F937D8ED6D99F5A7865E19F5267A169E2"
23− },
24− {
25− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "\/Users\/nst\/Dropbox\/dropbox.git",
26− "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
27− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A"
28− }
29− ]
30−}
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_Freddy.xcschemedeleted−91
@@ -1,91 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<Scheme
3− LastUpgradeVersion = "0800"
4− version = "1.3">
5− <BuildAction
6− parallelizeBuildables = "YES"
7− buildImplicitDependencies = "YES">
8− <BuildActionEntries>
9− <BuildActionEntry
10− buildForTesting = "YES"
11− buildForRunning = "YES"
12− buildForProfiling = "YES"
13− buildForArchiving = "YES"
14− buildForAnalyzing = "YES">
15− <BuildableReference
16− BuildableIdentifier = "primary"
17− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
18− BuildableName = "test_Freddy"
19− BlueprintName = "test_Freddy"
20− ReferencedContainer = "container:test_Freddy.xcodeproj">
21− </BuildableReference>
22− </BuildActionEntry>
23− </BuildActionEntries>
24− </BuildAction>
25− <TestAction
26− buildConfiguration = "Debug"
27− selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28− selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29− shouldUseLaunchSchemeArgsEnv = "YES">
30− <Testables>
31− </Testables>
32− <MacroExpansion>
33− <BuildableReference
34− BuildableIdentifier = "primary"
35− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
36− BuildableName = "test_Freddy"
37− BlueprintName = "test_Freddy"
38− ReferencedContainer = "container:test_Freddy.xcodeproj">
39− </BuildableReference>
40− </MacroExpansion>
41− <AdditionalOptions>
42− </AdditionalOptions>
43− </TestAction>
44− <LaunchAction
45− buildConfiguration = "Debug"
46− selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
47− selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
48− launchStyle = "0"
49− useCustomWorkingDirectory = "NO"
50− ignoresPersistentStateOnLaunch = "NO"
51− debugDocumentVersioning = "YES"
52− debugServiceExtension = "internal"
53− allowLocationSimulation = "YES">
54− <BuildableProductRunnable
55− runnableDebuggingMode = "0">
56− <BuildableReference
57− BuildableIdentifier = "primary"
58− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
59− BuildableName = "test_Freddy"
60− BlueprintName = "test_Freddy"
61− ReferencedContainer = "container:test_Freddy.xcodeproj">
62− </BuildableReference>
63− </BuildableProductRunnable>
64− <AdditionalOptions>
65− </AdditionalOptions>
66− </LaunchAction>
67− <ProfileAction
68− buildConfiguration = "Release"
69− shouldUseLaunchSchemeArgsEnv = "YES"
70− savedToolIdentifier = ""
71− useCustomWorkingDirectory = "NO"
72− debugDocumentVersioning = "YES">
73− <BuildableProductRunnable
74− runnableDebuggingMode = "0">
75− <BuildableReference
76− BuildableIdentifier = "primary"
77− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
78− BuildableName = "test_Freddy"
79− BlueprintName = "test_Freddy"
80− ReferencedContainer = "container:test_Freddy.xcodeproj">
81− </BuildableReference>
82− </BuildableProductRunnable>
83− </ProfileAction>
84− <AnalyzeAction
85− buildConfiguration = "Debug">
86− </AnalyzeAction>
87− <ArchiveAction
88− buildConfiguration = "Release"
89− revealArchiveInOrganizer = "YES">
90− </ArchiveAction>
91−</Scheme>
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22
@@ -1,22 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3−<plist version="1.0">
4−<dict>
5− <key>SchemeUserState</key>
6− <dict>
7− <key>test_Freddy.xcscheme</key>
8− <dict>
9− <key>orderHint</key>
10− <integer>0</integer>
11− </dict>
12− </dict>
13− <key>SuppressBuildableAutocreation</key>
14− <dict>
15− <key>03D84AB61D5B0A1000776402</key>
16− <dict>
17− <key>primary</key>
18− <true/>
19− </dict>
20− </dict>
21−</dict>
22−</plist>
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSON.swiftdeleted−95
@@ -1,95 +0,0 @@
1−//
2−// JSON.swift
3−// Freddy
4−//
5−// Created by Matthew D. Mathias on 3/17/15.
6−// Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
7−//
8−
9−/// An enum to describe the structure of JSON.
10−public enum JSON {
11− /// A case for denoting an array with an associated value of `[JSON]`
12− case Array([JSON])
13− /// A case for denoting a dictionary with an associated value of `[Swift.String: JSON]`
14− case Dictionary([Swift.String: JSON])
15− /// A case for denoting a double with an associated value of `Swift.Double`.
16− case Double(Swift.Double)
17− /// A case for denoting an integer with an associated value of `Swift.Int`.
18− case Int(Swift.Int)
19− /// A case for denoting a string with an associated value of `Swift.String`.
20− case String(Swift.String)
21− /// A case for denoting a boolean with an associated value of `Swift.Bool`.
22− case Bool(Swift.Bool)
23− /// A case for denoting null.
24− case Null
25−}
26−
27−// MARK: - Errors
28−
29−extension JSON {
30−
31− /// An enum to encapsulate errors that may arise in working with `JSON`.
32− public enum Error: ErrorType {
33− /// The `index` is out of bounds for a JSON array
34− case IndexOutOfBounds(index: Swift.Int)
35−
36− /// The `key` was not found in the JSON dictionary
37− case KeyNotFound(key: Swift.String)
38−
39− /// The JSON is not subscriptable with `type`
40− case UnexpectedSubscript(type: JSONPathType.Type)
41−
42− /// Unexpected JSON `value` was found that is not convertible `to` type
43− case ValueNotConvertible(value: JSON, to: Any.Type)
44− }
45−
46−}
47−
48−// MARK: - Test Equality
49−
50−/// Return `true` if `lhs` is equal to `rhs`.
51−public func ==(lhs: JSON, rhs: JSON) -> Bool {
52− switch (lhs, rhs) {
53− case (.Array(let arrL), .Array(let arrR)):
54− return arrL == arrR
55− case (.Dictionary(let dictL), .Dictionary(let dictR)):
56− return dictL == dictR
57− case (.String(let strL), .String(let strR)):
58− return strL == strR
59− case (.Double(let dubL), .Double(let dubR)):
60− return dubL == dubR
61− case (.Double(let dubL), .Int(let intR)):
62− return dubL == Double(intR)
63− case (.Int(let intL), .Int(let intR)):
64− return intL == intR
65− case (.Int(let intL), .Double(let dubR)):
66− return Double(intL) == dubR
67− case (.Bool(let bL), .Bool(let bR)):
68− return bL == bR
69− case (.Null, .Null):
70− return true
71− default:
72− return false
73− }
74−}
75−
76−extension JSON: Equatable {}
77−
78−// MARK: - Printing
79−
80−extension JSON: CustomStringConvertible {
81−
82− /// A textual representation of `self`.
83− public var description: Swift.String {
84− switch self {
85− case .Array(let arr): return Swift.String(arr)
86− case .Dictionary(let dict): return Swift.String(dict)
87− case .String(let string): return string
88− case .Double(let double): return Swift.String(double)
89− case .Int(let int): return Swift.String(int)
90− case .Bool(let bool): return Swift.String(bool)
91− case .Null: return "null"
92− }
93− }
94−
95−}
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONDecodable.swiftdeleted−177
@@ -1,177 +0,0 @@
1−//
2−// JSONDecodable.swift
3−// Freddy
4−//
5−// Created by Matthew D. Mathias on 3/24/15.
6−// Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
7−//
8−
9−/// A protocol to provide functionality for creating a model object with a `JSON`
10−/// value.
11−public protocol JSONDecodable {
12−
13− /// Creates an instance of the model with a `JSON` instance.
14− /// - parameter json: An instance of a `JSON` value from which to
15− /// construct an instance of the implementing type.
16− /// - throws: Any `JSON.Error` for errors derived from inspecting the
17− /// `JSON` value, or any other error involved in decoding.
18− init(json: JSON) throws
19−
20−}
21−
22−extension Double: JSONDecodable {
23−
24− /// An initializer to create an instance of `Double` from a `JSON` value.
25− /// - parameter json: An instance of `JSON`.
26− /// - throws: The initializer will throw an instance of `JSON.Error` if
27− /// an instance of `Double` cannot be created from the `JSON` value that was
28− /// passed to this initializer.
29− public init(json: JSON) throws {
30− switch json {
31− case let .Double(double):
32− self = double
33− case let .Int(int):
34− self = Swift.Double(int)
35− default:
36− throw JSON.Error.ValueNotConvertible(value: json, to: Swift.Double)
37− }
38− }
39−
40−}
41−
42−extension Int: JSONDecodable {
43−
44− /// An initializer to create an instance of `Int` from a `JSON` value.
45− /// - parameter json: An instance of `JSON`.
46− /// - throws: The initializer will throw an instance of `JSON.Error` if
47− /// an instance of `Int` cannot be created from the `JSON` value that was
48− /// passed to this initializer.
49− public init(json: JSON) throws {
50− switch json {
51− case let .Double(double) where double <= Double(Swift.Int.max):
52− self = Swift.Int(double)
53− case let .Int(int):
54− self = int
55− default:
56− throw JSON.Error.ValueNotConvertible(value: json, to: Swift.Int)
57− }
58− }
59−
60−}
61−
62−extension String: JSONDecodable {
63−
64− /// An initializer to create an instance of `String` from a `JSON` value.
65− /// - parameter json: An instance of `JSON`.
66− /// - throws: The initializer will throw an instance of `JSON.Error` if
67− /// an instance of `String` cannot be created from the `JSON` value that was
68− /// passed to this initializer.
69− public init(json: JSON) throws {
70−
71− switch json {
72− case let .String(string):
73− self = string
74− case let .Int(int):
75− self = String(int)
76− case let .Bool(bool):
77− self = String(bool)
78− case let .Double(double):
79− self = String(double)
80− default:
81− throw JSON.Error.ValueNotConvertible(value: json, to: Swift.String)
82− }
83− }
84−
85−}
86−
87−extension Bool: JSONDecodable {
88−
89− /// An initializer to create an instance of `Bool` from a `JSON` value.
90− /// - parameter json: An instance of `JSON`.
91− /// - throws: The initializer will throw an instance of `JSON.Error` if
92− /// an instance of `Bool` cannot be created from the `JSON` value that was
93− /// passed to this initializer.
94− public init(json: JSON) throws {
95− guard case let .Bool(bool) = json else {
96− throw JSON.Error.ValueNotConvertible(value: json, to: Swift.Bool)
97− }
98− self = bool
99− }
100−
101−}
102−
103−extension RawRepresentable where RawValue: JSONDecodable {
104−
105− /// An initializer to create an instance of `RawRepresentable` from a `JSON` value.
106− /// - parameter json: An instance of `JSON`.
107− /// - throws: The initializer will throw an instance of `JSON.Error` if
108− /// an instance of `RawRepresentable` cannot be created from the `JSON` value that was
109− /// passed to this initializer.
110− public init(json: JSON) throws {
111− let raw = try json.decode(type: RawValue.self)
112− guard let value = Self(rawValue: raw) else {
113− throw JSON.Error.ValueNotConvertible(value: json, to: Self.self)
114− }
115− self = value
116− }
117−}
118−
119−internal extension JSON {
120−
121− /// Retrieves a `[JSON]` from the JSON.
122− /// - parameter: A `JSON` to be used to create the returned `Array`.
123− /// - returns: An `Array` of `JSON` elements
124− /// - throws: Any of the `JSON.Error` cases thrown by `decode(type:)`.
125− /// - seealso: `JSON.decode(_:type:)`
126− static func getArray(json: JSON) throws -> [JSON] {
127− // Ideally should be expressed as a conditional protocol implementation on Swift.Array.
128− guard case let .Array(array) = json else {
129− throw Error.ValueNotConvertible(value: json, to: Swift.Array<JSON>)
130− }
131− return array
132− }
133−
134− /// Retrieves a `[String: JSON]` from the JSON.
135− /// - parameter: A `JSON` to be used to create the returned `Dictionary`.
136− /// - returns: An `Dictionary` of `String` mapping to `JSON` elements
137− /// - throws: Any of the `JSON.Error` cases thrown by `decode(type:)`.
138− /// - seealso: `JSON.decode(_:type:)`
139− static func getDictionary(json: JSON) throws -> [Swift.String: JSON] {
140− // Ideally should be expressed as a conditional protocol implementation on Swift.Dictionary.
141− guard case let .Dictionary(dictionary) = json else {
142− throw Error.ValueNotConvertible(value: json, to: Swift.Dictionary<Swift.String, JSON>)
143− }
144− return dictionary
145− }
146−
147− /// Attempts to decode many values from a descendant JSON array at a path
148− /// into JSON.
149− /// - parameter: A `JSON` to be used to create the returned `Array` of some type conforming to `JSONDecodable`.
150− /// - returns: An `Array` of `Decoded` elements.
151− /// - throws: Any of the `JSON.Error` cases thrown by `decode(type:)`, as
152− /// well as any error that arises from decoding the contained values.
153− /// - seealso: `JSON.decode(_:type:)`
154− static func getArrayOf<Decoded: JSONDecodable>(json: JSON) throws -> [Decoded] {
155− // Ideally should be expressed as a conditional protocol implementation on Swift.Dictionary.
156− // This implementation also doesn't do the `type = Type.self` trick.
157− return try getArray(json).map(Decoded.init)
158− }
159−
160− /// Attempts to decode many values from a descendant JSON object at a path
161− /// into JSON.
162− /// - returns: A `Dictionary` of string keys and `Decoded` values.
163− /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)` or
164− /// any error that arises from decoding the contained values.
165− /// - seealso: `JSON.decode(_:type:)`
166− static func getDictionaryOf<Decoded: JSONDecodable>(json: JSON) throws -> [Swift.String: Decoded] {
167− guard case let .Dictionary(dictionary) = json else {
168− throw Error.ValueNotConvertible(value: json, to: Swift.Dictionary<Swift.String, Decoded>)
169− }
170− var decodedDictionary = Swift.Dictionary<Swift.String, Decoded>(minimumCapacity: dictionary.count)
171− for (key, value) in dictionary {
172− decodedDictionary[key] = try Decoded(json: value)
173− }
174− return decodedDictionary
175− }
176−
177−}
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONEncodable.swiftdeleted−83
@@ -1,83 +0,0 @@
1−//
2−// JSONEncodable.swift
3−// Freddy
4−//
5−// Created by Matthew Mathias on 1/4/16.
6−// Copyright © 2016 Big Nerd Ranch. All rights reserved.
7−//
8−
9−import Foundation
10−
11−/// A protocol to facilitate encoding and decoding of `JSON`.
12−public protocol JSONEncodable {
13− /// Converts an instance of a conforming type to `JSON`.
14− /// - returns: An instance of `JSON`.
15− /// - Note: If conforming to `JSONEncodable` with a custom type of your own, you should return an instance of
16− /// `JSON.Dictionary`.
17− func toJSON() -> JSON
18−}
19−
20−extension Array where Element: JSONEncodable {
21− /// Converts an instance of `Array` whose elements conform to `JSONEncodable` to `JSON`.
22− /// - returns: An instance of `JSON` where the enum case is `.Array`.
23− public func toJSON() -> JSON {
24− let arrayOfJSON = self.map { $0.toJSON() }
25− return .Array(arrayOfJSON)
26− }
27−}
28−
29−extension Dictionary where Value: JSONEncodable {
30− /// Converts an instance of `Dictionary` whose values conform to `JSONEncodable` to `JSON`. The keys in the resulting
31− /// `JSON.Dictionary` will be of type `String`.
32− /// - returns: An instance of `JSON` where the enum case is `.Dictionary`.
33− public func toJSON() -> JSON {
34− var jsonDictionary = [String: JSON]()
35−
36− for (k, v) in self {
37− let key = String(k)
38− jsonDictionary[key] = v.toJSON()
39− }
40−
41− return .Dictionary(jsonDictionary)
42− }
43−}
44−
45−extension Int: JSONEncodable {
46− /// Converts an instance of a conforming type to `JSON`.
47− /// - returns: An instance of `JSON` where the enum case is `.Int`.
48− public func toJSON() -> JSON {
49− return .Int(self)
50− }
51−}
52−
53−extension Double: JSONEncodable {
54− /// Converts an instance of a conforming type to `JSON`.
55− /// - returns: An instance of `JSON` where the enum case is `.Double`.
56− public func toJSON() -> JSON {
57− return .Double(self)
58− }
59−}
60−
61−extension String: JSONEncodable {
62− /// Converts an instance of a conforming type to `JSON`.
63− /// - returns: An instance of `JSON` where the enum case is `.String`.
64− public func toJSON() -> JSON {
65− return .String(self)
66− }
67−}
68−
69−extension Bool: JSONEncodable {
70− /// Converts an instance of a conforming type to `JSON`.
71− /// - returns: An instance of `JSON` where the enum case is `.Bool`.
72− public func toJSON() -> JSON {
73− return .Bool(self)
74− }
75−}
76−
77−extension RawRepresentable where RawValue: JSONEncodable {
78− /// Converts an instance of a conforming type to `JSON`.
79− /// - returns: An instance of `JSON` where the enum case is whatever the underlying `RawValue` converts to.
80− public func toJSON() -> JSON {
81− return rawValue.toJSON()
82− }
83−}
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONEncodingDetector.swiftdeleted−110
@@ -1,110 +0,0 @@
1−//
2−// JSONEncodingDetector.swift
3−// Freddy
4−//
5−// Created by Robert Edwards on 1/27/16.
6−// Copyright © 2016 Big Nerd Ranch. All rights reserved.
7−//
8−
9−/// Struct for attempting to detect the Unicode encoding used with the data supplied to the JSONParser
10−public struct JSONEncodingDetector {
11−
12− //// The Unicode encodings looked for during detection
13− public enum Encoding {
14− //// UTF-8
15− case UTF8
16− //// UTF-16 Little Endian
17− case UTF16LE
18− //// UTF-16 Big Endian
19− case UTF16BE
20− //// UTF-32 Little Endian
21− case UTF32LE
22− //// UTF-32 Big Endian
23− case UTF32BE
24− }
25−
26− //// The Unicode encodings supported by JSONParser.swift
27− public static let supportedEncodings: [Encoding] = [.UTF8]
28−
29− typealias ByteStreamPrefixInformation = (encoding: Encoding, byteOrderMarkLength: Int)
30−
31− //// Attempts to detect the Unicode encoding used for a given set of data.
32− ////
33− //// This function initially looks for a Byte Order Mark in the following form:
34− ////
35− //// Bytes | Encoding Form
36− //// --------------|----------------
37− //// 00 00 FE FF | UTF-32, big-endian
38− //// FF FE 00 00 | UTF-32, little-endian
39− //// FE FF | UTF-16, big-endian
40− //// FF FE | UTF-16, little-endian
41− //// EF BB BF | UTF-8
42− ////
43− //// If a BOM is not found then we detect using the following approach described in
44− //// the JSON RFC http://www.ietf.org/rfc/rfc4627.txt:
45− ////
46− //// Since the first two characters of a JSON text will always be ASCII
47− //// characters [RFC0020], it is possible to determine whether an octet
48− //// stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
49− //// at the pattern of nulls in the first four octets.
50− ////
51− //// 00 00 00 xx UTF-32BE
52− //// 00 xx 00 xx UTF-16BE
53− //// xx 00 00 00 UTF-32LE
54− //// xx 00 xx 00 UTF-16LE
55− //// xx xx xx xx UTF-8
56− ////
57− //// - parameter header: The front Slice of data being read and evaluated.
58− //// - returns: A tuple containing the detected Unicode encoding and the lenght of the byte order mark.
59− static func detectEncoding(header: Slice<UnsafeBufferPointer<UInt8>>) -> ByteStreamPrefixInformation {
60−
61− guard let prefix = prefixFromHeader(header) else {
62− return (.UTF8, 0)
63− }
64−
65− if let prefixInfo = JSONEncodingDetector.encodingFromBOM(prefix) {
66− return prefixInfo
67− } else {
68− switch prefix {
69− case(0, 0, 0?, _):
70− return (.UTF32BE, 0)
71− case(_, 0, 0?, 0?):
72− return (.UTF32LE, 0)
73− case (0, _, 0?, _), (0, _, _, _):
74− return (.UTF16BE, 0)
75− case (_, 0, _, 0?), (_, 0, _, _):
76− return (.UTF16LE, 0)
77− default:
78− return (.UTF8, 0)
79− }
80− }
81− }
82−
83− private typealias EncodingBytePrefix = (UInt8, UInt8, UInt8?, UInt8?)
84−
85− private static func prefixFromHeader(header: Slice<UnsafeBufferPointer<UInt8>>) -> EncodingBytePrefix? {
86− if header.count >= 4 {
87− return(header[0], header[1], header[2], header[3])
88− } else if header.count >= 2 {
89− return (header[0], header[1], nil, nil)
90− }
91− return nil
92− }
93−
94− private static func encodingFromBOM(prefix: EncodingBytePrefix) -> ByteStreamPrefixInformation? {
95− switch prefix {
96− case(0xFE, 0xFF, _, _):
97− return (.UTF16BE, 2)
98− case(0x00, 0x00, 0xFE?, 0xFF?):
99− return (.UTF32BE, 4)
100− case(0xEF, 0xBB, 0xBF?, _):
101− return (.UTF8, 3)
102− case(0xFF, 0xFE, 0?, 0?):
103− return (.UTF32LE, 4)
104− case(0xFF, 0xFE, _, _):
105− return (.UTF16LE, 2)
106− default:
107− return nil
108− }
109− }
110−}
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONLiteralConvertible.swiftdeleted−130
@@ -1,130 +0,0 @@
1−//
2−// JSONLiteralConvertible.swift
3−// Freddy
4−//
5−// Created by Zachary Waldowski on 5/11/15.
6−// Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
7−//
8−
9−// MARK: - ArrayLiteralConvertible
10−
11−extension JSON: ArrayLiteralConvertible {
12−
13− /// Create an instance by copying each element of the `collection` into a
14− /// new `Array`.
15− public init<Collection: CollectionType where Collection.Generator.Element == JSON>(_ collection: Collection) {
16− self = .Array(Swift.Array(collection))
17− }
18−
19− /// Create an instance initialized with `elements`.
20− public init(arrayLiteral elements: JSON...) {
21− self.init(elements)
22− }
23−
24−}
25−
26−// MARK: - DictionaryLiteralConvertible
27−
28−extension JSON: DictionaryLiteralConvertible {
29−
30− /// Create an instance by copying each key/value pair of the `pairs` into
31− /// a new `Dictionary`.
32− public init<Dictionary: SequenceType where Dictionary.Generator.Element == (Swift.String, JSON)>(_ pairs: Dictionary) {
33− var dictionary = Swift.Dictionary<Swift.String, JSON>(minimumCapacity: pairs.underestimateCount())
34− for (key, value) in pairs {
35− dictionary[key] = value
36− }
37− self = .Dictionary(dictionary)
38− }
39−
40− /// Create an instance initialized with `pairs`.
41− public init(dictionaryLiteral pairs: (Swift.String, JSON)...) {
42− self.init(pairs)
43− }
44−
45−}
46−
47−// MARK: - FloatLiteralConvertible
48−
49−extension JSON: FloatLiteralConvertible {
50−
51− /// Create an instance initialized to `Double` `value`.
52− public init(_ value: Swift.Double) {
53− self = .Double(value)
54− }
55−
56− /// Create a literal instance initialized to `value`.
57− public init(floatLiteral value: Swift.Double) {
58− self.init(value)
59− }
60−
61−}
62−
63−// MARK: - IntegerLiteralConvertible
64−
65−extension JSON: IntegerLiteralConvertible {
66−
67− /// Create an instance initialized to `Int` by `value`.
68− public init(_ value: Swift.Int) {
69− self = .Int(value)
70− }
71−
72− /// Create a literal instance initialized to `value`.
73− public init(integerLiteral value: Swift.Int) {
74− self.init(value)
75− }
76−
77−}
78−
79−// MARK: - StringLiteralConvertible
80−
81−extension JSON: StringLiteralConvertible {
82−
83− /// Create an instance initialized to `String` by `text`.
84− public init(_ text: Swift.String) {
85− self = .String(text)
86− }
87−
88− /// Create a literal instance initialized to `value`.
89− public init(stringLiteral value: StringLiteralType) {
90− self.init(value)
91− }
92−
93− /// Create a literal instance initialized to `value`.
94− public init(extendedGraphemeClusterLiteral value: StringLiteralType) {
95− self.init(value)
96− }
97−
98− /// Create a literal instance initialized to `value`.
99− public init(unicodeScalarLiteral value: StringLiteralType) {
100− self.init(value)
101− }
102−
103−}
104−
105−// MARK: - BooleanLiteralConvertible
106−
107−extension JSON: BooleanLiteralConvertible {
108−
109− /// Create an instance initialized to `Bool` by `value`.
110− public init(_ value: Swift.Bool) {
111− self = .Bool(value)
112− }
113−
114− /// Create a literal instance initialized to `value`.
115− public init(booleanLiteral value: Swift.Bool) {
116− self.init(value)
117− }
118−
119−}
120−
121−// MARK: - NilLiteralConvertible
122−
123−extension JSON: NilLiteralConvertible {
124−
125− /// Create an instance initialized with `nil`.
126− public init(nilLiteral: ()) {
127− self = .Null
128− }
129−
130−}
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONParser.swiftdeleted−907
@@ -1,907 +0,0 @@
1−//
2−// JSONParser.swift
3−// Freddy
4−//
5−// Created by John Gallagher on 4/18/15.
6−// Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
7−//
8−
9−import Foundation
10−
11−private struct Literal {
12− static let BACKSLASH = UInt8(ascii: "\\")
13− static let BACKSPACE = UInt8(ascii: "\u{0008}")
14− static let COLON = UInt8(ascii: ":")
15− static let COMMA = UInt8(ascii: ",")
16− static let DOUBLE_QUOTE = UInt8(ascii: "\"")
17− static let FORMFEED = UInt8(ascii: "\u{000c}")
18− static let LEFT_BRACE = UInt8(ascii: "{")
19− static let LEFT_BRACKET = UInt8(ascii: "[")
20− static let MINUS = UInt8(ascii: "-")
21− static let NEWLINE = UInt8(ascii: "\n")
22− static let PERIOD = UInt8(ascii: ".")
23− static let PLUS = UInt8(ascii: "+")
24− static let RETURN = UInt8(ascii: "\r")
25− static let RIGHT_BRACE = UInt8(ascii: "}")
26− static let RIGHT_BRACKET = UInt8(ascii: "]")
27− static let SLASH = UInt8(ascii: "/")
28− static let SPACE = UInt8(ascii: " ")
29− static let TAB = UInt8(ascii: "\t")
30−
31− static let a = UInt8(ascii: "a")
32− static let b = UInt8(ascii: "b")
33− static let c = UInt8(ascii: "c")
34− static let d = UInt8(ascii: "d")
35− static let e = UInt8(ascii: "e")
36− static let f = UInt8(ascii: "f")
37− static let l = UInt8(ascii: "l")
38− static let n = UInt8(ascii: "n")
39− static let r = UInt8(ascii: "r")
40− static let s = UInt8(ascii: "s")
41− static let t = UInt8(ascii: "t")
42− static let u = UInt8(ascii: "u")
43−
44− static let A = UInt8(ascii: "A")
45− static let B = UInt8(ascii: "B")
46− static let C = UInt8(ascii: "C")
47− static let D = UInt8(ascii: "D")
48− static let E = UInt8(ascii: "E")
49− static let F = UInt8(ascii: "F")
50−
51− static let zero = UInt8(ascii: "0")
52− static let one = UInt8(ascii: "1")
53− static let two = UInt8(ascii: "2")
54− static let three = UInt8(ascii: "3")
55− static let four = UInt8(ascii: "4")
56− static let five = UInt8(ascii: "5")
57− static let six = UInt8(ascii: "6")
58− static let seven = UInt8(ascii: "7")
59− static let eight = UInt8(ascii: "8")
60− static let nine = UInt8(ascii: "9")
61−}
62−
63−private let ParserMaximumDepth = 512
64−
65−
66−/// A pure Swift JSON parser. This parser is much faster than the
67−/// `NSJSONSerialization`-based parser (due to the overhead of having to
68−/// dynamically cast the Objective-C objects to determine their type); however,
69−/// it is much newer and has restrictions that the `NSJSONSerialization` parser
70−/// does not. Two restrictions in particular are that it requires UTF-8 data as
71−/// input and it does not allow trailing commas in arrays or dictionaries.
72−public struct JSONParser {
73−
74− private enum Sign: Int {
75− case Positive = 1
76− case Negative = -1
77− }
78−
79− private let input: UnsafeBufferPointer<UInt8>
80− private let owner: Any?
81− private var loc = 0
82− private var depth = 0
83−
84− private init<T>(buffer: UnsafeBufferPointer<UInt8>, owner: T) {
85− self.input = buffer
86− self.owner = owner
87− }
88−
89− /// Decode the root element of the `JSON` stream. This may be any fragment
90− /// or a structural element, per RFC 7159.
91− ///
92− /// The beginning bytes are used to determine the stream's encoding.
93− /// `JSONParser` currently only supports UTF-8 encoding, with or without
94− /// a byte-order mark.
95− ///
96− /// - throws: `JSONParser.Error` for any decoding failures, including a
97− /// source location if needed.
98− public mutating func parse() throws -> JSON {
99− try guardAgainstUnsupportedEncodings()
100− let value = try parseValue()
101− skipWhitespace()
102− guard loc == input.count else {
103− throw Error.EndOfStreamGarbage(offset: loc)
104− }
105− return value
106− }
107−
108− private mutating func parseValue() throws -> JSON {
109− guard depth <= ParserMaximumDepth else {
110− throw Error.ExceededNestingLimit(offset: loc)
111− }
112−
113− guard input.count > 0 else {
114− throw Error.EndOfStreamUnexpected
115− }
116−
117− advancing: while loc < input.count {
118− do {
119− switch input[loc] {
120− case Literal.LEFT_BRACKET:
121− depth += 1
122− defer { depth -= 1 }
123− return try decodeArray()
124−
125− case Literal.LEFT_BRACE:
126− depth += 1
127− defer { depth -= 1 }
128− return try decodeObject()
129−
130− case Literal.DOUBLE_QUOTE:
131− return try decodeString()
132−
133− case Literal.f:
134− return try decodeFalse()
135−
136− case Literal.n:
137− return try decodeNull()
138−
139− case Literal.t:
140− return try decodeTrue()
141−
142− case Literal.MINUS:
143− return try decodeIntegralValue(NumberParser(loc: loc, input: input, state: .LeadingMinus))
144−
145− case Literal.zero:
146− return try decodeIntegralValue(NumberParser(loc: loc, input: input, state: .LeadingZero))
147−
148− case Literal.one...Literal.nine:
149− return try decodeIntegralValue(NumberParser(loc: loc, input: input, state: .PreDecimalDigits))
150−
151− case Literal.SPACE, Literal.TAB, Literal.RETURN, Literal.NEWLINE:
152− loc = loc.successor()
153−
154− default:
155− break advancing
156− }
157− } catch let InternalError.NumberOverflow(offset: start) {
158− return try decodeNumberAsString(start)
159− }
160− }
161−
162− if loc < input.count {
163− throw Error.ValueInvalid(offset: loc, character: UnicodeScalar(input[loc]))
164− } else {
165− throw Error.EndOfStreamUnexpected
166− }
167− }
168−
169− private mutating func skipWhitespace() {
170− while loc < input.count {
171− switch input[loc] {
172− case Literal.SPACE, Literal.TAB, Literal.RETURN, Literal.NEWLINE:
173− loc = loc.successor()
174−
175− default:
176− return
177− }
178− }
179− }
180−
181− private mutating func guardAgainstUnsupportedEncodings() throws {
182− let header = input.prefix(4)
183− let encodingPrefixInformation = JSONEncodingDetector.detectEncoding(header)
184− guard JSONEncodingDetector.supportedEncodings.contains(encodingPrefixInformation.encoding) else {
185− throw Error.InvalidUnicodeStreamEncoding(detectedEncoding: encodingPrefixInformation.encoding)
186− }
187− loc = loc.advancedBy(encodingPrefixInformation.byteOrderMarkLength)
188− }
189−
190− private mutating func decodeNull() throws -> JSON {
191− guard loc.advancedBy(3, limit: input.count) != input.count else {
192− throw Error.LiteralNilMisspelled(offset: loc)
193− }
194−
195− if input[loc+1] != Literal.u
196− || input[loc+2] != Literal.l
197− || input[loc+3] != Literal.l {
198− throw Error.LiteralNilMisspelled(offset: loc)
199− }
200−
201− loc += 4
202− return .Null
203− }
204−
205− private mutating func decodeTrue() throws -> JSON {
206− guard loc.advancedBy(3, limit: input.count) != input.count else {
207− throw Error.LiteralTrueMisspelled(offset: loc)
208− }
209−
210− if input[loc+1] != Literal.r
211− || input[loc+2] != Literal.u
212− || input[loc+3] != Literal.e {
213− throw Error.LiteralTrueMisspelled(offset: loc)
214− }
215−
216− loc += 4
217− return .Bool(true)
218− }
219−
220− private mutating func decodeFalse() throws -> JSON {
221− guard loc.advancedBy(4, limit: input.count) != input.count else {
222− throw Error.LiteralFalseMisspelled(offset: loc)
223− }
224−
225− if input[loc+1] != Literal.a
226− || input[loc+2] != Literal.l
227− || input[loc+3] != Literal.s
228− || input[loc+4] != Literal.e {
229− throw Error.LiteralFalseMisspelled(offset: loc)
230− }
231−
232− loc += 5
233− return .Bool(false)
234− }
235−
236− private var stringDecodingBuffer = [UInt8]()
237− private mutating func decodeString() throws -> JSON {
238− let start = loc
239− loc = loc.successor()
240− stringDecodingBuffer.removeAll(keepCapacity: true)
241− while loc < input.count {
242− switch input[loc] {
243− case Literal.BACKSLASH:
244− loc = loc.successor()
245− switch input[loc] {
246− case Literal.DOUBLE_QUOTE: stringDecodingBuffer.append(Literal.DOUBLE_QUOTE)
247− case Literal.BACKSLASH: stringDecodingBuffer.append(Literal.BACKSLASH)
248− case Literal.SLASH: stringDecodingBuffer.append(Literal.SLASH)
249− case Literal.b: stringDecodingBuffer.append(Literal.BACKSPACE)
250− case Literal.f: stringDecodingBuffer.append(Literal.FORMFEED)
251− case Literal.r: stringDecodingBuffer.append(Literal.RETURN)
252− case Literal.t: stringDecodingBuffer.append(Literal.TAB)
253− case Literal.n: stringDecodingBuffer.append(Literal.NEWLINE)
254− case Literal.u:
255− loc = loc.successor()
256− try readUnicodeEscape(start: loc - 2)
257−
258− // readUnicodeEscape() advances loc on its own, so we'll `continue` now
259− // to skip the typical "advance past this character" for all the other escapes
260− continue
261−
262− default:
263− throw Error.ControlCharacterUnrecognized(offset: loc)
264− }
265− loc = loc.successor()
266−
267− case Literal.DOUBLE_QUOTE:
268− loc = loc.successor()
269− stringDecodingBuffer.append(0)
270−
271− guard let string = (stringDecodingBuffer.withUnsafeBufferPointer {
272− String.fromCString(UnsafePointer($0.baseAddress))
273− }) else {
274− throw Error.UnicodeEscapeInvalid(offset: start)
275− }
276−
277− return .String(string)
278−
279− case let other:
280− stringDecodingBuffer.append(other)
281− loc = loc.successor()
282− }
283− }
284−
285− throw Error.EndOfStreamUnexpected
286− }
287−
288− private mutating func readCodeUnit() -> UInt16? {
289− guard loc + 4 <= input.count else {
290− return nil
291− }
292− var codeUnit: UInt16 = 0
293− for c in input[loc..<loc+4] {
294− let nibble: UInt16
295−
296− switch c {
297− case Literal.zero...Literal.nine:
298− nibble = UInt16(c - Literal.zero)
299−
300− case Literal.a...Literal.f:
301− nibble = 10 + UInt16(c - Literal.a)
302−
303− case Literal.A...Literal.F:
304− nibble = 10 + UInt16(c - Literal.A)
305−
306− default:
307− return nil
308− }
309− codeUnit = (codeUnit << 4) | nibble
310− }
311− loc += 4
312− return codeUnit
313− }
314−
315− private mutating func readUnicodeEscape(start start: Int) throws {
316− guard let codeUnit = readCodeUnit() else {
317− throw Error.UnicodeEscapeInvalid(offset: start)
318− }
319−
320− let codeUnits: [UInt16]
321−
322− if UTF16.isLeadSurrogate(codeUnit) {
323− // First half of a UTF16 surrogate pair - we must parse another code unit and combine them
324−
325− // First confirm and skip over that we have another "\u"
326− guard loc + 6 <= input.count && input[loc] == Literal.BACKSLASH && input[loc+1] == Literal.u else {
327− throw Error.UnicodeEscapeInvalid(offset: start)
328− }
329− loc += 2
330−
331− // Ensure the second code unit is valid for the surrogate pair
332− guard let secondCodeUnit = readCodeUnit() where UTF16.isTrailSurrogate(secondCodeUnit) else {
333− throw Error.UnicodeEscapeInvalid(offset: start)
334− }
335−
336− codeUnits = [codeUnit, secondCodeUnit]
337− } else {
338− codeUnits = [codeUnit]
339− }
340−
341− let transcodeHadError = transcode(UTF16.self, UTF8.self, codeUnits.generate(), { self.stringDecodingBuffer.append($0) }, stopOnError: true)
342−
343− if transcodeHadError {
344− throw Error.UnicodeEscapeInvalid(offset: start)
345− }
346− }
347−
348− private mutating func decodeArray() throws -> JSON {
349− let start = loc
350− loc = loc.successor()
351− var items = [JSON]()
352−
353− while loc < input.count {
354− skipWhitespace()
355−
356− if loc < input.count && input[loc] == Literal.RIGHT_BRACKET {
357− loc = loc.successor()
358− return .Array(items)
359− }
360−
361− if !items.isEmpty {
362− guard loc < input.count && input[loc] == Literal.COMMA else {
363− throw Error.CollectionMissingSeparator(offset: start)
364− }
365− loc = loc.successor()
366− }
367−
368− items.append(try parseValue())
369− }
370−
371− throw Error.EndOfStreamUnexpected
372− }
373−
374− // Decoding objects can be recursive, so we have to keep more than one
375− // buffer around for building up key/value pairs (to reduce allocations
376− // when parsing large JSON documents).
377− //
378− // Rough estimate of the difference between this and using a fresh
379− // [(String,JSON)] for the `pairs` variable in decodeObject() below is
380− // about 12% on an iPhone 5.
381− private struct DecodeObjectBuffers {
382− var buffers = [[(String,JSON)]]()
383−
384− mutating func getBuffer() -> [(String,JSON)] {
385− if !buffers.isEmpty {
386− var buffer = buffers.removeLast()
387− buffer.removeAll(keepCapacity: true)
388− return buffer
389− }
390− return [(String,JSON)]()
391− }
392−
393− mutating func putBuffer(buffer: [(String,JSON)]) {
394− buffers.append(buffer)
395− }
396− }
397−
398− private var decodeObjectBuffers = DecodeObjectBuffers()
399−
400− private mutating func decodeObject() throws -> JSON {
401− let start = loc
402− loc = loc.successor()
403− var pairs = decodeObjectBuffers.getBuffer()
404−
405− while loc < input.count {
406− skipWhitespace()
407−
408− if loc < input.count && input[loc] == Literal.RIGHT_BRACE {
409− loc = loc.successor()
410− var obj = [String:JSON](minimumCapacity: pairs.count)
411− for (k, v) in pairs {
412− obj[k] = v
413− }
414− decodeObjectBuffers.putBuffer(pairs)
415− return .Dictionary(obj)
416− }
417−
418− if !pairs.isEmpty {
419− guard loc < input.count && input[loc] == Literal.COMMA else {
420− throw Error.CollectionMissingSeparator(offset: start)
421− }
422− loc = loc.successor()
423−
424− skipWhitespace()
425− }
426−
427− guard loc < input.count && input[loc] == Literal.DOUBLE_QUOTE else {
428− throw Error.DictionaryMissingKey(offset: start)
429− }
430−
431− let key = try decodeString().string()
432− skipWhitespace()
433−
434− guard loc < input.count && input[loc] == Literal.COLON else {
435− throw Error.CollectionMissingSeparator(offset: start)
436− }
437− loc = loc.successor()
438−
439− pairs.append((key, try parseValue()))
440− }
441−
442− throw Error.EndOfStreamUnexpected
443− }
444−
445− private mutating func decodeIntegralValue(parser: NumberParser) throws -> JSON {
446− var sign = Sign.Positive
447− var parser = parser
448− var value = 0
449−
450− // This would be more natural as `while true { ... }` with a meaningful .Done case,
451− // but that causes compile time explosion in Swift 2.2. :-|
452− while parser.state != .Done {
453− switch parser.state {
454− case .LeadingMinus:
455− sign = .Negative
456− try parser.parseNegative()
457−
458− case .LeadingZero:
459− parser.parseLeadingZero()
460−
461− case .PreDecimalDigits:
462− try parser.parsePreDecimalDigits { c in
463− guard case let (exponent, false) = Int.multiplyWithOverflow(10, value) else {
464− throw InternalError.NumberOverflow(offset: parser.start)
465− }
466−
467− guard case let (newValue, false) = Int.addWithOverflow(exponent, Int(c - Literal.zero)) else {
468− throw InternalError.NumberOverflow(offset: parser.start)
469− }
470−
471− value = newValue
472− }
473−
474− case .Decimal, .Exponent:
475− return try detectingFloatingPointErrors(parser.start) {
476− try decodeFloatingPointValue(parser, sign: sign, value: Double(value))
477− }
478−
479− case .PostDecimalDigits, .ExponentSign, .ExponentDigits:
480− assertionFailure("Invalid internal state while parsing number")
481−
482− case .Done:
483− fatalError("impossible condition")
484− }
485− }
486−
487− guard case let (signedValue, false) = Int.multiplyWithOverflow(sign.rawValue, value) else {
488− throw InternalError.NumberOverflow(offset: parser.start)
489− }
490−
491− loc = parser.loc
492− return .Int(signedValue)
493− }
494−
495− private mutating func decodeFloatingPointValue(parser: NumberParser, sign: Sign, value: Double) throws -> JSON {
496− var parser = parser
497− var value = value
498− var exponentSign = Sign.Positive
499− var exponent = Double(0)
500− var position = 0.1
501−
502− // This would be more natural as `while true { ... }` with a meaningful .Done case,
503− // but that causes compile time explosion in Swift 2.2. :-|
504− while parser.state != .Done {
505− switch parser.state {
506− case .LeadingMinus, .LeadingZero, .PreDecimalDigits:
507− assertionFailure("Invalid internal state while parsing number")
508−
509− case .Decimal:
510− try parser.parseDecimal()
511−
512− case .PostDecimalDigits:
513− parser.parsePostDecimalDigits { c in
514− value += position * Double(c - Literal.zero)
515− position /= 10
516− }
517−
518− case .Exponent:
519− exponentSign = try parser.parseExponent()
520−
521− case .ExponentSign:
522− try parser.parseExponentSign()
523−
524− case .ExponentDigits:
525− parser.parseExponentDigits { c in
526− exponent = exponent * 10 + Double(c - Literal.zero)
527− }
528−
529− case .Done:
530− fatalError("impossible condition")
531− }
532− }
533−
534− loc = parser.loc
535− return .Double(Double(sign.rawValue) * value * pow(10, Double(exponentSign.rawValue) * exponent))
536− }
537−
538− private mutating func decodeNumberAsString(start: Int) throws -> JSON {
539− var parser: NumberParser = {
540− let state: NumberParser.State
541− switch input[start] {
542− case Literal.MINUS: state = .LeadingMinus
543− case Literal.zero: state = .LeadingZero
544− case Literal.one...Literal.nine: state = .PreDecimalDigits
545− default:
546− fatalError("Internal error: decodeNumber called on not-a-number")
547− }
548− return NumberParser(loc: start, input: input, state: state)
549− }()
550−
551− stringDecodingBuffer.removeAll(keepCapacity: true)
552−
553− while true {
554− switch parser.state {
555− case .LeadingMinus:
556− try parser.parseNegative()
557− stringDecodingBuffer.append(Literal.MINUS)
558−
559− case .LeadingZero:
560− parser.parseLeadingZero()
561− stringDecodingBuffer.append(Literal.zero)
562−
563− case .PreDecimalDigits:
564− parser.parsePreDecimalDigits { stringDecodingBuffer.append($0) }
565−
566− case .Decimal:
567− try parser.parseDecimal()
568− stringDecodingBuffer.append(Literal.PERIOD)
569−
570− case .PostDecimalDigits:
571− parser.parsePostDecimalDigits { stringDecodingBuffer.append($0) }
572−
573− case .Exponent:
574− stringDecodingBuffer.append(input[parser.loc])
575− _ = try parser.parseExponent()
576−
577− case .ExponentSign:
578− stringDecodingBuffer.append(input[parser.loc])
579− try parser.parseExponentSign()
580−
581− case .ExponentDigits:
582− parser.parseExponentDigits { stringDecodingBuffer.append($0) }
583−
584− case .Done:
585− stringDecodingBuffer.append(0)
586− guard let string = (stringDecodingBuffer.withUnsafeBufferPointer {
587− String.fromCString(UnsafePointer($0.baseAddress))
588− }) else {
589− // Should never fail - any problems with the number string should
590− // result in thrown errors above
591− fatalError("Internal error: Invalid numeric string")
592− }
593−
594− loc = parser.loc
595− return .String(string)
596− }
597− }
598− }
599−
600− private func detectingFloatingPointErrors<T>(loc: Int, @noescape _ f: () throws -> T) throws -> T {
601− let flags = FE_UNDERFLOW | FE_OVERFLOW
602− feclearexcept(flags)
603− let value = try f()
604− guard fetestexcept(flags) == 0 else {
605− throw InternalError.NumberOverflow(offset: loc)
606− }
607− return value
608− }
609−}
610−
611−private struct NumberParser {
612− enum State {
613− case LeadingMinus
614− case LeadingZero
615− case PreDecimalDigits
616− case Decimal
617− case PostDecimalDigits
618− case Exponent
619− case ExponentSign
620− case ExponentDigits
621− case Done
622− }
623−
624− let start: Int
625− var loc = 0
626− var state: State
627− let input: UnsafeBufferPointer<UInt8>
628−
629− init(loc: Int, input: UnsafeBufferPointer<UInt8>, state: State) {
630− assert(loc < input.count, "Invalid input to NumberParser")
631− self.start = loc
632− self.loc = loc
633− self.input = input
634− self.state = state
635− }
636−
637− mutating func parseNegative() throws {
638− assert(state == .LeadingMinus, "Unexpected state entering parseNegative")
639−
640− loc = loc.successor()
641− guard loc < input.count else {
642− throw JSONParser.Error.EndOfStreamUnexpected
643− }
644−
645− switch input[loc] {
646− case Literal.zero:
647− state = .LeadingZero
648−
649− case Literal.one...Literal.nine:
650− state = .PreDecimalDigits
651−
652− default:
653− throw JSONParser.Error.NumberSymbolMissingDigits(offset: start)
654− }
655− }
656−
657− mutating func parseLeadingZero() {
658− assert(state == .LeadingZero, "Unexpected state entering parseLeadingZero")
659−
660− loc = loc.successor()
661− guard loc < input.count else {
662− state = .Done
663− return
664− }
665−
666− guard input[loc] == Literal.PERIOD else {
667− state = .Done
668− return
669− }
670−
671− state = .Decimal
672− }
673−
674− mutating func parsePreDecimalDigits(@noescape f: (UInt8) throws -> Void) rethrows {
675− assert(state == .PreDecimalDigits, "Unexpected state entering parsePreDecimalDigits")
676− advancing: while loc < input.count {
677− let c = input[loc]
678− switch c {
679− case Literal.zero...Literal.nine:
680− try f(c)
681− loc = loc.successor()
682−
683− case Literal.PERIOD:
684− state = .Decimal
685− return
686−
687− case Literal.e, Literal.E:
688− state = .Exponent
689− return
690−
691− default:
692− break advancing
693− }
694− }
695−
696− state = .Done
697− }
698−
699− mutating func parseDecimal() throws {
700− assert(state == .Decimal, "Unexpected state entering parseDecimal")
701− loc = loc.successor()
702− guard loc < input.count else {
703− throw JSONParser.Error.EndOfStreamUnexpected
704− }
705−
706− switch input[loc] {
707− case Literal.zero...Literal.nine:
708− state = .PostDecimalDigits
709−
710− default:
711− throw JSONParser.Error.NumberMissingFractionalDigits(offset: start)
712− }
713− }
714−
715− mutating func parsePostDecimalDigits(@noescape f: (UInt8) throws -> Void) rethrows {
716− assert(state == .PostDecimalDigits, "Unexpected state entering parsePostDecimalDigits")
717−
718− advancing: while loc < input.count {
719− let c = input[loc]
720− switch c {
721− case Literal.zero...Literal.nine:
722− try f(c)
723− loc = loc.successor()
724−
725− case Literal.e, Literal.E:
726− state = .Exponent
727− return
728−
729− default:
730− break advancing
731− }
732− }
733−
734− state = .Done
735− }
736−
737− mutating func parseExponent() throws -> JSONParser.Sign {
738− assert(state == .Exponent, "Unexpected state entering parseExponent")
739−
740− loc = loc.successor()
741− guard loc < input.count else {
742− throw JSONParser.Error.EndOfStreamUnexpected
743− }
744−
745− switch input[loc] {
746− case Literal.zero...Literal.nine:
747− state = .ExponentDigits
748−
749− case Literal.PLUS:
750− state = .ExponentSign
751−
752− case Literal.MINUS:
753− state = .ExponentSign
754− return .Negative
755−
756− default:
757− throw JSONParser.Error.NumberSymbolMissingDigits(offset: start)
758− }
759−
760− return .Positive
761− }
762−
763− mutating func parseExponentSign() throws {
764− assert(state == .ExponentSign, "Unexpected state entering parseExponentSign")
765− loc = loc.successor()
766− guard loc < input.count else {
767− throw JSONParser.Error.EndOfStreamUnexpected
768− }
769−
770− switch input[loc] {
771− case Literal.zero...Literal.nine:
772− state = .ExponentDigits
773−
774− default:
775− throw JSONParser.Error.NumberSymbolMissingDigits(offset: start)
776− }
777− }
778−
779− mutating func parseExponentDigits(@noescape f: (UInt8) throws -> Void) rethrows {
780− assert(state == .ExponentDigits, "Unexpected state entering parseExponentDigits")
781− advancing: while loc < input.count {
782− let c = input[loc]
783− switch c {
784− case Literal.zero...Literal.nine:
785− try f(c)
786− loc = loc.successor()
787−
788− default:
789− break advancing
790− }
791− }
792−
793− state = .Done
794− }
795−}
796−
797−public extension JSONParser {
798−
799− /// Creates a `JSONParser` ready to parse UTF-8 encoded `NSData`.
800− ///
801− /// If the data is mutable, it is copied before parsing. The data's lifetime
802− /// is extended for the duration of parsing.
803− init(utf8Data inData: NSData) {
804− let data = inData.copy() as! NSData
805− let buffer = UnsafeBufferPointer(start: UnsafePointer<UInt8>(data.bytes), count: data.length)
806− self.init(buffer: buffer, owner: data)
807− }
808−
809− /// Creates a `JSONParser` from the code units represented by the `string`.
810− ///
811− /// The synthesized string is lifetime-extended for the duration of parsing.
812− init(string: String) {
813− let codePoints = string.nulTerminatedUTF8
814− let buffer = codePoints.withUnsafeBufferPointer { nulTerminatedBuffer in
815− // don't want to include the nul termination in the buffer - trim it off
816− UnsafeBufferPointer(start: nulTerminatedBuffer.baseAddress, count: nulTerminatedBuffer.count - 1)
817− }
818− self.init(buffer: buffer, owner: codePoints)
819− }
820−
821−}
822−
823−extension JSONParser: JSONParserType {
824−
825− /// Creates an instance of `JSON` from UTF-8 encoded `NSData`.
826− /// - parameter data: An instance of `NSData` to parse `JSON` from.
827− /// - throws: Any `JSONParser.Error` that arises during decoding.
828− /// - seealso: JSONParser.parse()
829− public static func createJSONFromData(data: NSData) throws -> JSON {
830− var parser = JSONParser(utf8Data: data)
831− return try parser.parse()
832− }
833−
834−}
835−
836−// MARK: - Errors
837−
838−extension JSONParser {
839−
840− /// Enumeration describing possible errors that occur while parsing a JSON
841− /// document. Most errors include an associated `offset`, representing the
842− /// offset into the UTF-8 characters making up the document where the error
843− /// occurred.
844− public enum Error: ErrorType {
845− /// The parser ran out of data prematurely. This usually means a value
846− /// was not escaped, such as a string literal not ending with a double
847− /// quote.
848− case EndOfStreamUnexpected
849−
850− /// Unexpected non-whitespace data was left around `offset` after
851− /// parsing all valid JSON.
852− case EndOfStreamGarbage(offset: Int)
853−
854− /// Too many nested objects or arrays occured at the literal started
855− /// around `offset`.
856− case ExceededNestingLimit(offset: Int)
857−
858− /// A `character` was not a valid start of a value around `offset`.
859− case ValueInvalid(offset: Int, character: UnicodeScalar)
860−
861− /// Badly-formed Unicode escape sequence at `offset`. A Unicode escape
862− /// uses the text "\u" followed by 4 hex digits, such as "\uF09F\uA684"
863− /// to represent U+1F984, "UNICORN FACE".
864− case UnicodeEscapeInvalid(offset: Int)
865−
866− /// Badly-formed control character around `offset`. JSON supports
867− /// backslash-escaped double quotes, slashes, whitespace control codes,
868− /// and Unicode escape sequences.
869− case ControlCharacterUnrecognized(offset: Int)
870−
871− /// Invalid token, expected `null` around `offset`
872− case LiteralNilMisspelled(offset: Int)
873−
874− /// Invalid token, expected `true` around `offset`
875− case LiteralTrueMisspelled(offset: Int)
876−
877− /// Invalid token, expected `false` around `offset`
878− case LiteralFalseMisspelled(offset: Int)
879−
880− /// Badly-formed collection at given `offset`, expected `,` or `:`
881− case CollectionMissingSeparator(offset: Int)
882−
883− /// While parsing an object literal, a value was found without a key
884− /// around `offset`. The start of a string literal was expected.
885− case DictionaryMissingKey(offset: Int)
886−
887− /// Badly-formed number with no digits around `offset`. After a decimal
888− /// point, a number must include some number of digits.
889− case NumberMissingFractionalDigits(offset: Int)
890−
891− /// Badly-formed number with symbols ("-" or "e") but no following
892− /// digits around `offset`.
893− case NumberSymbolMissingDigits(offset: Int)
894−
895− /// Supplied data is encoded in an unsupported format.
896− case InvalidUnicodeStreamEncoding(detectedEncoding: JSONEncodingDetector.Encoding)
897− }
898−
899− private enum InternalError: ErrorType {
900− /// Attempted to parse an integer outside the range of [Int.min, Int.max]
901− /// or a double outside the range of representable doubles. Note that
902− /// for doubles, this could be an overflow or an underflow - we don't
903− /// get enough information from Swift here to know which it is. The number
904− /// causing the overflow/underflow began at `offset`.
905− case NumberOverflow(offset: Int)
906− }
907−}
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONParsing.swiftdeleted−126
@@ -1,126 +0,0 @@
1−//
2−// JSONParsing.swift
3−// Freddy
4−//
5−// Created by Matthew D. Mathias on 3/17/15.
6−// Copyright © 2015 Big Nerd Ranch. All rights reserved.
7−//
8−
9−import Foundation
10−
11−// MARK: - Deserialize JSON
12−
13−/// Protocol describing a backend parser that can produce `JSON` from `NSData`.
14−public protocol JSONParserType {
15−
16− /// Creates an instance of `JSON` from `NSData`.
17− /// - parameter data: An instance of `NSData` to use to create `JSON`.
18− /// - throws: An error that may arise from calling `JSONObjectWithData(_:options:)` on `NSJSONSerialization` with the given data.
19− /// - returns: An instance of `JSON`.
20− static func createJSONFromData(data: NSData) throws -> JSON
21−
22−}
23−
24−extension JSON {
25−
26− /// Create `JSON` from UTF-8 `data`. By default, parses using the
27− /// Swift-native `JSONParser` backend.
28− public init(data: NSData, usingParser parser: JSONParserType.Type = JSONParser.self) throws {
29− self = try parser.createJSONFromData(data)
30− }
31−
32− /// Create `JSON` from UTF-8 `string`.
33− public init(jsonString: Swift.String, usingParser parser: JSONParserType.Type = JSONParser.self) throws {
34− self = try parser.createJSONFromData((jsonString as NSString).dataUsingEncoding(NSUTF8StringEncoding) ?? NSData())
35− }
36−}
37−
38−// MARK: - NSJSONSerialization
39−
40−extension NSJSONSerialization: JSONParserType {
41−
42− // MARK: Decode NSData
43−
44− /// Use the built-in, Objective-C based JSON parser to create `JSON`.
45− /// - parameter data: An instance of `NSData`.
46− /// - returns: An instance of `JSON`.
47− /// - throws: An error that may arise if the `NSData` cannot be parsed into an object.
48− public static func createJSONFromData(data: NSData) throws -> JSON {
49− return makeJSON(try NSJSONSerialization.JSONObjectWithData(data, options: []))
50− }
51−
52− // MARK: Make JSON
53−
54− /// Makes a `JSON` object by matching its argument to a case in the `JSON` enum.
55− /// - parameter object: The instance of `AnyObject` returned from serializing the JSON.
56− /// - returns: An instance of `JSON` matching the JSON given to the function.
57− private static func makeJSON(object: AnyObject) -> JSON {
58− switch object {
59− case let n as NSNumber:
60− let numberType = CFNumberGetType(n)
61− switch numberType {
62− case .CharType:
63− return .Bool(n.boolValue)
64−
65− case .ShortType, .IntType, .LongType, .CFIndexType, .NSIntegerType, .SInt8Type, .SInt16Type, .SInt32Type:
66− return .Int(n.integerValue)
67−
68− case .SInt64Type, .LongLongType /* overflows 32-bit Int */:
69− #if /* 32-bit arch */ arch(arm) || arch(i386)
70− // Why double, when the Freddy parser would bump to String?
71− //
72− // Returning Double avoids making the type depend on whether you're running
73− // 32-bit or 64-bit code when using the NSJSONSerialization parser.
74− // NSJSONSerialization appears to bump numbers larger than Int.max to Double on
75− // 64-bit platforms but use .SInt64Type on 32-bit platforms.
76− // If we returned a String here, you'd get a String value on 32-bit,
77− // but a Double value on 64-bit. Instead, we return Double.
78− //
79− // This means that, if you switch parsers,
80− // you'll have to switch from .double to .string for pulling out
81− // overflowing values, but if you stick with a single parser,
82− // you at least won't have architecture-dependent lookups!
83− return .Double(n.doubleValue)
84− #else
85− return .Int(n.integerValue)
86− #endif
87−
88− case .Float32Type, .Float64Type, .FloatType, .DoubleType, .CGFloatType:
89− return .Double(n.doubleValue)
90− }
91−
92− case let arr as [AnyObject]:
93− return makeJSONArray(arr)
94−
95− case let dict as [Swift.String: AnyObject]:
96− return makeJSONDictionary(dict)
97−
98− case let s as Swift.String:
99− return .String(s)
100−
101− default:
102− return .Null
103− }
104− }
105−
106− // MARK: Make a JSON Array
107−
108− /// Makes a `JSON` array from the object passed in.
109− /// - parameter jsonArray: The array to transform into a `JSON`.
110− /// - returns: An instance of `JSON` matching the array.
111− private static func makeJSONArray(jsonArray: [AnyObject]) -> JSON {
112− return .Array(jsonArray.map(makeJSON))
113− }
114−
115− // MARK: Make a JSON Dictionary
116−
117− /// Makes a `JSON` dictionary from the Cocoa dictionary passed in.
118− /// - parameter jsonDict: The dictionary to transform into `JSON`.
119− /// - returns: An instance of `JSON` matching the dictionary.
120− private static func makeJSONDictionary(jsonDict: [Swift.String: AnyObject]) -> JSON {
121− return JSON(jsonDict.lazy.map { (key, value) in
122− (key, makeJSON(value))
123− })
124− }
125−
126−}
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONSerializing.swiftdeleted−43
@@ -1,43 +0,0 @@
1−// Copyright (C) 2016 Big Nerd Ranch, Inc. Licensed under the MIT license WITHOUT ANY WARRANTY.
2−
3−import Foundation
4−
5−// MARK: - Serialize JSON
6−
7−extension JSON {
8−
9− /// Attempt to serialize `JSON` into an `NSData`.
10− /// - returns: A byte-stream containing the `JSON` ready for wire transfer.
11− /// - throws: Errors that arise from `NSJSONSerialization`.
12− /// - see: Foundation.NSJSONSerialization
13− public func serialize() throws -> NSData {
14− let obj: AnyObject = toNSJSONSerializationObject()
15− return try NSJSONSerialization.dataWithJSONObject(obj, options: [])
16− }
17−
18− /// A function to help with the serialization of `JSON`.
19− /// - returns: An `AnyObject` suitable for `NSJSONSerialization`'s use.
20− private func toNSJSONSerializationObject() -> AnyObject {
21− switch self {
22− case .Array(let jsonArray):
23− return jsonArray.map { $0.toNSJSONSerializationObject() }
24− case .Dictionary(let jsonDictionary):
25− var cocoaDictionary = Swift.Dictionary<Swift.String, AnyObject>(minimumCapacity: jsonDictionary.count)
26− for (key, json) in jsonDictionary {
27− cocoaDictionary[key] = json.toNSJSONSerializationObject()
28− }
29− return cocoaDictionary
30− case .String(let str):
31− return str
32− case .Double(let num):
33− return num
34− case .Int(let int):
35− return int
36− case .Bool(let b):
37− return b
38− case .Null:
39− return NSNull()
40− }
41−
42− }
43−}
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/JSONSubscripting.swiftdeleted−705
@@ -1,705 +0,0 @@
1−//
2−// JSONSubscripting.swift
3−// Freddy
4−//
5−// Created by Zachary Waldowski on 8/15/15.
6−// Copyright © 2015 Big Nerd Ranch. All rights reserved.
7−//
8−
9−// MARK: JSONPathType
10−
11−/// A protocol used to define a path within an instance of `JSON` that leads to some desired value.
12−///
13−/// A custom type, such as a `RawRepresentable` enum, may be made to conform to `JSONPathType`
14−/// and used with the subscript APIs.
15−public protocol JSONPathType {
16− /// Use `self` to key into a `dictionary`.
17− ///
18− /// Unlike Swift dictionaries, failing to find a value for a key should throw
19− /// an error rather than convert to `nil`.
20− ///
21− /// Upon failure, implementers should throw an error from `JSON.Error`.
22− func valueInDictionary(dictionary: [Swift.String : JSON]) throws -> JSON
23−
24− /// Use `self` to index into an `array`.
25− ///
26− /// Unlike Swift array, attempting to index outside the collection's bounds
27− /// should throw an error rather than crash.
28− ///
29− /// Upon failure, implementers should throw an error from `JSON.Error`.
30− func valueInArray(array: [JSON]) throws -> JSON
31−}
32−
33−extension JSONPathType {
34−
35− /// The default behavior for keying into a dictionary is to throw
36− /// `JSON.Error.UnexpectedSubscript`.
37− public func valueInDictionary(dictionary: [Swift.String : JSON]) throws -> JSON {
38− throw JSON.Error.UnexpectedSubscript(type: Self.self)
39− }
40−
41− /// The default behavior for indexing into an array is to throw
42− /// `JSON.Error.UnexpectedSubscript`.
43− public func valueInArray(array: [JSON]) throws -> JSON {
44− throw JSON.Error.UnexpectedSubscript(type: Self.self)
45− }
46−
47−}
48−
49−extension String: JSONPathType {
50−
51− /// A method used to retrieve a value from a given dictionary for a specific key.
52− /// - parameter dictionary: A `Dictionary` with `String` keys and `JSON` values.
53− /// - throws: `.KeyNotFound` with an associated value of `self`, where `self` is a `String`,
54− /// should the key not be present within the `JSON`.
55− /// - returns: The `JSON` value associated with the given key.
56− public func valueInDictionary(dictionary: [Swift.String : JSON]) throws -> JSON {
57− guard let next = dictionary[self] else {
58− throw JSON.Error.KeyNotFound(key: self)
59− }
60− return next
61− }
62−
63−}
64−
65−extension Int: JSONPathType {
66−
67− /// A method used to retrieve a value from a given array for a specific index.
68− /// - parameter array: An `Array` of `JSON`.
69− /// - throws: `.IndexOutOfBounds` with an associated value of `self`, where `self` is an `Int`,
70− /// should the index not be within the valid range for the array of `JSON`.
71− /// - returns: The `JSON` value found at the given index.
72− public func valueInArray(array: [JSON]) throws -> JSON {
73− guard case array.indices = self else {
74− throw JSON.Error.IndexOutOfBounds(index: self)
75− }
76− return array[self]
77− }
78−
79−}
80−
81−// MARK: - Subscripting core
82−
83−private extension JSON {
84−
85− enum SubscriptError: ErrorType {
86− case SubscriptIntoNull(JSONPathType)
87− }
88−
89− func valueForPathFragment(fragment: JSONPathType, detectNull: Swift.Bool) throws -> JSON {
90− switch self {
91− case .Null where detectNull:
92− throw SubscriptError.SubscriptIntoNull(fragment)
93− case let .Dictionary(dict):
94− return try fragment.valueInDictionary(dict)
95− case let .Array(array):
96− return try fragment.valueInArray(array)
97− default:
98− throw Error.UnexpectedSubscript(type: fragment.dynamicType)
99− }
100− }
101−
102− func valueAtPath(path: [JSONPathType], detectNull: Swift.Bool = false) throws -> JSON {
103− var result = self
104− for fragment in path {
105− result = try result.valueForPathFragment(fragment, detectNull: detectNull)
106− }
107− return result
108− }
109−
110−}
111−
112−// MARK: - Subscripting operator
113−
114−extension JSON {
115−
116− public subscript(key: Swift.String) -> JSON? {
117− return try? valueForPathFragment(key, detectNull: false)
118− }
119−
120− public subscript(index: Swift.Int) -> JSON? {
121− return try? valueForPathFragment(index, detectNull: false)
122− }
123−
124−}
125−
126−// MARK: - Simple member unpacking
127−
128−extension JSON {
129−
130− /// Attempts to decode into the returning type from a path into JSON.
131− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`.
132− /// - parameter type: If the context this method is called from does not
133− /// make the return type clear, pass a type implementing `JSONDecodable`
134− /// to disambiguate the type to decode with.
135− /// - returns: An initialized member from the inner JSON.
136− /// - throws: One of the following errors contained in `JSON.Error`:
137− /// * `KeyNotFound`: A given `String` key does not exist inside a
138− /// descendant `JSON` dictionary.
139− /// * `IndexOutOfBounds`: A given `Int` index is outside the bounds of a
140− /// descendant `JSON` array.
141− /// * `UnexpectedSubscript`: A given subscript cannot be used with the
142− /// corresponding `JSON` value.
143− /// * `TypeNotConvertible`: The target value's type inside of
144− /// the `JSON` instance does not match `Decoded`.
145− public func decode<Decoded: JSONDecodable>(path: JSONPathType..., type: Decoded.Type = Decoded.self) throws -> Decoded {
146− return try Decoded(json: valueAtPath(path))
147− }
148−
149− /// Retrieves a `Double` from a path into JSON.
150− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
151− /// - returns: A floating-point `Double`
152− /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`.
153− /// - seealso: `JSON.decode(_:type:)`
154− public func double(path: JSONPathType...) throws -> Swift.Double {
155− return try Swift.Double(json: valueAtPath(path))
156− }
157−
158− /// Retrieves an `Int` from a path into JSON.
159− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
160− /// - returns: A numeric `Int`
161− /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`.
162− /// - seealso: `JSON.decode(_:type:)`
163− public func int(path: JSONPathType...) throws -> Swift.Int {
164− return try Swift.Int(json: valueAtPath(path))
165− }
166−
167− /// Retrieves a `String` from a path into JSON.
168− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
169− /// - returns: A textual `String`
170− /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`.
171− /// - seealso: `JSON.decode(_:type:)`
172− public func string(path: JSONPathType...) throws -> Swift.String {
173− return try Swift.String(json: valueAtPath(path))
174− }
175−
176− /// Retrieves a `Bool` from a path into JSON.
177− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
178− /// - returns: A truthy `Bool`
179− /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`.
180− /// - seealso: `JSON.decode(_:type:)`
181− public func bool(path: JSONPathType...) throws -> Swift.Bool {
182− return try Swift.Bool(json: valueAtPath(path))
183− }
184−
185− /// Retrieves a `[JSON]` from a path into JSON.
186− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
187− /// - returns: An `Array` of `JSON` elements
188− /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`.
189− /// - seealso: `JSON.decode(_:type:)`
190− public func array(path: JSONPathType...) throws -> [JSON] {
191− return try JSON.getArray(valueAtPath(path))
192− }
193−
194− /// Attempts to decode many values from a descendant JSON array at a path
195− /// into JSON.
196− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
197− /// - parameter type: If the context this method is called from does not
198− /// make the return type clear, pass a type implementing `JSONDecodable`
199− /// to disambiguate the type to decode with.
200− /// - returns: An `Array` of decoded elements
201− /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`, or
202− /// any error that arises from decoding the contained values.
203− /// - seealso: `JSON.decode(_:type:)`
204− public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., type: Decoded.Type = Decoded.self) throws -> [Decoded] {
205− return try JSON.getArrayOf(valueAtPath(path))
206− }
207−
208− /// Retrieves a `[String: JSON]` from a path into JSON.
209− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
210− /// - returns: An `Dictionary` of `String` mapping to `JSON` elements
211− /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`.
212− /// - seealso: `JSON.decode(_:type:)`
213− public func dictionary(path: JSONPathType...) throws -> [Swift.String: JSON] {
214− return try JSON.getDictionary(valueAtPath(path))
215− }
216−
217− /// Attempts to decode many values from a descendant JSON object at a path
218− /// into JSON.
219− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
220− /// - parameter type: If the context this method is called from does not
221− /// make the return type clear, pass a type implementing `JSONDecodable`
222− /// to disambiguate the value type to decode with.
223− /// - returns: A `Dictionary` of `String` keys and decoded values.
224− /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)` or
225− /// any error that arises from decoding the contained values.
226− /// - seealso: `JSON.decode(_:type:)`
227− public func dictionaryOf<Decoded: JSONDecodable>(path: JSONPathType..., type: Decoded.Type = Decoded.self) throws -> [Swift.String: Decoded] {
228− return try JSON.getDictionaryOf(valueAtPath(path))
229− }
230−
231−}
232−
233−// MARK: - NotFound-Or-Null-to-Optional unpacking
234−
235−extension JSON {
236−
237− /// An `OptionSetType` used to represent the different options available for subscripting `JSON` with `null` values or missing keys.
238− /// * `.NullBecomesNil` - Treat `null` values as `nil`.
239− /// * `.MissingKeyBecomesNil` - Treat missing keys as `nil`.
240− public struct SubscriptingOptions: OptionSetType {
241− public let rawValue: Swift.Int
242− public init(rawValue: Swift.Int) {
243− self.rawValue = rawValue
244− }
245−
246− /// Treat `null` values as `nil`.
247− public static let NullBecomesNil = SubscriptingOptions(rawValue: 1 << 0)
248− /// Treat missing keys as `nil`.
249− public static let MissingKeyBecomesNil = SubscriptingOptions(rawValue: 1 << 1)
250− }
251−
252− private func mapOptionalAtPath<Value>(path: [JSONPathType], alongPath: SubscriptingOptions, @noescape transform: JSON throws -> Value) throws -> Value? {
253− let detectNull = alongPath.contains(.NullBecomesNil)
254− let detectNotFound = alongPath.contains(.MissingKeyBecomesNil)
255− var json: JSON?
256− do {
257− json = try valueAtPath(path, detectNull: detectNull)
258− return try json.map(transform)
259− } catch Error.IndexOutOfBounds where detectNotFound {
260− return nil
261− } catch Error.KeyNotFound where detectNotFound {
262− return nil
263− } catch Error.ValueNotConvertible where detectNull && json == .Null {
264− return nil
265− } catch SubscriptError.SubscriptIntoNull where detectNull {
266− return nil
267− }
268− }
269−}
270−
271−extension JSON {
272−
273− /// Optionally decodes into the returning type from a path into JSON.
274− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
275− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
276− /// - parameter type: If the context this method is called from does not
277− /// make the return type clear, pass a type implementing `JSONDecodable`
278− /// to disambiguate the type to decode with.
279− /// - returns: A decoded value from the inner JSON if found, or `nil`.
280− /// - throws: One of the following errors contained in `JSON.Error`:
281− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
282− /// `JSON` dictionary.
283− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
284− /// descendant `JSON` array.
285− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
286− /// corresponding `JSON` value.
287− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
288− /// instance does not match the decoded value.
289− /// * Any error that arises from decoding the value.
290− public func decode<Decoded: JSONDecodable>(path: JSONPathType..., alongPath options: SubscriptingOptions, type: Decoded.Type = Decoded.self) throws -> Decoded? {
291− return try mapOptionalAtPath(path, alongPath: options, transform: Decoded.init)
292− }
293−
294− /// Optionally retrieves a `Double` from a path into JSON.
295− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`.
296− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
297− /// - returns: A `Double` if a value could be found, otherwise `nil`.
298− /// - throws: One of the following errors contained in `JSON.Error`:
299− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
300− /// `JSON` dictionary.
301− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
302− /// descendant `JSON` array.
303− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
304− /// corresponding `JSON` value.
305− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
306− /// instance does not match the decoded value.
307− public func double(path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> Swift.Double? {
308− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.Double.init)
309− }
310−
311− /// Optionally retrieves a `Int` from a path into JSON.
312− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
313− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
314− /// - returns: A numeric `Int` if a value could be found, otherwise `nil`.
315− /// - throws: One of the following errors contained in `JSON.Error`:
316− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
317− /// `JSON` dictionary.
318− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
319− /// descendant `JSON` array.
320− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
321− /// corresponding `JSON` value.
322− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
323− /// instance does not match the decoded value.
324− public func int(path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> Swift.Int? {
325− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.Int.init)
326− }
327−
328− /// Optionally retrieves a `String` from a path into JSON.
329− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
330− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
331− /// - returns: A text `String` if a value could be found, otherwise `nil`.
332− /// - throws: One of the following errors contained in `JSON.Error`:
333− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
334− /// `JSON` dictionary.
335− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
336− /// descendant `JSON` array.
337− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
338− /// corresponding `JSON` value.
339− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
340− /// instance does not match the decoded value.
341− public func string(path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> Swift.String? {
342− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.String.init)
343− }
344−
345− /// Optionally retrieves a `Bool` from a path into JSON.
346− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
347− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
348− /// - returns: A truthy `Bool` if a value could be found, otherwise `nil`.
349− /// - throws: One of the following errors contained in `JSON.Error`:
350− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
351− /// `JSON` dictionary.
352− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
353− /// descendant `JSON` array.
354− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
355− /// corresponding `JSON` value.
356− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
357− /// instance does not match the decoded value.
358− public func bool(path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> Swift.Bool? {
359− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.Bool.init)
360− }
361−
362− /// Optionally retrieves a `[JSON]` from a path into the recieving structure.
363− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
364− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
365− /// - returns: An `Array` of `JSON` elements if a value could be found,
366− /// otherwise `nil`.
367− /// - throws: One of the following errors contained in `JSON.Error`:
368− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
369− /// `JSON` dictionary.
370− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
371− /// descendant `JSON` array.
372− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
373− /// corresponding `JSON` value.
374− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
375− /// instance does not match the decoded value.
376− public func array(path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> [JSON]? {
377− return try mapOptionalAtPath(path, alongPath: options, transform: JSON.getArray)
378− }
379−
380− /// Optionally decodes many values from a descendant array at a path into
381− /// JSON.
382− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
383− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
384− /// - parameter type: If the context this method is called from does not
385− /// make the return type clear, pass a type implementing `JSONDecodable`
386− /// to disambiguate the value type to decode with.
387− /// - returns: An `Array` of decoded elements if found, otherwise `nil`.
388− /// - throws: One of the following errors contained in `JSON.Error`:
389− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
390− /// `JSON` dictionary.
391− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
392− /// descendant `JSON` array.
393− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
394− /// corresponding `JSON` value.
395− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
396− /// instance does not match the decoded value.
397− /// * Any error that arises from decoding the value.
398− public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., alongPath options: SubscriptingOptions, type: Decoded.Type = Decoded.self) throws -> [Decoded]? {
399− return try mapOptionalAtPath(path, alongPath: options, transform: JSON.getArrayOf)
400− }
401−
402− /// Optionally retrieves a `[String: JSON]` from a path into the recieving
403− /// structure.
404− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
405− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
406− /// - returns: A `Dictionary` of `String` mapping to `JSON` elements if a
407− /// value could be found, otherwise `nil`.
408− /// - throws: One of the following errors contained in `JSON.Error`:
409− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
410− /// `JSON` dictionary.
411− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
412− /// descendant `JSON` array.
413− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
414− /// corresponding `JSON` value.
415− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
416− /// instance does not match the decoded value.
417− public func dictionary(path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> [Swift.String: JSON]? {
418− return try mapOptionalAtPath(path, alongPath: options, transform: JSON.getDictionary)
419− }
420−
421− /// Optionally attempts to decode many values from a descendant object at a path
422− /// into JSON.
423− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
424− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
425− /// - parameter type: If the context this method is called from does not
426− /// make the return type clear, pass a type implementing `JSONDecodable`
427− /// to disambiguate the value type to decode with.
428− /// - returns: A `Dictionary` of `String` mapping to decoded elements if a
429− /// value could be found, otherwise `nil`.
430− /// - throws: One of the following errors contained in `JSON.Error`:
431− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
432− /// `JSON` dictionary.
433− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
434− /// descendant `JSON` array.
435− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
436− /// corresponding `JSON` value.
437− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
438− /// instance does not match the decoded value.
439− /// * Any error that arises from decoding the value.
440− public func dictionaryOf<Decoded: JSONDecodable>(path: JSONPathType..., alongPath options: SubscriptingOptions, type: Decoded.Type = Decoded.self) throws -> [Swift.String: Decoded]? {
441− return try mapOptionalAtPath(path, alongPath: options, transform: JSON.getDictionaryOf)
442− }
443−
444−}
445−
446−// MARK: - Missing-with-fallback unpacking
447−
448−extension JSON {
449−
450− private func mapOptionalAtPath<Value>(path: [JSONPathType], @noescape fallback: () -> Value, @noescape transform: JSON throws -> Value) throws -> Value {
451− return try mapOptionalAtPath(path, alongPath: .MissingKeyBecomesNil, transform: transform) ?? fallback()
452− }
453−
454− /// Attempts to decode into the returning type from a path into
455− /// JSON, or returns a fallback if not found.
456− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
457− /// - parameter fallback: Value to use when one is missing at the subscript.
458− /// - returns: An initialized member from the inner JSON.
459− /// - throws: One of the following errors contained in `JSON.Error`:
460− /// * `UnexpectedSubscript`: A given subscript cannot be used with the
461− /// corresponding `JSON` value.
462− /// * `TypeNotConvertible`: The target value's type inside of
463− /// the `JSON` instance does not match `Decoded`.
464− public func decode<Decoded: JSONDecodable>(path: JSONPathType..., @autoclosure or fallback: () -> Decoded) throws -> Decoded {
465− return try mapOptionalAtPath(path, fallback: fallback, transform: Decoded.init)
466− }
467−
468− /// Retrieves a `Double` from a path into JSON or a fallback if not found.
469− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
470− /// - parameter fallback: `Double` to use when one is missing at the subscript.
471− /// - returns: A floating-point `Double`
472− /// - throws: One of the `JSON.Error` cases thrown by calling `mapOptionalAtPath(_:fallback:transform:)`.
473− /// - seealso: `optionalAtPath(_:ifNotFound)`.
474− public func double(path: JSONPathType..., @autoclosure or fallback: () -> Swift.Double) throws -> Swift.Double {
475− return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.Double.init)
476− }
477−
478− /// Retrieves an `Int` from a path into JSON or a fallback if not found.
479− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
480− /// - parameter fallback: `Int` to use when one is missing at the subscript.
481− /// - returns: A numeric `Int`
482− /// - throws: One of the following errors contained in `JSON.Error`:
483− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
484− /// `JSON` dictionary.
485− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
486− /// descendant `JSON` array.
487− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
488− /// corresponding `JSON` value.
489− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
490− /// instance does not match the decoded value.
491− public func int(path: JSONPathType..., @autoclosure or fallback: () -> Swift.Int) throws -> Swift.Int {
492− return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.Int.init)
493− }
494−
495− /// Retrieves a `String` from a path into JSON or a fallback if not found.
496− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
497− /// - parameter fallback: `String` to use when one is missing at the subscript.
498− /// - returns: A textual `String`
499− /// - throws: One of the following errors contained in `JSON.Error`:
500− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
501− /// `JSON` dictionary.
502− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
503− /// descendant `JSON` array.
504− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
505− /// corresponding `JSON` value.
506− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
507− /// instance does not match the decoded value.
508− public func string(path: JSONPathType..., @autoclosure or fallback: () -> Swift.String) throws -> Swift.String {
509− return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.String.init)
510− }
511−
512− /// Retrieves a `Bool` from a path into JSON or a fallback if not found.
513− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
514− /// - parameter fallback: `Bool` to use when one is missing at the subscript.
515− /// - returns: A truthy `Bool`
516− /// - throws: One of the following errors contained in `JSON.Error`:
517− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
518− /// `JSON` dictionary.
519− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
520− /// descendant `JSON` array.
521− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
522− /// corresponding `JSON` value.
523− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
524− /// instance does not match the decoded value.
525− public func bool(path: JSONPathType..., @autoclosure or fallback: () -> Swift.Bool) throws -> Swift.Bool {
526− return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.Bool.init)
527− }
528−
529− /// Retrieves a `[JSON]` from a path into JSON or a fallback if not found.
530− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
531− /// - parameter fallback: `Array` to use when one is missing at the subscript.
532− /// - returns: An `Array` of `JSON` elements
533− /// - throws: One of the following errors contained in `JSON.Error`:
534− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
535− /// `JSON` dictionary.
536− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
537− /// descendant `JSON` array.
538− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
539− /// corresponding `JSON` value.
540− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
541− /// instance does not match the decoded value.
542− public func array(path: JSONPathType..., @autoclosure or fallback: () -> [JSON]) throws -> [JSON] {
543− return try mapOptionalAtPath(path, fallback: fallback, transform: JSON.getArray)
544− }
545−
546− /// Attempts to decodes many values from a desendant JSON array at a path
547− /// into the recieving structure, returning a fallback if not found.
548− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
549− /// - parameter fallback: `Array` to use when one is missing at the subscript.
550− /// - returns: An `Array` of decoded elements
551− /// - throws: One of the following errors contained in `JSON.Error`:
552− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
553− /// `JSON` dictionary.
554− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
555− /// descendant `JSON` array.
556− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
557− /// corresponding `JSON` value.
558− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
559− /// instance does not match the decoded value.
560− /// * Any error that arises from decoding the value.
561− public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., @autoclosure or fallback: () -> [Decoded]) throws -> [Decoded] {
562− return try mapOptionalAtPath(path, fallback: fallback, transform: JSON.getArrayOf)
563− }
564−
565− /// Retrieves a `[String: JSON]` from a path into JSON or a fallback if not
566− /// found.
567− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
568− /// - parameter fallback: `Dictionary` to use when one is missing at the subscript.
569− /// - returns: An `Dictionary` of `String` mapping to `JSON` elements
570− /// - throws: One of the following errors contained in `JSON.Error`:
571− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
572− /// `JSON` dictionary.
573− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
574− /// descendant `JSON` array.
575− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
576− /// corresponding `JSON` value.
577− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
578− /// instance does not match the decoded value.
579− public func dictionary(path: JSONPathType..., @autoclosure or fallback: () -> [Swift.String: JSON]) throws -> [Swift.String: JSON] {
580− return try mapOptionalAtPath(path, fallback: fallback, transform: JSON.getDictionary)
581− }
582−
583− /// Attempts to decode many values from a descendant JSON object at a path
584− /// into the receiving structure, returning a fallback if not found.
585− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
586− /// - parameter fallback: Value to use when one is missing at the subscript
587− /// - returns: A `Dictionary` of `String` mapping to decoded elements.
588− /// - throws: One of the following errors contained in `JSON.Error`:
589− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
590− /// `JSON` dictionary.
591− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
592− /// descendant `JSON` array.
593− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
594− /// corresponding `JSON` value.
595− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
596− /// instance does not match the decoded value.
597− /// * Any error that arises from decoding the value.
598− public func dictionaryOf<Decoded: JSONDecodable>(path: JSONPathType..., @autoclosure or fallback: () -> [Swift.String: Decoded]) throws -> [Swift.String: Decoded] {
599− return try mapOptionalAtPath(path, fallback: fallback, transform: JSON.getDictionaryOf)
600− }
601−
602−
603−}
604−
605−// MARK: - Deprecated methods
606−
607−extension JSON {
608−
609− @available(*, deprecated, message="Use 'decode(_:alongPath:type:)' with options '[.MissingKeyBecomesNil]'")
610− public func decode<Decoded: JSONDecodable>(path: JSONPathType..., ifNotFound: Swift.Bool, type: Decoded.Type = Decoded.self) throws -> Decoded? {
611− let options: SubscriptingOptions = ifNotFound ? [.MissingKeyBecomesNil] : []
612− return try mapOptionalAtPath(path, alongPath: options, transform: Decoded.init)
613− }
614−
615− @available(*, deprecated, message="Use 'decode(_:alongPath:type:)' with options '[.NullBecomesNil]'")
616− public func decode<Decoded: JSONDecodable>(path: JSONPathType..., ifNull: Swift.Bool, type: Decoded.Type = Decoded.self) throws -> Decoded? {
617− let options: SubscriptingOptions = ifNull ? [.NullBecomesNil] : []
618− return try mapOptionalAtPath(path, alongPath: options, transform: Decoded.init)
619− }
620−
621− @available(*, deprecated, message="Use 'double(_:alongPath:)' with options '[.MissingKeyBecomesNil]'")
622− public func double(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.Double? {
623− let options: SubscriptingOptions = ifNotFound ? [.MissingKeyBecomesNil] : []
624− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.Double.init)
625− }
626−
627− @available(*, deprecated, message="Use 'double(_:alongPath:)' with options '[.NullBecomesNil]'")
628− public func double(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.Double? {
629− let options: SubscriptingOptions = ifNull ? [.NullBecomesNil] : []
630− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.Double.init)
631− }
632−
633− @available(*, deprecated, message="Use 'int(_:alongPath:)' with options '[.MissingKeyBecomesNil]'")
634− public func int(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.Int? {
635− let options: SubscriptingOptions = ifNotFound ? [.MissingKeyBecomesNil] : []
636− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.Int.init)
637− }
638−
639− @available(*, deprecated, message="Use 'int(_:alongPath:)' with options '[.NullBecomesNil]'")
640− public func int(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.Int? {
641− let options: SubscriptingOptions = ifNull ? [.NullBecomesNil] : []
642− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.Int.init)
643− }
644−
645− @available(*, deprecated, message="Use 'string(_:alongPath:)' with options '[.MissingKeyBecomesNil]'")
646− public func string(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.String? {
647− let options: SubscriptingOptions = ifNotFound ? [.MissingKeyBecomesNil] : []
648− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.String.init)
649− }
650−
651− @available(*, deprecated, message="Use 'string(_:alongPath:)' with options '[.NullBecomesNil]'")
652− public func string(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.String? {
653− let options: SubscriptingOptions = ifNull ? [.NullBecomesNil] : []
654− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.String.init)
655− }
656−
657− @available(*, deprecated, message="Use 'bool(_:alongPath:)' with options '[.MissingKeyBecomesNil]'")
658− public func bool(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.Bool? {
659− let options: SubscriptingOptions = ifNotFound ? [.MissingKeyBecomesNil] : []
660− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.Bool.init)
661− }
662−
663− @available(*, deprecated, message="Use 'bool(_:alongPath:)' with options '[.NullBecomesNil]'")
664− public func bool(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.Bool? {
665− let options: SubscriptingOptions = ifNull ? [.NullBecomesNil] : []
666− return try mapOptionalAtPath(path, alongPath: options, transform: Swift.Bool.init)
667− }
668−
669− @available(*, deprecated, message="Use 'array(_:alongPath:)' with options '[.MissingKeyBecomesNil]'")
670− public func array(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> [JSON]? {
671− let options: SubscriptingOptions = ifNotFound ? [.MissingKeyBecomesNil] : []
672− return try mapOptionalAtPath(path, alongPath: options, transform: JSON.getArray)
673− }
674−
675− @available(*, deprecated, message="Use 'array(_:alongPath:)' with options '[.NullBecomesNil]'")
676− public func array(path: JSONPathType..., ifNull: Swift.Bool) throws -> [JSON]? {
677− let options: SubscriptingOptions = ifNull ? [.NullBecomesNil] : []
678− return try mapOptionalAtPath(path, alongPath: options, transform: JSON.getArray)
679− }
680−
681− @available(*, deprecated, message="Use 'arrayOf(_:alongPath:)' with options '[.MissingKeyBecomesNil]'")
682− public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> [Decoded]? {
683− let options: SubscriptingOptions = ifNotFound ? [.MissingKeyBecomesNil] : []
684− return try mapOptionalAtPath(path, alongPath: options, transform: JSON.getArrayOf)
685− }
686−
687− @available(*, deprecated, message="Use 'arrayOf(_:alongPath:)' with options '[.NullBecomesNil]'")
688− public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., ifNull: Swift.Bool) throws -> [Decoded]? {
689− let options: SubscriptingOptions = ifNull ? [.NullBecomesNil] : []
690− return try mapOptionalAtPath(path, alongPath: options, transform: JSON.getArrayOf)
691− }
692−
693− @available(*, deprecated, message="Use 'dictionary(_:alongPath:)' with options '[.MissingKeyBecomesNil]'")
694− public func dictionary(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> [Swift.String: JSON]? {
695− let options: SubscriptingOptions = ifNotFound ? [.MissingKeyBecomesNil] : []
696− return try mapOptionalAtPath(path, alongPath: options, transform: JSON.getDictionary)
697− }
698−
699− @available(*, deprecated, message="Use 'dictionary(_:alongPath:)' with options '[.NullBecomesNil]'")
700− public func dictionary(path: JSONPathType..., ifNull: Swift.Bool) throws -> [Swift.String: JSON]? {
701− let options: SubscriptingOptions = ifNull ? [.NullBecomesNil] : []
702− return try mapOptionalAtPath(path, alongPath: options, transform: JSON.getDictionary)
703− }
704−
705−}
tests/JSONTestSuite/parsers/test_Freddy_20160830/test_Freddy/main.swiftdeleted−37
@@ -1,37 +0,0 @@
1−//
2−// main.swift
3−// test_Freddy
4−//
5−// Created by nst on 10/08/16.
6−// Copyright © 2016 Nicolas Seriot. All rights reserved.
7−//
8−
9−import Foundation
10−
11−func main() {
12−
13− guard Process.arguments.count == 2 else {
14− let url = NSURL(fileURLWithPath: Process.arguments[0])
15− guard let programName = url.lastPathComponent else { exit(1) }
16− print("Usage: ./\(programName) file.json")
17− exit(1)
18− }
19−
20− let path = Process.arguments[1]
21− let url = NSURL.fileURLWithPath(path)
22−
23− guard let data = NSData(contentsOfURL:url) else {
24− print("*** CANNOT READ DATA AT \(url)")
25− return
26− }
27−
28− var p = JSONParser(utf8Data: data)
29− do {
30− try p.parse()
31− exit(0)
32− } catch {
33− exit(1)
34− }
35−}
36−
37−main()
tests/JSONTestSuite/parsers/test_Freddy_20161018/bin/test_Freddydeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/project.pbxprojdeleted−300
@@ -1,300 +0,0 @@
1−// !$*UTF8*$!
2−{
3− archiveVersion = 1;
4− classes = {
5− };
6− objectVersion = 46;
7− objects = {
8−
9−/* Begin PBXBuildFile section */
10− 03D84ABB1D5B0A1000776402 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D84ABA1D5B0A1000776402 /* main.swift */; };
11− 03F8F7811D5B75600021630C /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F7781D5B75600021630C /* JSON.swift */; };
12− 03F8F7821D5B75600021630C /* JSONDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F7791D5B75600021630C /* JSONDecodable.swift */; };
13− 03F8F7831D5B75600021630C /* JSONEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77A1D5B75600021630C /* JSONEncodable.swift */; };
14− 03F8F7841D5B75600021630C /* JSONEncodingDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77B1D5B75600021630C /* JSONEncodingDetector.swift */; };
15− 03F8F7851D5B75600021630C /* JSONLiteralConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77C1D5B75600021630C /* JSONLiteralConvertible.swift */; };
16− 03F8F7861D5B75600021630C /* JSONParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77D1D5B75600021630C /* JSONParser.swift */; };
17− 03F8F7871D5B75600021630C /* JSONParsing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77E1D5B75600021630C /* JSONParsing.swift */; };
18− 03F8F7881D5B75600021630C /* JSONSerializing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77F1D5B75600021630C /* JSONSerializing.swift */; };
19− 03F8F7891D5B75600021630C /* JSONSubscripting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F7801D5B75600021630C /* JSONSubscripting.swift */; };
20−/* End PBXBuildFile section */
21−
22−/* Begin PBXCopyFilesBuildPhase section */
23− 03D84AB51D5B0A1000776402 /* CopyFiles */ = {
24− isa = PBXCopyFilesBuildPhase;
25− buildActionMask = 2147483647;
26− dstPath = /usr/share/man/man1;
27− dstSubfolderSpec = 0;
28− files = (
29− );
30− runOnlyForDeploymentPostprocessing = 1;
31− };
32−/* End PBXCopyFilesBuildPhase section */
33−
34−/* Begin PBXFileReference section */
35− 03D84AB71D5B0A1000776402 /* test_Freddy */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = test_Freddy; sourceTree = BUILT_PRODUCTS_DIR; };
36− 03D84ABA1D5B0A1000776402 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
37− 03F8F7781D5B75600021630C /* JSON.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSON.swift; path = test_Freddy/JSON.swift; sourceTree = "<group>"; };
38− 03F8F7791D5B75600021630C /* JSONDecodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONDecodable.swift; path = test_Freddy/JSONDecodable.swift; sourceTree = "<group>"; };
39− 03F8F77A1D5B75600021630C /* JSONEncodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONEncodable.swift; path = test_Freddy/JSONEncodable.swift; sourceTree = "<group>"; };
40− 03F8F77B1D5B75600021630C /* JSONEncodingDetector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONEncodingDetector.swift; path = test_Freddy/JSONEncodingDetector.swift; sourceTree = "<group>"; };
41− 03F8F77C1D5B75600021630C /* JSONLiteralConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONLiteralConvertible.swift; path = test_Freddy/JSONLiteralConvertible.swift; sourceTree = "<group>"; };
42− 03F8F77D1D5B75600021630C /* JSONParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONParser.swift; path = test_Freddy/JSONParser.swift; sourceTree = "<group>"; };
43− 03F8F77E1D5B75600021630C /* JSONParsing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONParsing.swift; path = test_Freddy/JSONParsing.swift; sourceTree = "<group>"; };
44− 03F8F77F1D5B75600021630C /* JSONSerializing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONSerializing.swift; path = test_Freddy/JSONSerializing.swift; sourceTree = "<group>"; };
45− 03F8F7801D5B75600021630C /* JSONSubscripting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONSubscripting.swift; path = test_Freddy/JSONSubscripting.swift; sourceTree = "<group>"; };
46−/* End PBXFileReference section */
47−
48−/* Begin PBXFrameworksBuildPhase section */
49− 03D84AB41D5B0A1000776402 /* Frameworks */ = {
50− isa = PBXFrameworksBuildPhase;
51− buildActionMask = 2147483647;
52− files = (
53− );
54− runOnlyForDeploymentPostprocessing = 0;
55− };
56−/* End PBXFrameworksBuildPhase section */
57−
58−/* Begin PBXGroup section */
59− 03D84AAE1D5B0A1000776402 = {
60− isa = PBXGroup;
61− children = (
62− 03F8F7781D5B75600021630C /* JSON.swift */,
63− 03F8F7791D5B75600021630C /* JSONDecodable.swift */,
64− 03F8F77A1D5B75600021630C /* JSONEncodable.swift */,
65− 03F8F77B1D5B75600021630C /* JSONEncodingDetector.swift */,
66− 03F8F77C1D5B75600021630C /* JSONLiteralConvertible.swift */,
67− 03F8F77D1D5B75600021630C /* JSONParser.swift */,
68− 03F8F77E1D5B75600021630C /* JSONParsing.swift */,
69− 03F8F77F1D5B75600021630C /* JSONSerializing.swift */,
70− 03F8F7801D5B75600021630C /* JSONSubscripting.swift */,
71− 03D84AB91D5B0A1000776402 /* test_Freddy */,
72− 03D84AB81D5B0A1000776402 /* Products */,
73− );
74− sourceTree = "<group>";
75− };
76− 03D84AB81D5B0A1000776402 /* Products */ = {
77− isa = PBXGroup;
78− children = (
79− 03D84AB71D5B0A1000776402 /* test_Freddy */,
80− );
81− name = Products;
82− sourceTree = "<group>";
83− };
84− 03D84AB91D5B0A1000776402 /* test_Freddy */ = {
85− isa = PBXGroup;
86− children = (
87− 03D84ABA1D5B0A1000776402 /* main.swift */,
88− );
89− path = test_Freddy;
90− sourceTree = "<group>";
91− };
92−/* End PBXGroup section */
93−
94−/* Begin PBXNativeTarget section */
95− 03D84AB61D5B0A1000776402 /* test_Freddy */ = {
96− isa = PBXNativeTarget;
97− buildConfigurationList = 03D84ABE1D5B0A1000776402 /* Build configuration list for PBXNativeTarget "test_Freddy" */;
98− buildPhases = (
99− 03D84AB31D5B0A1000776402 /* Sources */,
100− 03D84AB41D5B0A1000776402 /* Frameworks */,
101− 03D84AB51D5B0A1000776402 /* CopyFiles */,
102− );
103− buildRules = (
104− );
105− dependencies = (
106− );
107− name = test_Freddy;
108− productName = test_Freddy;
109− productReference = 03D84AB71D5B0A1000776402 /* test_Freddy */;
110− productType = "com.apple.product-type.tool";
111− };
112−/* End PBXNativeTarget section */
113−
114−/* Begin PBXProject section */
115− 03D84AAF1D5B0A1000776402 /* Project object */ = {
116− isa = PBXProject;
117− attributes = {
118− LastSwiftUpdateCheck = 0800;
119− LastUpgradeCheck = 0800;
120− ORGANIZATIONNAME = "Nicolas Seriot";
121− TargetAttributes = {
122− 03D84AB61D5B0A1000776402 = {
123− CreatedOnToolsVersion = 8.0;
124− DevelopmentTeam = VBYRKYS73S;
125− DevelopmentTeamName = "Nicolas Seriot";
126− ProvisioningStyle = Automatic;
127− };
128− };
129− };
130− buildConfigurationList = 03D84AB21D5B0A1000776402 /* Build configuration list for PBXProject "test_Freddy" */;
131− compatibilityVersion = "Xcode 3.2";
132− developmentRegion = English;
133− hasScannedForEncodings = 0;
134− knownRegions = (
135− en,
136− );
137− mainGroup = 03D84AAE1D5B0A1000776402;
138− productRefGroup = 03D84AB81D5B0A1000776402 /* Products */;
139− projectDirPath = "";
140− projectRoot = "";
141− targets = (
142− 03D84AB61D5B0A1000776402 /* test_Freddy */,
143− );
144− };
145−/* End PBXProject section */
146−
147−/* Begin PBXSourcesBuildPhase section */
148− 03D84AB31D5B0A1000776402 /* Sources */ = {
149− isa = PBXSourcesBuildPhase;
150− buildActionMask = 2147483647;
151− files = (
152− 03F8F7881D5B75600021630C /* JSONSerializing.swift in Sources */,
153− 03F8F7821D5B75600021630C /* JSONDecodable.swift in Sources */,
154− 03F8F7851D5B75600021630C /* JSONLiteralConvertible.swift in Sources */,
155− 03F8F7871D5B75600021630C /* JSONParsing.swift in Sources */,
156− 03F8F7861D5B75600021630C /* JSONParser.swift in Sources */,
157− 03F8F7831D5B75600021630C /* JSONEncodable.swift in Sources */,
158− 03D84ABB1D5B0A1000776402 /* main.swift in Sources */,
159− 03F8F7811D5B75600021630C /* JSON.swift in Sources */,
160− 03F8F7891D5B75600021630C /* JSONSubscripting.swift in Sources */,
161− 03F8F7841D5B75600021630C /* JSONEncodingDetector.swift in Sources */,
162− );
163− runOnlyForDeploymentPostprocessing = 0;
164− };
165−/* End PBXSourcesBuildPhase section */
166−
167−/* Begin XCBuildConfiguration section */
168− 03D84ABC1D5B0A1000776402 /* Debug */ = {
169− isa = XCBuildConfiguration;
170− buildSettings = {
171− ALWAYS_SEARCH_USER_PATHS = NO;
172− CLANG_ANALYZER_NONNULL = YES;
173− CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
174− CLANG_CXX_LIBRARY = "libc++";
175− CLANG_ENABLE_MODULES = YES;
176− CLANG_ENABLE_OBJC_ARC = YES;
177− CLANG_WARN_BOOL_CONVERSION = YES;
178− CLANG_WARN_CONSTANT_CONVERSION = YES;
179− CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
180− CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
181− CLANG_WARN_EMPTY_BODY = YES;
182− CLANG_WARN_ENUM_CONVERSION = YES;
183− CLANG_WARN_INT_CONVERSION = YES;
184− CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
185− CLANG_WARN_UNREACHABLE_CODE = YES;
186− CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
187− CODE_SIGN_IDENTITY = "-";
188− COPY_PHASE_STRIP = NO;
189− DEBUG_INFORMATION_FORMAT = dwarf;
190− ENABLE_STRICT_OBJC_MSGSEND = YES;
191− ENABLE_TESTABILITY = YES;
192− GCC_C_LANGUAGE_STANDARD = gnu99;
193− GCC_DYNAMIC_NO_PIC = NO;
194− GCC_NO_COMMON_BLOCKS = YES;
195− GCC_OPTIMIZATION_LEVEL = 0;
196− GCC_PREPROCESSOR_DEFINITIONS = (
197− "DEBUG=1",
198− "$(inherited)",
199− );
200− GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
201− GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
202− GCC_WARN_UNDECLARED_SELECTOR = YES;
203− GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
204− GCC_WARN_UNUSED_FUNCTION = YES;
205− GCC_WARN_UNUSED_VARIABLE = YES;
206− MACOSX_DEPLOYMENT_TARGET = 10.11;
207− MTL_ENABLE_DEBUG_INFO = YES;
208− ONLY_ACTIVE_ARCH = YES;
209− SDKROOT = macosx;
210− SWIFT_OPTIMIZATION_LEVEL = "-Onone";
211− };
212− name = Debug;
213− };
214− 03D84ABD1D5B0A1000776402 /* Release */ = {
215− isa = XCBuildConfiguration;
216− buildSettings = {
217− ALWAYS_SEARCH_USER_PATHS = NO;
218− CLANG_ANALYZER_NONNULL = YES;
219− CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
220− CLANG_CXX_LIBRARY = "libc++";
221− CLANG_ENABLE_MODULES = YES;
222− CLANG_ENABLE_OBJC_ARC = YES;
223− CLANG_WARN_BOOL_CONVERSION = YES;
224− CLANG_WARN_CONSTANT_CONVERSION = YES;
225− CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
226− CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
227− CLANG_WARN_EMPTY_BODY = YES;
228− CLANG_WARN_ENUM_CONVERSION = YES;
229− CLANG_WARN_INT_CONVERSION = YES;
230− CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
231− CLANG_WARN_UNREACHABLE_CODE = YES;
232− CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
233− CODE_SIGN_IDENTITY = "-";
234− COPY_PHASE_STRIP = NO;
235− DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
236− ENABLE_NS_ASSERTIONS = NO;
237− ENABLE_STRICT_OBJC_MSGSEND = YES;
238− GCC_C_LANGUAGE_STANDARD = gnu99;
239− GCC_NO_COMMON_BLOCKS = YES;
240− GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
241− GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
242− GCC_WARN_UNDECLARED_SELECTOR = YES;
243− GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
244− GCC_WARN_UNUSED_FUNCTION = YES;
245− GCC_WARN_UNUSED_VARIABLE = YES;
246− MACOSX_DEPLOYMENT_TARGET = 10.11;
247− MTL_ENABLE_DEBUG_INFO = NO;
248− SDKROOT = macosx;
249− };
250− name = Release;
251− };
252− 03D84ABF1D5B0A1000776402 /* Debug */ = {
253− isa = XCBuildConfiguration;
254− buildSettings = {
255− FRAMEWORK_SEARCH_PATHS = (
256− "$(inherited)",
257− "$(PROJECT_DIR)",
258− );
259− PRODUCT_NAME = "$(TARGET_NAME)";
260− SWIFT_VERSION = 3.0;
261− };
262− name = Debug;
263− };
264− 03D84AC01D5B0A1000776402 /* Release */ = {
265− isa = XCBuildConfiguration;
266− buildSettings = {
267− FRAMEWORK_SEARCH_PATHS = (
268− "$(inherited)",
269− "$(PROJECT_DIR)",
270− );
271− PRODUCT_NAME = "$(TARGET_NAME)";
272− SWIFT_VERSION = 3.0;
273− };
274− name = Release;
275− };
276−/* End XCBuildConfiguration section */
277−
278−/* Begin XCConfigurationList section */
279− 03D84AB21D5B0A1000776402 /* Build configuration list for PBXProject "test_Freddy" */ = {
280− isa = XCConfigurationList;
281− buildConfigurations = (
282− 03D84ABC1D5B0A1000776402 /* Debug */,
283− 03D84ABD1D5B0A1000776402 /* Release */,
284− );
285− defaultConfigurationIsVisible = 0;
286− defaultConfigurationName = Release;
287− };
288− 03D84ABE1D5B0A1000776402 /* Build configuration list for PBXNativeTarget "test_Freddy" */ = {
289− isa = XCConfigurationList;
290− buildConfigurations = (
291− 03D84ABF1D5B0A1000776402 /* Debug */,
292− 03D84AC01D5B0A1000776402 /* Release */,
293− );
294− defaultConfigurationIsVisible = 0;
295− defaultConfigurationName = Release;
296− };
297−/* End XCConfigurationList section */
298− };
299− rootObject = 03D84AAF1D5B0A1000776402 /* Project object */;
300−}
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7
@@ -1,7 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<Workspace
3− version = "1.0">
4− <FileRef
5− location = "self:test_Freddy.xcodeproj">
6− </FileRef>
7−</Workspace>
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/project.xcworkspace/xcshareddata/test_Freddy.xcscmblueprintdeleted−30
@@ -1,30 +0,0 @@
1−{
2− "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A",
3− "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4−
5− },
6− "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
7− "6ADA245F937D8ED6D99F5A7865E19F5267A169E2" : 0,
8− "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A" : 0
9− },
10− "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "7B3DFA55-F9BF-41D8-8FD5-204D3162EB03",
11− "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
12− "6ADA245F937D8ED6D99F5A7865E19F5267A169E2" : "dropbox\/JSON\/test_Freddy\/Vendor\/Freddy\/",
13− "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A" : "dropbox\/"
14− },
15− "DVTSourceControlWorkspaceBlueprintNameKey" : "test_Freddy",
16− "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17− "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "JSON\/test_Freddy\/test_Freddy.xcodeproj",
18− "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19− {
20− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/bignerdranch\/Freddy.git",
21− "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
22− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "6ADA245F937D8ED6D99F5A7865E19F5267A169E2"
23− },
24− {
25− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "\/Users\/nst\/Dropbox\/dropbox.git",
26− "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
27− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A"
28− }
29− ]
30−}
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_Freddy.xcschemedeleted−91
@@ -1,91 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<Scheme
3− LastUpgradeVersion = "0800"
4− version = "1.3">
5− <BuildAction
6− parallelizeBuildables = "YES"
7− buildImplicitDependencies = "YES">
8− <BuildActionEntries>
9− <BuildActionEntry
10− buildForTesting = "YES"
11− buildForRunning = "YES"
12− buildForProfiling = "YES"
13− buildForArchiving = "YES"
14− buildForAnalyzing = "YES">
15− <BuildableReference
16− BuildableIdentifier = "primary"
17− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
18− BuildableName = "test_Freddy"
19− BlueprintName = "test_Freddy"
20− ReferencedContainer = "container:test_Freddy.xcodeproj">
21− </BuildableReference>
22− </BuildActionEntry>
23− </BuildActionEntries>
24− </BuildAction>
25− <TestAction
26− buildConfiguration = "Debug"
27− selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28− selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29− shouldUseLaunchSchemeArgsEnv = "YES">
30− <Testables>
31− </Testables>
32− <MacroExpansion>
33− <BuildableReference
34− BuildableIdentifier = "primary"
35− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
36− BuildableName = "test_Freddy"
37− BlueprintName = "test_Freddy"
38− ReferencedContainer = "container:test_Freddy.xcodeproj">
39− </BuildableReference>
40− </MacroExpansion>
41− <AdditionalOptions>
42− </AdditionalOptions>
43− </TestAction>
44− <LaunchAction
45− buildConfiguration = "Debug"
46− selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
47− selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
48− launchStyle = "0"
49− useCustomWorkingDirectory = "NO"
50− ignoresPersistentStateOnLaunch = "NO"
51− debugDocumentVersioning = "YES"
52− debugServiceExtension = "internal"
53− allowLocationSimulation = "YES">
54− <BuildableProductRunnable
55− runnableDebuggingMode = "0">
56− <BuildableReference
57− BuildableIdentifier = "primary"
58− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
59− BuildableName = "test_Freddy"
60− BlueprintName = "test_Freddy"
61− ReferencedContainer = "container:test_Freddy.xcodeproj">
62− </BuildableReference>
63− </BuildableProductRunnable>
64− <AdditionalOptions>
65− </AdditionalOptions>
66− </LaunchAction>
67− <ProfileAction
68− buildConfiguration = "Release"
69− shouldUseLaunchSchemeArgsEnv = "YES"
70− savedToolIdentifier = ""
71− useCustomWorkingDirectory = "NO"
72− debugDocumentVersioning = "YES">
73− <BuildableProductRunnable
74− runnableDebuggingMode = "0">
75− <BuildableReference
76− BuildableIdentifier = "primary"
77− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
78− BuildableName = "test_Freddy"
79− BlueprintName = "test_Freddy"
80− ReferencedContainer = "container:test_Freddy.xcodeproj">
81− </BuildableReference>
82− </BuildableProductRunnable>
83− </ProfileAction>
84− <AnalyzeAction
85− buildConfiguration = "Debug">
86− </AnalyzeAction>
87− <ArchiveAction
88− buildConfiguration = "Release"
89− revealArchiveInOrganizer = "YES">
90− </ArchiveAction>
91−</Scheme>
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22
@@ -1,22 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3−<plist version="1.0">
4−<dict>
5− <key>SchemeUserState</key>
6− <dict>
7− <key>test_Freddy.xcscheme</key>
8− <dict>
9− <key>orderHint</key>
10− <integer>0</integer>
11− </dict>
12− </dict>
13− <key>SuppressBuildableAutocreation</key>
14− <dict>
15− <key>03D84AB61D5B0A1000776402</key>
16− <dict>
17− <key>primary</key>
18− <true/>
19− </dict>
20− </dict>
21−</dict>
22−</plist>
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSON.swiftdeleted−98
@@ -1,98 +0,0 @@
1−//
2−// JSON.swift
3−// Freddy
4−//
5−// Created by Matthew D. Mathias on 3/17/15.
6−// Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
7−//
8−
9−/// An enum to describe the structure of JSON.
10−public enum JSON {
11− /// A case for denoting an array with an associated value of `[JSON]`
12− case array([JSON])
13− /// A case for denoting a dictionary with an associated value of `[Swift.String: JSON]`
14− case dictionary([String: JSON])
15− /// A case for denoting a double with an associated value of `Swift.Double`.
16− case double(Double)
17− /// A case for denoting an integer with an associated value of `Swift.Int`.
18− case int(Int)
19− /// A case for denoting a string with an associated value of `Swift.String`.
20− case string(String)
21− /// A case for denoting a boolean with an associated value of `Swift.Bool`.
22− case bool(Bool)
23− /// A case for denoting null.
24− case null
25−}
26−
27−// MARK: - Errors
28−
29−extension JSON {
30−
31− /// An enum to encapsulate errors that may arise in working with `JSON`.
32− public enum Error: Swift.Error {
33− /// The `index` is out of bounds for a JSON array
34− case indexOutOfBounds(index: Int)
35−
36− /// The `key` was not found in the JSON dictionary
37− case keyNotFound(key: String)
38−
39− /// The JSON is not subscriptable with `type`
40− case unexpectedSubscript(type: JSONPathType.Type)
41−
42− /// Unexpected JSON `value` was found that is not convertible `to` type
43− case valueNotConvertible(value: JSON, to: Any.Type)
44−
45− /// The JSON is not serializable to a `String`.
46− case stringSerializationError
47− }
48−
49−}
50−
51−// MARK: - Test Equality
52−
53−/// Return `true` if `lhs` is equal to `rhs`.
54−public func ==(lhs: JSON, rhs: JSON) -> Bool {
55− switch (lhs, rhs) {
56− case (.array(let arrL), .array(let arrR)):
57− return arrL == arrR
58− case (.dictionary(let dictL), .dictionary(let dictR)):
59− return dictL == dictR
60− case (.string(let strL), .string(let strR)):
61− return strL == strR
62− case (.double(let dubL), .double(let dubR)):
63− return dubL == dubR
64− case (.double(let dubL), .int(let intR)):
65− return dubL == Double(intR)
66− case (.int(let intL), .int(let intR)):
67− return intL == intR
68− case (.int(let intL), .double(let dubR)):
69− return Double(intL) == dubR
70− case (.bool(let bL), .bool(let bR)):
71− return bL == bR
72− case (.null, .null):
73− return true
74− default:
75− return false
76− }
77−}
78−
79−extension JSON: Equatable {}
80−
81−// MARK: - Printing
82−
83−extension JSON: CustomStringConvertible {
84−
85− /// A textual representation of `self`.
86− public var description: Swift.String {
87− switch self {
88− case .array(let arr): return String(describing: arr)
89− case .dictionary(let dict): return String(describing: dict)
90− case .string(let string): return string
91− case .double(let double): return String(describing: double)
92− case .int(let int): return String(describing: int)
93− case .bool(let bool): return String(describing: bool)
94− case .null: return "null"
95− }
96− }
97−
98−}
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONDecodable.swiftdeleted−186
@@ -1,186 +0,0 @@
1−//
2−// JSONDecodable.swift
3−// Freddy
4−//
5−// Created by Matthew D. Mathias on 3/24/15.
6−// Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
7−//
8−
9−/// A protocol to provide functionality for creating a model object with a `JSON`
10−/// value.
11−public protocol JSONDecodable {
12−
13− /// Creates an instance of the model with a `JSON` instance.
14− /// - parameter json: An instance of a `JSON` value from which to
15− /// construct an instance of the implementing type.
16− /// - throws: Any `JSON.Error` for errors derived from inspecting the
17− /// `JSON` value, or any other error involved in decoding.
18− init(json: JSON) throws
19−
20−}
21−
22−extension Double: JSONDecodable {
23−
24− /// An initializer to create an instance of `Double` from a `JSON` value.
25− /// - parameter json: An instance of `JSON`.
26− /// - throws: The initializer will throw an instance of `JSON.Error` if
27− /// an instance of `Double` cannot be created from the `JSON` value that was
28− /// passed to this initializer.
29− public init(json: JSON) throws {
30− if case let .double(double) = json {
31− self = double
32− } else if case let .int(int) = json {
33− self = Double(int)
34− } else if case let .string(string) = json, let s = Double(string) {
35− self = s
36− } else {
37− throw JSON.Error.valueNotConvertible(value: json, to: Double.self)
38− }
39− }
40−
41−}
42−
43−extension Int: JSONDecodable {
44−
45− /// An initializer to create an instance of `Int` from a `JSON` value.
46− /// - parameter json: An instance of `JSON`.
47− /// - throws: The initializer will throw an instance of `JSON.Error` if
48− /// an instance of `Int` cannot be created from the `JSON` value that was
49− /// passed to this initializer.
50− public init(json: JSON) throws {
51−
52− if case let .double(double) = json, double <= Double(Int.max) {
53− self = Int(double)
54− } else if case let .int(int) = json {
55− self = int
56− } else if case let .string(string) = json, let int = Int(string) {
57− self = int
58− } else if case let .string(string) = json,
59− let double = Double(string),
60− let decimalSeparator = string.characters.index(of: "."),
61− let int = Int(String(string.characters.prefix(upTo: decimalSeparator))),
62− double == Double(int) {
63− self = int
64− } else {
65− throw JSON.Error.valueNotConvertible(value: json, to: Int.self)
66− }
67− }
68−
69−}
70−
71−extension String: JSONDecodable {
72−
73− /// An initializer to create an instance of `String` from a `JSON` value.
74− /// - parameter json: An instance of `JSON`.
75− /// - throws: The initializer will throw an instance of `JSON.Error` if
76− /// an instance of `String` cannot be created from the `JSON` value that was
77− /// passed to this initializer.
78− public init(json: JSON) throws {
79− switch json {
80− case let .string(string):
81− self = string
82− case let .int(int):
83− self = String(int)
84− case let .bool(bool):
85− self = String(bool)
86− case let .double(double):
87− self = String(double)
88− default:
89− throw JSON.Error.valueNotConvertible(value: json, to: String.self)
90− }
91− }
92−
93−}
94−
95−extension Bool: JSONDecodable {
96−
97− /// An initializer to create an instance of `Bool` from a `JSON` value.
98− /// - parameter json: An instance of `JSON`.
99− /// - throws: The initializer will throw an instance of `JSON.Error` if
100− /// an instance of `Bool` cannot be created from the `JSON` value that was
101− /// passed to this initializer.
102− public init(json: JSON) throws {
103− guard case let .bool(bool) = json else {
104− throw JSON.Error.valueNotConvertible(value: json, to: Bool.self)
105− }
106− self = bool
107− }
108−
109−}
110−
111−extension RawRepresentable where RawValue: JSONDecodable {
112−
113− /// An initializer to create an instance of `RawRepresentable` from a `JSON` value.
114− /// - parameter json: An instance of `JSON`.
115− /// - throws: The initializer will throw an instance of `JSON.Error` if
116− /// an instance of `RawRepresentable` cannot be created from the `JSON` value that was
117− /// passed to this initializer.
118− public init(json: JSON) throws {
119− let raw = try json.decode(type: RawValue.self)
120− guard let value = Self(rawValue: raw) else {
121− throw JSON.Error.valueNotConvertible(value: json, to: Self.self)
122− }
123− self = value
124− }
125−}
126−
127−internal extension JSON {
128−
129− /// Retrieves a `[JSON]` from the JSON.
130− /// - parameter: A `JSON` to be used to create the returned `Array`.
131− /// - returns: An `Array` of `JSON` elements
132− /// - throws: Any of the `JSON.Error` cases thrown by `decode(type:)`.
133− /// - seealso: `JSON.decode(_:type:)`
134− static func getArray(from json: JSON) throws -> [JSON] {
135− // Ideally should be expressed as a conditional protocol implementation on Swift.Array.
136− guard case let .array(array) = json else {
137− throw Error.valueNotConvertible(value: json, to: Swift.Array<JSON>)
138− }
139− return array
140− }
141−
142− /// Retrieves a `[String: JSON]` from the JSON.
143− /// - parameter: A `JSON` to be used to create the returned `Dictionary`.
144− /// - returns: An `Dictionary` of `String` mapping to `JSON` elements
145− /// - throws: Any of the `JSON.Error` cases thrown by `decode(type:)`.
146− /// - seealso: `JSON.decode(_:type:)`
147− static func getDictionary(from json: JSON) throws -> [String: JSON] {
148− // Ideally should be expressed as a conditional protocol implementation on Swift.Dictionary.
149− guard case let .dictionary(dictionary) = json else {
150− throw Error.valueNotConvertible(value: json, to: Swift.Dictionary<String, JSON>)
151− }
152− return dictionary
153− }
154−
155− /// Attempts to decode many values from a descendant JSON array at a path
156− /// into JSON.
157− /// - parameter json: A `JSON` to be used to create the returned `Array` of some type conforming to `JSONDecodable`.
158− /// - returns: An `Array` of `Decoded` elements.
159− /// - throws: Any of the `JSON.Error` cases thrown by `decode(type:)`, as
160− /// well as any error that arises from decoding the contained values.
161− /// - seealso: `JSON.decode(_:type:)`
162− static func decodedArray<Decoded: JSONDecodable>(from json: JSON) throws -> [Decoded] {
163− // Ideally should be expressed as a conditional protocol implementation on Swift.Dictionary.
164− // This implementation also doesn't do the `type = Type.self` trick.
165− return try getArray(from: json).map(Decoded.init)
166− }
167−
168− /// Attempts to decode many values from a descendant JSON object at a path
169− /// into JSON.
170− /// - parameter json: A `JSON` to be used to create the returned `Dictionary` of some type conforming to `JSONDecodable`.
171− /// - returns: A `Dictionary` of string keys and `Decoded` values.
172− /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)` or
173− /// any error that arises from decoding the contained values.
174− /// - seealso: `JSON.decode(_:type:)`
175− static func decodedDictionary<Decoded: JSONDecodable>(from json: JSON) throws -> [Swift.String: Decoded] {
176− guard case let .dictionary(dictionary) = json else {
177− throw Error.valueNotConvertible(value: json, to: Swift.Dictionary<String, Decoded>)
178− }
179− var decodedDictionary = Swift.Dictionary<String, Decoded>(minimumCapacity: dictionary.count)
180− for (key, value) in dictionary {
181− decodedDictionary[key] = try Decoded(json: value)
182− }
183− return decodedDictionary
184− }
185−
186−}
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONEncodable.swiftdeleted−83
@@ -1,83 +0,0 @@
1−//
2−// JSONEncodable.swift
3−// Freddy
4−//
5−// Created by Matthew Mathias on 1/4/16.
6−// Copyright © 2016 Big Nerd Ranch. All rights reserved.
7−//
8−
9−import Foundation
10−
11−/// A protocol to facilitate encoding and decoding of `JSON`.
12−public protocol JSONEncodable {
13− /// Converts an instance of a conforming type to `JSON`.
14− /// - returns: An instance of `JSON`.
15− /// - Note: If conforming to `JSONEncodable` with a custom type of your own, you should return an instance of
16− /// `JSON.dictionary`.
17− func toJSON() -> JSON
18−}
19−
20−extension Array where Element: JSONEncodable {
21− /// Converts an instance of `Array` whose elements conform to `JSONEncodable` to `JSON`.
22− /// - returns: An instance of `JSON` where the enum case is `.array`.
23− public func toJSON() -> JSON {
24− let arrayOfJSON = self.map { $0.toJSON() }
25− return .array(arrayOfJSON)
26− }
27−}
28−
29−extension Dictionary where Value: JSONEncodable {
30− /// Converts an instance of `Dictionary` whose values conform to `JSONEncodable` to `JSON`. The keys in the resulting
31− /// `JSON.dictionary` will be of type `String`.
32− /// - returns: An instance of `JSON` where the enum case is `.dictionary`.
33− public func toJSON() -> JSON {
34− var jsonDictionary = [String: JSON]()
35−
36− for (k, v) in self {
37− let key = String(describing: k)
38− jsonDictionary[key] = v.toJSON()
39− }
40−
41− return .dictionary(jsonDictionary)
42− }
43−}
44−
45−extension Int: JSONEncodable {
46− /// Converts an instance of a conforming type to `JSON`.
47− /// - returns: An instance of `JSON` where the enum case is `.int`.
48− public func toJSON() -> JSON {
49− return .int(self)
50− }
51−}
52−
53−extension Double: JSONEncodable {
54− /// Converts an instance of a conforming type to `JSON`.
55− /// - returns: An instance of `JSON` where the enum case is `.double`.
56− public func toJSON() -> JSON {
57− return .double(self)
58− }
59−}
60−
61−extension String: JSONEncodable {
62− /// Converts an instance of a conforming type to `JSON`.
63− /// - returns: An instance of `JSON` where the enum case is `.string`.
64− public func toJSON() -> JSON {
65− return .string(self)
66− }
67−}
68−
69−extension Bool: JSONEncodable {
70− /// Converts an instance of a conforming type to `JSON`.
71− /// - returns: An instance of `JSON` where the enum case is `.bool`.
72− public func toJSON() -> JSON {
73− return .bool(self)
74− }
75−}
76−
77−extension RawRepresentable where RawValue: JSONEncodable {
78− /// Converts an instance of a conforming type to `JSON`.
79− /// - returns: An instance of `JSON` where the enum case is whatever the underlying `RawValue` converts to.
80− public func toJSON() -> JSON {
81− return rawValue.toJSON()
82− }
83−}
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONEncodingDetector.swiftdeleted−110
@@ -1,110 +0,0 @@
1−//
2−// JSONEncodingDetector.swift
3−// Freddy
4−//
5−// Created by Robert Edwards on 1/27/16.
6−// Copyright © 2016 Big Nerd Ranch. All rights reserved.
7−//
8−
9−/// Struct for attempting to detect the Unicode encoding used with the data supplied to the JSONParser
10−public struct JSONEncodingDetector {
11−
12− //// The Unicode encodings looked for during detection
13− public enum Encoding {
14− //// UTF-8
15− case utf8
16− //// UTF-16 Little Endian
17− case utf16LE
18− //// UTF-16 Big Endian
19− case utf16BE
20− //// UTF-32 Little Endian
21− case utf32LE
22− //// UTF-32 Big Endian
23− case utf32BE
24− }
25−
26− //// The Unicode encodings supported by JSONParser.swift
27− public static let supportedEncodings: [Encoding] = [.utf8]
28−
29− typealias ByteStreamPrefixInformation = (encoding: Encoding, byteOrderMarkLength: Int)
30−
31− //// Attempts to detect the Unicode encoding used for a given set of data.
32− ////
33− //// This function initially looks for a Byte Order Mark in the following form:
34− ////
35− //// Bytes | Encoding Form
36− //// --------------|----------------
37− //// 00 00 FE FF | UTF-32, big-endian
38− //// FF FE 00 00 | UTF-32, little-endian
39− //// FE FF | UTF-16, big-endian
40− //// FF FE | UTF-16, little-endian
41− //// EF BB BF | UTF-8
42− ////
43− //// If a BOM is not found then we detect using the following approach described in
44− //// the JSON RFC http://www.ietf.org/rfc/rfc4627.txt:
45− ////
46− //// Since the first two characters of a JSON text will always be ASCII
47− //// characters [RFC0020], it is possible to determine whether an octet
48− //// stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
49− //// at the pattern of nulls in the first four octets.
50− ////
51− //// 00 00 00 xx UTF-32BE
52− //// 00 xx 00 xx UTF-16BE
53− //// xx 00 00 00 UTF-32LE
54− //// xx 00 xx 00 UTF-16LE
55− //// xx xx xx xx UTF-8
56− ////
57− //// - parameter header: The front Slice of data being read and evaluated.
58− //// - returns: A tuple containing the detected Unicode encoding and the lenght of the byte order mark.
59− static func detectEncoding(_ header: RandomAccessSlice<UnsafeBufferPointer<UInt8>>) -> ByteStreamPrefixInformation {
60−
61− guard let prefix = prefixFromHeader(header) else {
62− return (.utf8, 0)
63− }
64−
65− if let prefixInfo = JSONEncodingDetector.encodingFromBOM(prefix) {
66− return prefixInfo
67− } else {
68− switch prefix {
69− case(0, 0, 0?, _):
70− return (.utf32BE, 0)
71− case(_, 0, 0?, 0?):
72− return (.utf32LE, 0)
73− case (0, _, 0?, _), (0, _, _, _):
74− return (.utf16BE, 0)
75− case (_, 0, _, 0?), (_, 0, _, _):
76− return (.utf16LE, 0)
77− default:
78− return (.utf8, 0)
79− }
80− }
81− }
82−
83− private typealias EncodingBytePrefix = (UInt8, UInt8, UInt8?, UInt8?)
84−
85− private static func prefixFromHeader(_ header: RandomAccessSlice<UnsafeBufferPointer<UInt8>>) -> EncodingBytePrefix? {
86− if header.count >= 4 {
87− return(header[0], header[1], header[2], header[3])
88− } else if header.count >= 2 {
89− return (header[0], header[1], nil, nil)
90− }
91− return nil
92− }
93−
94− private static func encodingFromBOM(_ prefix: EncodingBytePrefix) -> ByteStreamPrefixInformation? {
95− switch prefix {
96− case(0xFE, 0xFF, _, _):
97− return (.utf16BE, 2)
98− case(0x00, 0x00, 0xFE?, 0xFF?):
99− return (.utf32BE, 4)
100− case(0xEF, 0xBB, 0xBF?, _):
101− return (.utf8, 3)
102− case(0xFF, 0xFE, 0?, 0?):
103− return (.utf32LE, 4)
104− case(0xFF, 0xFE, _, _):
105− return (.utf16LE, 2)
106− default:
107− return nil
108− }
109− }
110−}
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONLiteralConvertible.swiftdeleted−134
@@ -1,134 +0,0 @@
1−//
2−// JSONLiteralConvertible.swift
3−// Freddy
4−//
5−// Created by Zachary Waldowski on 5/11/15.
6−// Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
7−//
8−
9−// MARK: - ArrayLiteralConvertible
10−
11−extension JSON: ExpressibleByArrayLiteral {
12−
13− /// Create an instance by copying each element of the `collection` into a
14− /// new `Array`.
15− public init<Collection: Swift.Collection>(_ collection: Collection) where Collection.Iterator.Element == JSON {
16− self = .array(Swift.Array(collection))
17− }
18−
19− /// Create an instance initialized with `elements`.
20− public init(arrayLiteral elements: JSON...) {
21− self.init(elements)
22− }
23−
24−}
25−
26−// MARK: - DictionaryLiteralConvertible
27−
28−extension JSON: ExpressibleByDictionaryLiteral {
29−
30− /// Create an instance by copying each key/value pair of the `pairs` into
31− /// a new `Dictionary`.
32− public init<Dictionary: Sequence>(_ pairs: Dictionary) where Dictionary.Iterator.Element == (Swift.String, JSON) {
33− var dictionary = Swift.Dictionary<Swift.String, JSON>(minimumCapacity: pairs.underestimatedCount)
34− for (key, value) in pairs {
35− dictionary[key] = value
36− }
37− self.init(dictionary)
38− }
39−
40− /// Create an instance initialized with `pairs`.
41− public init(dictionaryLiteral pairs: (Swift.String, JSON)...) {
42− self.init(pairs)
43− }
44−
45− /// Create an instance initialized to `dictionary`.
46− public init(_ dictionary: Swift.Dictionary<Swift.String, JSON>) {
47− self = .dictionary(dictionary)
48− }
49−}
50−
51−// MARK: - FloatLiteralConvertible
52−
53−extension JSON: ExpressibleByFloatLiteral {
54−
55− /// Create an instance initialized to `Double` `value`.
56− public init(_ value: Swift.Double) {
57− self = .double(value)
58− }
59−
60− /// Create a literal instance initialized to `value`.
61− public init(floatLiteral value: Swift.Double) {
62− self.init(value)
63− }
64−
65−}
66−
67−// MARK: - IntegerLiteralConvertible
68−
69−extension JSON: ExpressibleByIntegerLiteral {
70−
71− /// Create an instance initialized to `Int` by `value`.
72− public init(_ value: Swift.Int) {
73− self = .int(value)
74− }
75−
76− /// Create a literal instance initialized to `value`.
77− public init(integerLiteral value: Swift.Int) {
78− self.init(value)
79− }
80−
81−}
82−
83−// MARK: - StringLiteralConvertible
84−
85−extension JSON: ExpressibleByStringLiteral {
86−
87− /// Create an instance initialized to `String` by `text`.
88− public init(_ text: Swift.String) {
89− self = .string(text)
90− }
91−
92− /// Create a literal instance initialized to `value`.
93− public init(stringLiteral value: StringLiteralType) {
94− self.init(value)
95− }
96−
97− /// Create a literal instance initialized to `value`.
98− public init(extendedGraphemeClusterLiteral value: StringLiteralType) {
99− self.init(value)
100− }
101−
102− /// Create a literal instance initialized to `value`.
103− public init(unicodeScalarLiteral value: StringLiteralType) {
104− self.init(value)
105− }
106−
107−}
108−
109−// MARK: - BooleanLiteralConvertible
110−
111−extension JSON: ExpressibleByBooleanLiteral {
112−
113− /// Create an instance initialized to `Bool` by `value`.
114− public init(_ value: Swift.Bool) {
115− self = .bool(value)
116− }
117−
118− /// Create a literal instance initialized to `value`.
119− public init(booleanLiteral value: Swift.Bool) {
120− self.init(value)
121− }
122−
123−}
124−
125−// MARK: - NilLiteralConvertible
126−
127−extension JSON: ExpressibleByNilLiteral {
128−
129− /// Create an instance initialized with `nil`.
130− public init(nilLiteral: ()) {
131− self = .null
132− }
133−
134−}
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONParser.swiftdeleted−918
@@ -1,918 +0,0 @@
1−//
2−// JSONParser.swift
3−// Freddy
4−//
5−// Created by John Gallagher on 4/18/15.
6−// Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
7−//
8−
9−import Foundation
10−
11−private struct Literal {
12− static let BACKSLASH = UInt8(ascii: "\\")
13− static let BACKSPACE = UInt8(ascii: "\u{0008}")
14− static let COLON = UInt8(ascii: ":")
15− static let COMMA = UInt8(ascii: ",")
16− static let DOUBLE_QUOTE = UInt8(ascii: "\"")
17− static let FORMFEED = UInt8(ascii: "\u{000c}")
18− static let LEFT_BRACE = UInt8(ascii: "{")
19− static let LEFT_BRACKET = UInt8(ascii: "[")
20− static let MINUS = UInt8(ascii: "-")
21− static let NEWLINE = UInt8(ascii: "\n")
22− static let PERIOD = UInt8(ascii: ".")
23− static let PLUS = UInt8(ascii: "+")
24− static let RETURN = UInt8(ascii: "\r")
25− static let RIGHT_BRACE = UInt8(ascii: "}")
26− static let RIGHT_BRACKET = UInt8(ascii: "]")
27− static let SLASH = UInt8(ascii: "/")
28− static let SPACE = UInt8(ascii: " ")
29− static let TAB = UInt8(ascii: "\t")
30−
31− static let a = UInt8(ascii: "a")
32− static let b = UInt8(ascii: "b")
33− static let c = UInt8(ascii: "c")
34− static let d = UInt8(ascii: "d")
35− static let e = UInt8(ascii: "e")
36− static let f = UInt8(ascii: "f")
37− static let l = UInt8(ascii: "l")
38− static let n = UInt8(ascii: "n")
39− static let r = UInt8(ascii: "r")
40− static let s = UInt8(ascii: "s")
41− static let t = UInt8(ascii: "t")
42− static let u = UInt8(ascii: "u")
43−
44− static let A = UInt8(ascii: "A")
45− static let B = UInt8(ascii: "B")
46− static let C = UInt8(ascii: "C")
47− static let D = UInt8(ascii: "D")
48− static let E = UInt8(ascii: "E")
49− static let F = UInt8(ascii: "F")
50−
51− static let zero = UInt8(ascii: "0")
52− static let one = UInt8(ascii: "1")
53− static let two = UInt8(ascii: "2")
54− static let three = UInt8(ascii: "3")
55− static let four = UInt8(ascii: "4")
56− static let five = UInt8(ascii: "5")
57− static let six = UInt8(ascii: "6")
58− static let seven = UInt8(ascii: "7")
59− static let eight = UInt8(ascii: "8")
60− static let nine = UInt8(ascii: "9")
61−}
62−
63−private let ParserMaximumDepth = 512
64−
65−
66−/// A pure Swift JSON parser. This parser is much faster than the
67−/// `NSJSONSerialization`-based parser (due to the overhead of having to
68−/// dynamically cast the Objective-C objects to determine their type); however,
69−/// it is much newer and has restrictions that the `NSJSONSerialization` parser
70−/// does not. Two restrictions in particular are that it requires UTF-8 data as
71−/// input and it does not allow trailing commas in arrays or dictionaries.
72−public struct JSONParser {
73−
74− fileprivate enum Sign: Int {
75− case positive = 1
76− case negative = -1
77− }
78−
79− private let input: UnsafeBufferPointer<UInt8>
80− private var loc = 0
81− private var depth = 0
82−
83− fileprivate init(input: UnsafeBufferPointer<UInt8>) {
84− self.input = input
85− }
86−
87− /// Decode the root element of the `JSON` stream. This may be any fragment
88− /// or a structural element, per RFC 7159.
89− ///
90− /// The beginning bytes are used to determine the stream's encoding.
91− /// `JSONParser` currently only supports UTF-8 encoding, with or without
92− /// a byte-order mark.
93− ///
94− /// - throws: `JSONParser.Error` for any decoding failures, including a
95− /// source location if needed.
96− public mutating func parse() throws -> JSON {
97− try guardAgainstUnsupportedEncodings()
98− let value = try parseValue()
99− skipWhitespace()
100− guard loc == input.count else {
101− throw Error.endOfStreamGarbage(offset: loc)
102− }
103− return value
104− }
105−
106− private mutating func parseValue() throws -> JSON {
107− guard depth <= ParserMaximumDepth else {
108− throw Error.exceededNestingLimit(offset: loc)
109− }
110−
111− guard input.count > 0 else {
112− throw Error.endOfStreamUnexpected
113− }
114−
115− advancing: while loc < input.count {
116− do {
117− switch input[loc] {
118− case Literal.LEFT_BRACKET:
119− depth += 1
120− defer { depth -= 1 }
121− return try decodeArray()
122−
123− case Literal.LEFT_BRACE:
124− depth += 1
125− defer { depth -= 1 }
126− return try decodeObject()
127−
128− case Literal.DOUBLE_QUOTE:
129− return try decodeString()
130−
131− case Literal.f:
132− return try decodeFalse()
133−
134− case Literal.n:
135− return try decodeNull()
136−
137− case Literal.t:
138− return try decodeTrue()
139−
140− case Literal.MINUS:
141− return try decodeIntegralValue(NumberParser(loc: loc, input: input, state: .leadingMinus))
142−
143− case Literal.zero:
144− return try decodeIntegralValue(NumberParser(loc: loc, input: input, state: .leadingZero))
145−
146− case Literal.one...Literal.nine:
147− return try decodeIntegralValue(NumberParser(loc: loc, input: input, state: .preDecimalDigits))
148−
149− case Literal.SPACE, Literal.TAB, Literal.RETURN, Literal.NEWLINE:
150− loc = (loc + 1)
151−
152− default:
153− break advancing
154− }
155− } catch let InternalError.numberOverflow(offset: start) {
156− return try decodeNumberAsString(from: start)
157− }
158− }
159− if loc < input.count {
160− throw Error.valueInvalid(offset: loc, character: UnicodeScalar(input[loc]))
161− } else {
162− throw Error.endOfStreamUnexpected
163− }
164− }
165−
166− private mutating func skipWhitespace() {
167− while loc < input.count {
168− switch input[loc] {
169− case Literal.SPACE, Literal.TAB, Literal.RETURN, Literal.NEWLINE:
170− loc = (loc + 1)
171− default:
172− return
173− }
174− }
175− }
176−
177− private mutating func guardAgainstUnsupportedEncodings() throws {
178− let header = input.prefix(4)
179− let encodingPrefixInformation = JSONEncodingDetector.detectEncoding(header)
180− guard JSONEncodingDetector.supportedEncodings.contains(encodingPrefixInformation.encoding) else {
181− throw Error.invalidUnicodeStreamEncoding(detectedEncoding: encodingPrefixInformation.encoding)
182− }
183− loc = loc.advanced(by: encodingPrefixInformation.byteOrderMarkLength)
184− }
185−
186− private mutating func decodeNull() throws -> JSON {
187− guard input.index(loc, offsetBy: 3, limitedBy: input.count) != input.count else {
188− throw Error.literalNilMisspelled(offset: loc)
189− }
190−
191− if input[loc+1] != Literal.u
192− || input[loc+2] != Literal.l
193− || input[loc+3] != Literal.l {
194− throw Error.literalNilMisspelled(offset: loc)
195− }
196−
197− loc += 4
198− return .null
199− }
200−
201− private mutating func decodeTrue() throws -> JSON {
202− guard input.index(loc, offsetBy: 3, limitedBy: input.count) != input.count else {
203− throw Error.literalNilMisspelled(offset: loc)
204− }
205−
206− if input[loc+1] != Literal.r
207− || input[loc+2] != Literal.u
208− || input[loc+3] != Literal.e {
209− throw Error.literalTrueMisspelled(offset: loc)
210− }
211−
212− loc += 4
213− return .bool(true)
214− }
215−
216− private mutating func decodeFalse() throws -> JSON {
217− guard input.index(loc, offsetBy: 4, limitedBy: input.count) != input.count else {
218− throw Error.literalNilMisspelled(offset: loc)
219− }
220−
221− if input[loc+1] != Literal.a
222− || input[loc+2] != Literal.l
223− || input[loc+3] != Literal.s
224− || input[loc+4] != Literal.e {
225− throw Error.literalFalseMisspelled(offset: loc)
226− }
227−
228− loc += 5
229− return .bool(false)
230− }
231−
232− private var stringDecodingBuffer = [UInt8]()
233− private mutating func decodeString() throws -> JSON {
234− loc = (loc + 1)
235− stringDecodingBuffer.removeAll(keepingCapacity: true)
236− while loc < input.count {
237− switch input[loc] {
238− case Literal.BACKSLASH:
239− loc = (loc + 1)
240− switch input[loc] {
241− case Literal.DOUBLE_QUOTE: stringDecodingBuffer.append(Literal.DOUBLE_QUOTE)
242− case Literal.BACKSLASH: stringDecodingBuffer.append(Literal.BACKSLASH)
243− case Literal.SLASH: stringDecodingBuffer.append(Literal.SLASH)
244− case Literal.b: stringDecodingBuffer.append(Literal.BACKSPACE)
245− case Literal.f: stringDecodingBuffer.append(Literal.FORMFEED)
246− case Literal.r: stringDecodingBuffer.append(Literal.RETURN)
247− case Literal.t: stringDecodingBuffer.append(Literal.TAB)
248− case Literal.n: stringDecodingBuffer.append(Literal.NEWLINE)
249− case Literal.u:
250− loc = (loc + 1)
251− try readUnicodeEscape(start: loc - 2)
252−
253− // readUnicodeEscape() advances loc on its own, so we'll `continue` now
254− // to skip the typical "advance past this character" for all the other escapes
255− continue
256−
257− default:
258− throw Error.controlCharacterUnrecognized(offset: loc)
259− }
260− loc = (loc + 1)
261−
262− case Literal.DOUBLE_QUOTE:
263− loc = (loc + 1)
264− stringDecodingBuffer.append(0)
265−
266− let string = stringDecodingBuffer.withUnsafeBufferPointer {
267− String(cString: UnsafePointer($0.baseAddress!))
268− }
269−
270− return .string(string)
271−
272− case let other:
273− stringDecodingBuffer.append(other)
274− loc = (loc + 1)
275− }
276− }
277−
278− throw Error.endOfStreamUnexpected
279− }
280−
281− private mutating func readCodeUnit() -> UInt16? {
282− guard loc + 4 <= input.count else {
283− return nil
284− }
285− var codeUnit: UInt16 = 0
286− for c in input[loc..<loc+4] {
287− let nibble: UInt16
288−
289− switch c {
290− case Literal.zero...Literal.nine:
291− nibble = UInt16(c - Literal.zero)
292−
293− case Literal.a...Literal.f:
294− nibble = 10 + UInt16(c - Literal.a)
295−
296− case Literal.A...Literal.F:
297− nibble = 10 + UInt16(c - Literal.A)
298−
299− default:
300− return nil
301− }
302− codeUnit = (codeUnit << 4) | nibble
303− }
304− loc += 4
305− return codeUnit
306− }
307−
308− private mutating func readUnicodeEscape(start: Int) throws {
309− guard let codeUnit = readCodeUnit() else {
310− throw Error.unicodeEscapeInvalid(offset: start)
311− }
312−
313− let codeUnits: [UInt16]
314−
315− if UTF16.isLeadSurrogate(codeUnit) {
316− // First half of a UTF16 surrogate pair - we must parse another code unit and combine them
317−
318− // First confirm and skip over that we have another "\u"
319− guard loc + 6 <= input.count && input[loc] == Literal.BACKSLASH && input[loc+1] == Literal.u else {
320− throw Error.unicodeEscapeInvalid(offset: start)
321− }
322− loc += 2
323−
324− // Ensure the second code unit is valid for the surrogate pair
325− guard let secondCodeUnit = readCodeUnit(), UTF16.isTrailSurrogate(secondCodeUnit) else {
326− throw Error.unicodeEscapeInvalid(offset: start)
327− }
328−
329− codeUnits = [codeUnit, secondCodeUnit]
330− } else {
331− codeUnits = [codeUnit]
332− }
333−
334− let transcodeHadError = transcode(codeUnits.makeIterator(), from: UTF16.self, to: UTF8.self, stoppingOnError: true) { (outputEncodingCodeUnit) in
335− self.stringDecodingBuffer.append(outputEncodingCodeUnit)
336− }
337−
338− if transcodeHadError {
339− throw Error.unicodeEscapeInvalid(offset: start)
340− }
341− }
342−
343− private mutating func decodeArray() throws -> JSON {
344− let start = loc
345− loc = (loc + 1)
346− var items = [JSON]()
347−
348− while loc < input.count {
349− skipWhitespace()
350−
351− if loc < input.count && input[loc] == Literal.RIGHT_BRACKET {
352− loc = (loc + 1)
353− return .array(items)
354− }
355−
356− if !items.isEmpty {
357− guard loc < input.count && input[loc] == Literal.COMMA else {
358− throw Error.collectionMissingSeparator(offset: start)
359− }
360− loc = (loc + 1)
361− }
362−
363− items.append(try parseValue())
364− }
365−
366− throw Error.endOfStreamUnexpected
367− }
368−
369− // Decoding objects can be recursive, so we have to keep more than one
370− // buffer around for building up key/value pairs (to reduce allocations
371− // when parsing large JSON documents).
372− //
373− // Rough estimate of the difference between this and using a fresh
374− // [(String,JSON)] for the `pairs` variable in decodeObject() below is
375− // about 12% on an iPhone 5.
376− private struct DecodeObjectBuffers {
377− var buffers = [[(String,JSON)]]()
378−
379− mutating func getBuffer() -> [(String,JSON)] {
380− if !buffers.isEmpty {
381− var buffer = buffers.removeLast()
382− buffer.removeAll(keepingCapacity: true)
383− return buffer
384− }
385− return [(String,JSON)]()
386− }
387−
388− mutating func putBuffer(_ buffer: [(String,JSON)]) {
389− buffers.append(buffer)
390− }
391− }
392−
393− private var decodeObjectBuffers = DecodeObjectBuffers()
394−
395− private mutating func decodeObject() throws -> JSON {
396− let start = loc
397− loc = (loc + 1)
398− var pairs = decodeObjectBuffers.getBuffer()
399−
400− while loc < input.count {
401− skipWhitespace()
402−
403− if loc < input.count && input[loc] == Literal.RIGHT_BRACE {
404− loc = (loc + 1)
405− var obj = [String:JSON](minimumCapacity: pairs.count)
406− for (k, v) in pairs {
407− obj[k] = v
408− }
409− decodeObjectBuffers.putBuffer(pairs)
410− return .dictionary(obj)
411− }
412−
413− if !pairs.isEmpty {
414− guard loc < input.count && input[loc] == Literal.COMMA else {
415− throw Error.collectionMissingSeparator(offset: start)
416− }
417− loc = (loc + 1)
418−
419− skipWhitespace()
420− }
421−
422− guard loc < input.count && input[loc] == Literal.DOUBLE_QUOTE else {
423− throw Error.dictionaryMissingKey(offset: start)
424− }
425−
426− let key = try decodeString().getString()
427− skipWhitespace()
428−
429− guard loc < input.count && input[loc] == Literal.COLON else {
430− throw Error.collectionMissingSeparator(offset: start)
431− }
432− loc = (loc + 1)
433−
434− pairs.append((key, try parseValue()))
435− }
436−
437− throw Error.endOfStreamUnexpected
438− }
439−
440− private mutating func decodeIntegralValue(_ parser: NumberParser) throws -> JSON {
441− var sign = Sign.positive
442− var parser = parser
443− var value = 0
444−
445− // This would be more natural as `while true { ... }` with a meaningful .Done case,
446− // but that causes compile time explosion in Swift 2.2. :-|
447− while parser.state != .done {
448− switch parser.state {
449− case .leadingMinus:
450− sign = .negative
451− try parser.parseNegative()
452−
453− case .leadingZero:
454− parser.parseLeadingZero()
455−
456− case .preDecimalDigits:
457− try parser.parsePreDecimalDigits { c in
458− guard case let (exponent, false) = Int.multiplyWithOverflow(10, value) else {
459− throw InternalError.numberOverflow(offset: parser.start)
460− }
461−
462− guard case let (newValue, false) = Int.addWithOverflow(exponent, Int(c - Literal.zero)) else {
463− throw InternalError.numberOverflow(offset: parser.start)
464− }
465−
466− value = newValue
467− }
468−
469− case .decimal, .exponent:
470− return try detectingFloatingPointErrors(start: parser.start) {
471− try decodeFloatingPointValue(parser, sign: sign, value: Double(value))
472− }
473−
474− case .postDecimalDigits, .exponentSign, .exponentDigits:
475− assertionFailure("Invalid internal state while parsing number")
476−
477− case .done:
478− fatalError("impossible condition")
479− }
480− }
481−
482− guard case let (signedValue, false) = Int.multiplyWithOverflow(sign.rawValue, value) else {
483− throw InternalError.numberOverflow(offset: parser.start)
484− }
485−
486− loc = parser.loc
487− return .int(signedValue)
488− }
489−
490− private mutating func decodeFloatingPointValue(_ parser: NumberParser, sign: Sign, value: Double) throws -> JSON {
491− var parser = parser
492− var value = value
493− var exponentSign = Sign.positive
494− var exponent = Double(0)
495− var position = 0.1
496−
497− // This would be more natural as `while true { ... }` with a meaningful .Done case,
498− // but that causes compile time explosion in Swift 2.2. :-|
499− while parser.state != .done {
500− switch parser.state {
501− case .leadingMinus, .leadingZero, .preDecimalDigits:
502− assertionFailure("Invalid internal state while parsing number")
503−
504− case .decimal:
505− try parser.parseDecimal()
506−
507− case .postDecimalDigits:
508− parser.parsePostDecimalDigits { c in
509− value += position * Double(c - Literal.zero)
510− position /= 10
511− }
512−
513− case .exponent:
514− exponentSign = try parser.parseExponent()
515−
516− case .exponentSign:
517− try parser.parseExponentSign()
518−
519− case .exponentDigits:
520− parser.parseExponentDigits { c in
521− exponent = exponent * 10 + Double(c - Literal.zero)
522− }
523−
524− case .done:
525− fatalError("impossible condition")
526− }
527− }
528−
529− loc = parser.loc
530− return .double(Double(sign.rawValue) * value * pow(10, Double(exponentSign.rawValue) * exponent))
531− }
532−
533−
534− private mutating func decodeNumberAsString(from position: Int) throws -> JSON {
535− var parser: NumberParser = {
536− let state: NumberParser.State
537− switch input[position] {
538− case Literal.MINUS: state = .leadingMinus
539− case Literal.zero: state = .leadingZero
540− case Literal.one...Literal.nine: state = .preDecimalDigits
541− default:
542− fatalError("Internal error: decodeNumber called on not-a-number")
543− }
544− return NumberParser(loc: position, input: input, state: state)
545− }()
546−
547− stringDecodingBuffer.removeAll(keepingCapacity: true)
548−
549− while true {
550− switch parser.state {
551− case .leadingMinus:
552− try parser.parseNegative()
553− stringDecodingBuffer.append(Literal.MINUS)
554−
555− case .leadingZero:
556− parser.parseLeadingZero()
557− stringDecodingBuffer.append(Literal.zero)
558−
559− case .preDecimalDigits:
560− parser.parsePreDecimalDigits { stringDecodingBuffer.append($0) }
561−
562− case .decimal:
563− try parser.parseDecimal()
564− stringDecodingBuffer.append(Literal.PERIOD)
565−
566− case .postDecimalDigits:
567− parser.parsePostDecimalDigits { stringDecodingBuffer.append($0) }
568−
569− case .exponent:
570− stringDecodingBuffer.append(input[parser.loc])
571− _ = try parser.parseExponent()
572−
573− case .exponentSign:
574− stringDecodingBuffer.append(input[parser.loc])
575− try parser.parseExponentSign()
576−
577− case .exponentDigits:
578− parser.parseExponentDigits { stringDecodingBuffer.append($0) }
579−
580− case .done:
581− stringDecodingBuffer.append(0)
582− let string = stringDecodingBuffer.withUnsafeBufferPointer {
583− String(cString: UnsafePointer($0.baseAddress!))
584− }
585−
586− loc = parser.loc
587− return .string(string)
588− }
589− }
590− }
591−
592− private func detectingFloatingPointErrors<T>(start loc: Int, _ f: () throws -> T) throws -> T {
593− let flags = FE_UNDERFLOW | FE_OVERFLOW
594− feclearexcept(flags)
595− let value = try f()
596− guard fetestexcept(flags) == 0 else {
597− throw InternalError.numberOverflow(offset: loc)
598− }
599− return value
600− }
601−}
602−
603−private struct NumberParser {
604− enum State {
605− case leadingMinus
606− case leadingZero
607− case preDecimalDigits
608− case decimal
609− case postDecimalDigits
610− case exponent
611− case exponentSign
612− case exponentDigits
613− case done
614− }
615−
616− let start: Int
617− var loc = 0
618− var state: State
619− let input: UnsafeBufferPointer<UInt8>
620−
621− init(loc: Int, input: UnsafeBufferPointer<UInt8>, state: State) {
622− assert(loc < input.count, "Invalid input to NumberParser")
623− self.start = loc
624− self.loc = loc
625− self.input = input
626− self.state = state
627− }
628−
629− mutating func parseNegative() throws {
630− assert(state == .leadingMinus, "Unexpected state entering parseNegative")
631−
632− loc = (loc + 1)
633− guard loc < input.count else {
634− throw JSONParser.Error.endOfStreamUnexpected
635− }
636−
637− switch input[loc] {
638− case Literal.zero:
639− state = .leadingZero
640−
641− case Literal.one...Literal.nine:
642− state = .preDecimalDigits
643−
644− default:
645− throw JSONParser.Error.numberSymbolMissingDigits(offset: start)
646− }
647− }
648−
649− mutating func parseLeadingZero() {
650− assert(state == .leadingZero, "Unexpected state entering parseLeadingZero")
651−
652− loc = (loc + 1)
653− guard loc < input.count else {
654− state = .done
655− return
656− }
657−
658− switch input[loc] {
659− case Literal.PERIOD:
660− state = .decimal
661−
662− case Literal.e, Literal.E:
663− state = .exponent
664−
665− default:
666− state = .done
667− }
668− }
669−
670− mutating func parsePreDecimalDigits(f: (UInt8) throws -> Void) rethrows {
671− assert(state == .preDecimalDigits, "Unexpected state entering parsePreDecimalDigits")
672− advancing: while loc < input.count {
673− let c = input[loc]
674− switch c {
675− case Literal.zero...Literal.nine:
676− try f(c)
677− loc = (loc + 1)
678−
679− case Literal.PERIOD:
680− state = .decimal
681− return
682−
683− case Literal.e, Literal.E:
684− state = .exponent
685− return
686−
687− default:
688− break advancing
689− }
690− }
691−
692− state = .done
693− }
694−
695− mutating func parseDecimal() throws {
696− assert(state == .decimal, "Unexpected state entering parseDecimal")
697− loc = (loc + 1)
698− guard loc < input.count else {
699− throw JSONParser.Error.endOfStreamUnexpected
700− }
701−
702− switch input[loc] {
703− case Literal.zero...Literal.nine:
704− state = .postDecimalDigits
705−
706− default:
707− throw JSONParser.Error.numberMissingFractionalDigits(offset: start)
708− }
709− }
710−
711− mutating func parsePostDecimalDigits(f: (UInt8) throws -> Void) rethrows {
712− assert(state == .postDecimalDigits, "Unexpected state entering parsePostDecimalDigits")
713−
714− advancing: while loc < input.count {
715− let c = input[loc]
716− switch c {
717− case Literal.zero...Literal.nine:
718− try f(c)
719− loc = (loc + 1)
720−
721− case Literal.e, Literal.E:
722− state = .exponent
723− return
724−
725− default:
726− break advancing
727− }
728− }
729−
730− state = .done
731− }
732−
733− mutating func parseExponent() throws -> JSONParser.Sign {
734− assert(state == .exponent, "Unexpected state entering parseExponent")
735−
736− loc = (loc + 1)
737− guard loc < input.count else {
738− throw JSONParser.Error.endOfStreamUnexpected
739− }
740−
741− switch input[loc] {
742− case Literal.zero...Literal.nine:
743− state = .exponentDigits
744−
745− case Literal.PLUS:
746− state = .exponentSign
747−
748− case Literal.MINUS:
749− state = .exponentSign
750− return .negative
751−
752− default:
753− throw JSONParser.Error.numberSymbolMissingDigits(offset: start)
754− }
755−
756− return .positive
757− }
758−
759− mutating func parseExponentSign() throws {
760− assert(state == .exponentSign, "Unexpected state entering parseExponentSign")
761− loc = (loc + 1)
762− guard loc < input.count else {
763− throw JSONParser.Error.endOfStreamUnexpected
764− }
765−
766− switch input[loc] {
767− case Literal.zero...Literal.nine:
768− state = .exponentDigits
769−
770− default:
771− throw JSONParser.Error.numberSymbolMissingDigits(offset: start)
772− }
773− }
774−
775− mutating func parseExponentDigits(f: (UInt8) throws -> Void) rethrows {
776− assert(state == .exponentDigits, "Unexpected state entering parseExponentDigits")
777− advancing: while loc < input.count {
778− let c = input[loc]
779− switch c {
780− case Literal.zero...Literal.nine:
781− try f(c)
782− loc = (loc + 1)
783−
784− default:
785− break advancing
786− }
787− }
788−
789− state = .done
790− }
791−}
792−
793−public extension JSONParser {
794−
795− /// Creates a `JSONParser` ready to parse UTF-8 encoded `Data`.
796− ///
797− /// If the data is mutable, it is copied before parsing. The data's lifetime
798− /// is extended for the duration of parsing.
799− @available(*, unavailable, message: "Replaced with parse(utf8:)")
800− init(utf8Data inData: Data) {
801− fatalError("unavailable code cannot be executed")
802− }
803−
804− /// Creates a `JSONParser` from the code units represented by the `string`.
805− ///
806− /// The synthesized string is lifetime-extended for the duration of parsing.
807− @available(*, unavailable, message: "Replaced with parse(utf8:)")
808− init(string: String) {
809− fatalError("unavailable code cannot be executed")
810− }
811−
812− /// Creates an instance of `JSON` from UTF-8 encoded `data`.
813− static func parse(utf8 data: Data) throws -> JSON {
814− return try data.withUnsafeBytes { (ptr: UnsafePointer<UInt8>) -> JSON in
815− let buffer = UnsafeBufferPointer(start: ptr, count: data.count)
816− var parser = JSONParser(input: buffer)
817− return try parser.parse()
818− }
819− }
820−
821− /// Creates an instance of `JSON` from `string`.
822− static func parse(_ string: String) throws -> JSON {
823− return try string.utf8CString.withUnsafeBufferPointer { (nulTerminatedBuffer) throws -> JSON in
824− return try nulTerminatedBuffer.baseAddress!.withMemoryRebound(to: UInt8.self, capacity: nulTerminatedBuffer.count) { (utf8Base) throws -> JSON in
825− // don't want to include the nul termination in the buffer - trim it off
826− let buffer = UnsafeBufferPointer(start: utf8Base, count: nulTerminatedBuffer.count - 1)
827− var parser = JSONParser(input: buffer)
828− return try parser.parse()
829− }
830− }
831− }
832−
833−}
834−
835−extension JSONParser: JSONParserType {
836−
837− /// Creates an instance of `JSON` from UTF-8 encoded `Data`.
838− /// - parameter data: An instance of `Data` to parse `JSON` from.
839− /// - throws: Any `JSONParser.Error` that arises during decoding.
840− /// - seealso: JSONParser.parse()
841− public static func createJSON(from data: Data) throws -> JSON {
842− return try parse(utf8: data)
843− }
844−
845−}
846−
847−// MARK: - Errors
848−
849−extension JSONParser {
850−
851− /// Enumeration describing possible errors that occur while parsing a JSON
852− /// document. Most errors include an associated `offset`, representing the
853− /// offset into the UTF-8 characters making up the document where the error
854− /// occurred.
855− public enum Error: Swift.Error {
856− /// The parser ran out of data prematurely. This usually means a value
857− /// was not escaped, such as a string literal not ending with a double
858− /// quote.
859− case endOfStreamUnexpected
860−
861− /// Unexpected non-whitespace data was left around `offset` after
862− /// parsing all valid JSON.
863− case endOfStreamGarbage(offset: Int)
864−
865− /// Too many nested objects or arrays occured at the literal started
866− /// around `offset`.
867− case exceededNestingLimit(offset: Int)
868−
869− /// A `character` was not a valid start of a value around `offset`.
870− case valueInvalid(offset: Int, character: UnicodeScalar)
871−
872− /// Badly-formed Unicode escape sequence at `offset`. A Unicode escape
873− /// uses the text "\u" followed by 4 hex digits, such as "\uF09F\uA684"
874− /// to represent U+1F984, "UNICORN FACE".
875− case unicodeEscapeInvalid(offset: Int)
876−
877− /// Badly-formed control character around `offset`. JSON supports
878− /// backslash-escaped double quotes, slashes, whitespace control codes,
879− /// and Unicode escape sequences.
880− case controlCharacterUnrecognized(offset: Int)
881−
882− /// Invalid token, expected `null` around `offset`
883− case literalNilMisspelled(offset: Int)
884−
885− /// Invalid token, expected `true` around `offset`
886− case literalTrueMisspelled(offset: Int)
887−
888− /// Invalid token, expected `false` around `offset`
889− case literalFalseMisspelled(offset: Int)
890−
891− /// Badly-formed collection at given `offset`, expected `,` or `:`
892− case collectionMissingSeparator(offset: Int)
893−
894− /// While parsing an object literal, a value was found without a key
895− /// around `offset`. The start of a string literal was expected.
896− case dictionaryMissingKey(offset: Int)
897−
898− /// Badly-formed number with no digits around `offset`. After a decimal
899− /// point, a number must include some number of digits.
900− case numberMissingFractionalDigits(offset: Int)
901−
902− /// Badly-formed number with symbols ("-" or "e") but no following
903− /// digits around `offset`.
904− case numberSymbolMissingDigits(offset: Int)
905−
906− /// Supplied data is encoded in an unsupported format.
907− case invalidUnicodeStreamEncoding(detectedEncoding: JSONEncodingDetector.Encoding)
908− }
909−
910− fileprivate enum InternalError: Swift.Error {
911− /// Attempted to parse an integer outside the range of [Int.min, Int.max]
912− /// or a double outside the range of representable doubles. Note that
913− /// for doubles, this could be an overflow or an underflow - we don't
914− /// get enough information from Swift here to know which it is. The number
915− /// causing the overflow/underflow began at `offset`.
916− case numberOverflow(offset: Int)
917− }
918−}
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONParsing.swiftdeleted−126
@@ -1,126 +0,0 @@
1−//
2−// JSONParsing.swift
3−// Freddy
4−//
5−// Created by Matthew D. Mathias on 3/17/15.
6−// Copyright © 2015 Big Nerd Ranch. All rights reserved.
7−//
8−
9−import Foundation
10−
11−// MARK: - Deserialize JSON
12−
13−/// Protocol describing a backend parser that can produce `JSON` from `Data`.
14−public protocol JSONParserType {
15−
16− /// Creates an instance of `JSON` from `Data`.
17− /// - parameter data: An instance of `Data` to use to create `JSON`.
18− /// - throws: An error that may arise from calling `JSONObjectWithData(_:options:)` on `NSJSONSerialization` with the given data.
19− /// - returns: An instance of `JSON`.
20− static func createJSON(from data: Data) throws -> JSON
21−
22−}
23−
24−extension JSON {
25−
26− /// Create `JSON` from UTF-8 `data`. By default, parses using the
27− /// Swift-native `JSONParser` backend.
28− public init(data: Data, usingParser parser: JSONParserType.Type = JSONParser.self) throws {
29− self = try parser.createJSON(from: data)
30− }
31−
32− /// Create `JSON` from UTF-8 `string`.
33− public init(jsonString: Swift.String, usingParser parser: JSONParserType.Type = JSONParser.self) throws {
34− self = try parser.createJSON(from: jsonString.data(using: Swift.String.Encoding.utf8) ?? Data())
35− }
36−}
37−
38−// MARK: - NSJSONSerialization
39−
40−extension JSONSerialization: JSONParserType {
41−
42− // MARK: Decode Data
43−
44− /// Use the built-in, Objective-C based JSON parser to create `JSON`.
45− /// - parameter data: An instance of `Data`.
46− /// - returns: An instance of `JSON`.
47− /// - throws: An error that may arise if the `Data` cannot be parsed into an object.
48− public static func createJSON(from data: Data) throws -> JSON {
49− return makeJSON(with: try JSONSerialization.jsonObject(with: data, options: []))
50− }
51−
52− // MARK: Make JSON
53−
54− /// Makes a `JSON` object by matching its argument to a case in the `JSON` enum.
55− /// - parameter object: The instance of `Any` returned from serializing the JSON.
56− /// - returns: An instance of `JSON` matching the JSON given to the function.
57− private static func makeJSON(with object: Any) -> JSON {
58− switch object {
59− case let n as NSNumber:
60− let numberType = CFNumberGetType(n)
61− switch numberType {
62− case .charType:
63− return .bool(n.boolValue)
64−
65− case .shortType, .intType, .longType, .cfIndexType, .nsIntegerType, .sInt8Type, .sInt16Type, .sInt32Type:
66− return .int(n.intValue)
67−
68− case .sInt64Type, .longLongType /* overflows 32-bit Int */:
69− #if /* 32-bit arch */ arch(arm) || arch(i386)
70− // Why double, when the Freddy parser would bump to String?
71− //
72− // Returning Double avoids making the type depend on whether you're running
73− // 32-bit or 64-bit code when using the NSJSONSerialization parser.
74− // NSJSONSerialization appears to bump numbers larger than Int.max to Double on
75− // 64-bit platforms but use .SInt64Type on 32-bit platforms.
76− // If we returned a String here, you'd get a String value on 32-bit,
77− // but a Double value on 64-bit. Instead, we return Double.
78− //
79− // This means that, if you switch parsers,
80− // you'll have to switch from .double to .string for pulling out
81− // overflowing values, but if you stick with a single parser,
82− // you at least won't have architecture-dependent lookups!
83− return .double(n.doubleValue)
84− #else
85− return .int(n.intValue)
86− #endif
87−
88− case .float32Type, .float64Type, .floatType, .doubleType, .cgFloatType:
89− return .double(n.doubleValue)
90− }
91−
92− case let arr as [Any]:
93− return makeJSONArray(arr)
94−
95− case let dict as [Swift.String: Any]:
96− return makeJSONDictionary(dict)
97−
98− case let s as Swift.String:
99− return .string(s)
100−
101− default:
102− return .null
103− }
104− }
105−
106− // MARK: Make a JSON Array
107−
108− /// Makes a `JSON` array from the object passed in.
109− /// - parameter jsonArray: The array to transform into a `JSON`.
110− /// - returns: An instance of `JSON` matching the array.
111− private static func makeJSONArray(_ jsonArray: [Any]) -> JSON {
112− return .array(jsonArray.map(makeJSON))
113− }
114−
115− // MARK: Make a JSON Dictionary
116−
117− /// Makes a `JSON` dictionary from the Cocoa dictionary passed in.
118− /// - parameter jsonDict: The dictionary to transform into `JSON`.
119− /// - returns: An instance of `JSON` matching the dictionary.
120− private static func makeJSONDictionary(_ jsonDict: [Swift.String: Any]) -> JSON {
121− return JSON(jsonDict.lazy.map { (key, value) in
122− (key, makeJSON(with: value))
123− })
124− }
125−
126−}
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONSerializing.swiftdeleted−54
@@ -1,54 +0,0 @@
1−// Copyright (C) 2016 Big Nerd Ranch, Inc. Licensed under the MIT license WITHOUT ANY WARRANTY.
2−
3−import Foundation
4−
5−// MARK: - Serialize JSON
6−
7−extension JSON {
8−
9− /// Attempt to serialize `JSON` into an `Data`.
10− /// - returns: A byte-stream containing the `JSON` ready for wire transfer.
11− /// - throws: Errors that arise from `JSONSerialization`.
12− /// - see: Foundation.JSONSerialization
13− public func serialize() throws -> Data {
14− return try JSONSerialization.data(withJSONObject: toJSONSerializationValue(), options: [])
15− }
16−
17− /// Attempt to serialize `JSON` into a `String`.
18− /// - returns: A `String` containing the `JSON`.
19− /// - throws: A `JSON.Error.StringSerializationError` or errors that arise from `JSONSerialization`.
20− /// - see: Foundation.JSONSerialization
21− public func serializeString() throws -> String {
22− let data = try self.serialize()
23− guard let json = String(data: data, encoding: String.Encoding.utf8) else {
24− throw Error.stringSerializationError
25− }
26− return json
27− }
28−
29− /// A function to help with the serialization of `JSON`.
30− /// - returns: An `Any` suitable for `JSONSerialization`'s use.
31− private func toJSONSerializationValue() -> Any {
32− switch self {
33− case .array(let jsonArray):
34− return jsonArray.map { $0.toJSONSerializationValue() }
35− case .dictionary(let jsonDictionary):
36− var cocoaDictionary = Swift.Dictionary<Swift.String, Any>(minimumCapacity: jsonDictionary.count)
37− for (key, json) in jsonDictionary {
38− cocoaDictionary[key] = json.toJSONSerializationValue()
39− }
40− return cocoaDictionary
41− case .string(let str):
42− return str
43− case .double(let num):
44− return NSNumber(value: num)
45− case .int(let int):
46− return NSNumber(value: int)
47− case .bool(let b):
48− return NSNumber(value: b)
49− case .null:
50− return NSNull()
51− }
52−
53− }
54−}
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/JSONSubscripting.swiftdeleted−613
@@ -1,613 +0,0 @@
1−//
2−// JSONSubscripting.swift
3−// Freddy
4−//
5−// Created by Zachary Waldowski on 8/15/15.
6−// Copyright © 2015 Big Nerd Ranch. All rights reserved.
7−//
8−
9−// MARK: JSONPathType
10−
11−/// A protocol used to define a path within an instance of `JSON` that leads to some desired value.
12−///
13−/// A custom type, such as a `RawRepresentable` enum, may be made to conform to `JSONPathType`
14−/// and used with the subscript APIs.
15−public protocol JSONPathType {
16− /// Use `self` to key into a `dictionary`.
17− ///
18− /// Unlike Swift dictionaries, failing to find a value for a key should throw
19− /// an error rather than convert to `nil`.
20− ///
21− /// Upon failure, implementers should throw an error from `JSON.Error`.
22− func value(in dictionary: [String : JSON]) throws -> JSON
23−
24− /// Use `self` to index into an `array`.
25− ///
26− /// Unlike Swift arrays, attempting to index outside the collection's bounds
27− /// should throw an error rather than crash.
28− ///
29− /// Upon failure, implementers should throw an error from `JSON.Error`.
30− func value(in array: [JSON]) throws -> JSON
31−}
32−
33−extension JSONPathType {
34−
35− /// The default behavior for keying into a dictionary is to throw
36− /// `JSON.Error.UnexpectedSubscript`.
37− public func value(in dictionary: [String : JSON]) throws -> JSON {
38− throw JSON.Error.unexpectedSubscript(type: Self.self)
39− }
40−
41− /// The default behavior for indexing into an array is to throw
42− /// `JSON.Error.UnexpectedSubscript`.
43− public func value(in array: [JSON]) throws -> JSON {
44− throw JSON.Error.unexpectedSubscript(type: Self.self)
45− }
46−
47−}
48−
49−extension String: JSONPathType {
50−
51− /// A method used to retrieve a value from a given dictionary for a specific key.
52− /// - parameter dictionary: A `Dictionary` with `String` keys and `JSON` values.
53− /// - throws: `.KeyNotFound` with an associated value of `self`, where `self` is a `String`,
54− /// should the key not be present within the `JSON`.
55− /// - returns: The `JSON` value associated with the given key.
56− public func value(in dictionary: [String : JSON]) throws -> JSON {
57− guard let next = dictionary[self] else {
58− throw JSON.Error.keyNotFound(key: self)
59− }
60− return next
61− }
62−
63−}
64−
65−extension Int: JSONPathType {
66−
67− /// A method used to retrieve a value from a given array for a specific index.
68− /// - parameter array: An `Array` of `JSON`.
69− /// - throws: `.IndexOutOfBounds` with an associated value of `self`, where `self` is an `Int`,
70− /// should the index not be within the valid range for the array of `JSON`.
71− /// - returns: The `JSON` value found at the given index.
72− public func value(in array: [JSON]) throws -> JSON {
73− guard case array.indices = self else {
74− throw JSON.Error.indexOutOfBounds(index: self)
75− }
76− return array[self]
77− }
78−
79−}
80−
81−// MARK: - Subscripting core
82−
83−private extension JSON {
84−
85− enum SubscriptError: Swift.Error {
86− case subscriptIntoNull(JSONPathType)
87− }
88−
89− func value(for pathFragment: JSONPathType, detectingNull: Bool) throws -> JSON {
90− switch self {
91− case .null where detectingNull:
92− throw SubscriptError.subscriptIntoNull(pathFragment)
93− case let .dictionary(dict):
94− return try pathFragment.value(in: dict)
95− case let .array(array):
96− return try pathFragment.value(in: array)
97− default:
98− throw Error.unexpectedSubscript(type: type(of: pathFragment))
99− }
100− }
101−
102− func value(at path: [JSONPathType], detectingNull: Bool = false) throws -> JSON {
103− var result = self
104− for pathFragment in path {
105− result = try result.value(for: pathFragment, detectingNull: detectingNull)
106− }
107− return result
108− }
109−
110−}
111−
112−// MARK: - Subscripting operator
113−
114−extension JSON {
115−
116− public subscript(key: String) -> JSON? {
117− return try? value(for: key, detectingNull: false)
118− }
119−
120− public subscript(index: Int) -> JSON? {
121− return try? value(for: index, detectingNull: false)
122− }
123−
124−}
125−
126−// MARK: - Simple member unpacking
127−
128−extension JSON {
129−
130− /// Attempts to decode into the returning type from a path into JSON.
131− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`.
132− /// - parameter type: If the context this method is called from does not
133− /// make the return type clear, pass a type implementing `JSONDecodable`
134− /// to disambiguate the type to decode with.
135− /// - returns: An initialized member from the inner JSON.
136− /// - throws: One of the following errors contained in `JSON.Error`:
137− /// * `KeyNotFound`: A given `String` key does not exist inside a
138− /// descendant `JSON` dictionary.
139− /// * `IndexOutOfBounds`: A given `Int` index is outside the bounds of a
140− /// descendant `JSON` array.
141− /// * `UnexpectedSubscript`: A given subscript cannot be used with the
142− /// corresponding `JSON` value.
143− /// * `TypeNotConvertible`: The target value's type inside of
144− /// the `JSON` instance does not match `Decoded`.
145− public func decode<Decoded: JSONDecodable>(at path: JSONPathType..., type: Decoded.Type = Decoded.self) throws -> Decoded {
146− return try Decoded(json: value(at: path))
147− }
148−
149− /// Retrieves a `Double` from a path into JSON.
150− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
151− /// - returns: A floating-point `Double`
152− /// - throws: One of the `JSON.Error` cases thrown by `decode(at:type:)`.
153− /// - seealso: `JSON.decode(at:type:)`
154− public func getDouble(at path: JSONPathType...) throws -> Double {
155− return try Double(json: value(at: path))
156− }
157−
158− /// Retrieves an `Int` from a path into JSON.
159− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
160− /// - returns: A numeric `Int`
161− /// - throws: One of the `JSON.Error` cases thrown by `decode(at:type:)`.
162− /// - seealso: `JSON.decode(at:type:)`
163− public func getInt(at path: JSONPathType...) throws -> Int {
164− return try Int(json: value(at: path))
165− }
166−
167− /// Retrieves a `String` from a path into JSON.
168− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
169− /// - returns: A textual `String`
170− /// - throws: One of the `JSON.Error` cases thrown by `decode(at:type:)`.
171− /// - seealso: `JSON.decode(at:type:)`
172− public func getString(at path: JSONPathType...) throws -> String {
173− return try String(json: value(at: path))
174− }
175−
176− /// Retrieves a `Bool` from a path into JSON.
177− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
178− /// - returns: A truthy `Bool`
179− /// - throws: One of the `JSON.Error` cases thrown by `decode(at:type:)`.
180− /// - seealso: `JSON.decode(at:type:)`
181− public func getBool(at path: JSONPathType...) throws -> Bool {
182− return try Bool(json: value(at: path))
183− }
184−
185− /// Retrieves a `[JSON]` from a path into JSON.
186− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
187− /// - returns: An `Array` of `JSON` elements
188− /// - throws: One of the `JSON.Error` cases thrown by `decode(at:type:)`.
189− /// - seealso: `JSON.decode(at:type:)`
190− public func getArray(at path: JSONPathType...) throws -> [JSON] {
191− return try JSON.getArray(from: value(at: path))
192− }
193−
194− /// Attempts to decode many values from a descendant JSON array at a path
195− /// into JSON.
196− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
197− /// - parameter type: If the context this method is called from does not
198− /// make the return type clear, pass a type implementing `JSONDecodable`
199− /// to disambiguate the type to decode with.
200− /// - returns: An `Array` of decoded elements
201− /// - throws: One of the `JSON.Error` cases thrown by `decode(at:type:)`, or
202− /// any error that arises from decoding the contained values.
203− /// - seealso: `JSON.decode(at:type:)`
204− public func decodedArray<Decoded: JSONDecodable>(at path: JSONPathType..., type: Decoded.Type = Decoded.self) throws -> [Decoded] {
205− return try JSON.decodedArray(from: value(at: path))
206− }
207−
208− /// Retrieves a `[String: JSON]` from a path into JSON.
209− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
210− /// - returns: An `Dictionary` of `String` mapping to `JSON` elements
211− /// - throws: One of the `JSON.Error` cases thrown by `decode(at:type:)`.
212− /// - seealso: `JSON.decode(at:type:)`
213− public func getDictionary(at path: JSONPathType...) throws -> [String: JSON] {
214− return try JSON.getDictionary(from: value(at: path))
215− }
216−
217− /// Attempts to decode many values from a descendant JSON object at a path
218− /// into JSON.
219− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
220− /// - parameter type: If the context this method is called from does not
221− /// make the return type clear, pass a type implementing `JSONDecodable`
222− /// to disambiguate the value type to decode with.
223− /// - returns: A `Dictionary` of `String` keys and decoded values.
224− /// - throws: One of the `JSON.Error` cases thrown by `decode(at:type:)` or
225− /// any error that arises from decoding the contained values.
226− /// - seealso: `JSON.decode(at:type:)`
227− public func decodedDictionary<Decoded: JSONDecodable>(at path: JSONPathType..., type: Decoded.Type = Decoded.self) throws -> [String: Decoded] {
228− return try JSON.decodedDictionary(from: value(at: path))
229− }
230−
231−}
232−
233−// MARK: - NotFound-Or-Null-to-Optional unpacking
234−
235−extension JSON {
236−
237− /// An `OptionSetType` used to represent the different options available for subscripting `JSON` with `null` values or missing keys.
238− /// * `.NullBecomesNil` - Treat `null` values as `nil`.
239− /// * `.MissingKeyBecomesNil` - Treat missing keys as `nil`.
240− public struct SubscriptingOptions: OptionSet {
241− public let rawValue: Int
242− public init(rawValue: Int) {
243− self.rawValue = rawValue
244− }
245−
246− /// Treat `null` values as `nil`.
247− public static let NullBecomesNil = SubscriptingOptions(rawValue: 1 << 0)
248− /// Treat missing keys as `nil`.
249− public static let MissingKeyBecomesNil = SubscriptingOptions(rawValue: 1 << 1)
250− }
251−
252− fileprivate func mapOptional<Value>(at path: [JSONPathType], alongPath options: SubscriptingOptions, transform: (JSON) throws -> Value) throws -> Value? {
253− let detectNull = options.contains(.NullBecomesNil)
254− let detectNotFound = options.contains(.MissingKeyBecomesNil)
255− var json: JSON?
256− do {
257− json = try value(at: path, detectingNull: detectNull)
258− return try json.map(transform)
259− } catch Error.indexOutOfBounds where detectNotFound {
260− return nil
261− } catch Error.keyNotFound where detectNotFound {
262− return nil
263− } catch Error.valueNotConvertible where detectNull && json == .null {
264− return nil
265− } catch SubscriptError.subscriptIntoNull where detectNull {
266− return nil
267− }
268− }
269−}
270−
271−extension JSON {
272−
273− /// Decodes a `JSON` instance if it is not `.Null`, throws otherwise.
274− /// - parameter json: An instance of `JSON`.
275− /// - returns: An instance of some type that conforms to `JSONDecodable`.
276− /// - throws: `Error.ValueNotConvertible` if the `JSON` instance is `.Null`.
277− private static func getDecoded<Decoded: JSONDecodable>(json: JSON) throws -> Decoded {
278− guard json != .null else {
279− throw Error.valueNotConvertible(value: json, to: Decoded.self)
280− }
281− return try Decoded.init(json: json)
282− }
283−
284− /// Optionally decodes into the returning type from a path into JSON.
285− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
286− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
287− /// - parameter type: If the context this method is called from does not
288− /// make the return type clear, pass a type implementing `JSONDecodable`
289− /// to disambiguate the type to decode with.
290− /// - returns: A decoded value from the inner JSON if found, or `nil`.
291− /// - throws: One of the following errors contained in `JSON.Error`:
292− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
293− /// `JSON` dictionary.
294− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
295− /// descendant `JSON` array.
296− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
297− /// corresponding `JSON` value.
298− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
299− /// instance does not match the decoded value.
300− /// * Any error that arises from decoding the value.
301− public func decode<Decoded: JSONDecodable>(at path: JSONPathType..., alongPath options: SubscriptingOptions, type: Decoded.Type = Decoded.self) throws -> Decoded? {
302− return try mapOptional(at: path, alongPath: options, transform: JSON.getDecoded)
303− }
304−
305− /// Optionally retrieves a `Double` from a path into JSON.
306− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`.
307− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
308− /// - returns: A `Double` if a value could be found, otherwise `nil`.
309− /// - throws: One of the following errors contained in `JSON.Error`:
310− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
311− /// `JSON` dictionary.
312− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
313− /// descendant `JSON` array.
314− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
315− /// corresponding `JSON` value.
316− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
317− /// instance does not match the decoded value.
318− public func getDouble(at path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> Double? {
319− return try mapOptional(at: path, alongPath: options, transform: Double.init)
320− }
321−
322− /// Optionally retrieves a `Int` from a path into JSON.
323− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
324− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
325− /// - returns: A numeric `Int` if a value could be found, otherwise `nil`.
326− /// - throws: One of the following errors contained in `JSON.Error`:
327− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
328− /// `JSON` dictionary.
329− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
330− /// descendant `JSON` array.
331− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
332− /// corresponding `JSON` value.
333− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
334− /// instance does not match the decoded value.
335− public func getInt(at path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> Int? {
336− return try mapOptional(at: path, alongPath: options, transform: Int.init)
337− }
338−
339− /// Optionally retrieves a `String` from a path into JSON.
340− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
341− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
342− /// - returns: A text `String` if a value could be found, otherwise `nil`.
343− /// - throws: One of the following errors contained in `JSON.Error`:
344− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
345− /// `JSON` dictionary.
346− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
347− /// descendant `JSON` array.
348− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
349− /// corresponding `JSON` value.
350− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
351− /// instance does not match the decoded value.
352− public func getString(at path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> String? {
353− return try mapOptional(at: path, alongPath: options, transform: String.init)
354− }
355−
356− /// Optionally retrieves a `Bool` from a path into JSON.
357− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
358− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
359− /// - returns: A truthy `Bool` if a value could be found, otherwise `nil`.
360− /// - throws: One of the following errors contained in `JSON.Error`:
361− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
362− /// `JSON` dictionary.
363− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
364− /// descendant `JSON` array.
365− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
366− /// corresponding `JSON` value.
367− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
368− /// instance does not match the decoded value.
369− public func getBool(at path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> Bool? {
370− return try mapOptional(at: path, alongPath: options, transform: Bool.init)
371− }
372−
373− /// Optionally retrieves a `[JSON]` from a path into the recieving structure.
374− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
375− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
376− /// - returns: An `Array` of `JSON` elements if a value could be found,
377− /// otherwise `nil`.
378− /// - throws: One of the following errors contained in `JSON.Error`:
379− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
380− /// `JSON` dictionary.
381− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
382− /// descendant `JSON` array.
383− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
384− /// corresponding `JSON` value.
385− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
386− /// instance does not match the decoded value.
387− public func getArray(at path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> [JSON]? {
388− return try mapOptional(at: path, alongPath: options, transform: JSON.getArray)
389− }
390−
391− /// Optionally decodes many values from a descendant array at a path into
392− /// JSON.
393− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
394− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
395− /// - parameter type: If the context this method is called from does not
396− /// make the return type clear, pass a type implementing `JSONDecodable`
397− /// to disambiguate the value type to decode with.
398− /// - returns: An `Array` of decoded elements if found, otherwise `nil`.
399− /// - throws: One of the following errors contained in `JSON.Error`:
400− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
401− /// `JSON` dictionary.
402− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
403− /// descendant `JSON` array.
404− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
405− /// corresponding `JSON` value.
406− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
407− /// instance does not match the decoded value.
408− /// * Any error that arises from decoding the value.
409− public func decodedArray<Decoded: JSONDecodable>(at path: JSONPathType..., alongPath options: SubscriptingOptions, type: Decoded.Type = Decoded.self) throws -> [Decoded]? {
410− return try mapOptional(at: path, alongPath: options, transform: JSON.decodedArray)
411− }
412−
413− /// Optionally retrieves a `[String: JSON]` from a path into the recieving
414− /// structure.
415− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
416− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
417− /// - returns: A `Dictionary` of `String` mapping to `JSON` elements if a
418− /// value could be found, otherwise `nil`.
419− /// - throws: One of the following errors contained in `JSON.Error`:
420− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
421− /// `JSON` dictionary.
422− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
423− /// descendant `JSON` array.
424− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
425− /// corresponding `JSON` value.
426− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
427− /// instance does not match the decoded value.
428− public func getDictionary(at path: JSONPathType..., alongPath options: SubscriptingOptions) throws -> [String: JSON]? {
429− return try mapOptional(at: path, alongPath: options, transform: JSON.getDictionary)
430− }
431−
432− /// Optionally attempts to decode many values from a descendant object at a path
433− /// into JSON.
434− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
435− /// - parameter alongPath: Options that control what should be done with values that are `null` or keys that are missing.
436− /// - parameter type: If the context this method is called from does not
437− /// make the return type clear, pass a type implementing `JSONDecodable`
438− /// to disambiguate the value type to decode with.
439− /// - returns: A `Dictionary` of `String` mapping to decoded elements if a
440− /// value could be found, otherwise `nil`.
441− /// - throws: One of the following errors contained in `JSON.Error`:
442− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
443− /// `JSON` dictionary.
444− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
445− /// descendant `JSON` array.
446− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
447− /// corresponding `JSON` value.
448− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
449− /// instance does not match the decoded value.
450− /// * Any error that arises from decoding the value.
451− public func decodedDictionary<Decoded: JSONDecodable>(at path: JSONPathType..., alongPath options: SubscriptingOptions, type: Decoded.Type = Decoded.self) throws -> [String: Decoded]? {
452− return try mapOptional(at: path, alongPath: options, transform: JSON.decodedDictionary)
453− }
454−
455−}
456−
457−// MARK: - Missing-with-fallback unpacking
458−
459−extension JSON {
460−
461− fileprivate func mapOptional<Value>(at path: [JSONPathType], fallback: () -> Value, transform: (JSON) throws -> Value) throws -> Value {
462− return try mapOptional(at: path, alongPath: .MissingKeyBecomesNil, transform: transform) ?? fallback()
463− }
464−
465− /// Attempts to decode into the returning type from a path into
466− /// JSON, or returns a fallback if not found.
467− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
468− /// - parameter fallback: Value to use when one is missing at the subscript.
469− /// - returns: An initialized member from the inner JSON.
470− /// - throws: One of the following errors contained in `JSON.Error`:
471− /// * `UnexpectedSubscript`: A given subscript cannot be used with the
472− /// corresponding `JSON` value.
473− /// * `TypeNotConvertible`: The target value's type inside of
474− /// the `JSON` instance does not match `Decoded`.
475− public func decode<Decoded: JSONDecodable>(at path: JSONPathType..., or fallback: @autoclosure() -> Decoded) throws -> Decoded {
476− return try mapOptional(at: path, fallback: fallback, transform: Decoded.init)
477− }
478−
479− /// Retrieves a `Double` from a path into JSON or a fallback if not found.
480− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
481− /// - parameter fallback: `Double` to use when one is missing at the subscript.
482− /// - returns: A floating-point `Double`
483− /// - throws: One of the `JSON.Error` cases thrown by calling `mapOptional(at:fallback:transform:)`.
484− public func getDouble(at path: JSONPathType..., or fallback: @autoclosure() -> Double) throws -> Double {
485− return try mapOptional(at: path, fallback: fallback, transform: Double.init)
486− }
487−
488− /// Retrieves an `Int` from a path into JSON or a fallback if not found.
489− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
490− /// - parameter fallback: `Int` to use when one is missing at the subscript.
491− /// - returns: A numeric `Int`
492− /// - throws: One of the following errors contained in `JSON.Error`:
493− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
494− /// `JSON` dictionary.
495− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
496− /// descendant `JSON` array.
497− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
498− /// corresponding `JSON` value.
499− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
500− /// instance does not match the decoded value.
501− public func getInt(at path: JSONPathType..., or fallback: @autoclosure() -> Int) throws -> Int {
502− return try mapOptional(at: path, fallback: fallback, transform: Int.init)
503− }
504−
505− /// Retrieves a `String` from a path into JSON or a fallback if not found.
506− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
507− /// - parameter fallback: `String` to use when one is missing at the subscript.
508− /// - returns: A textual `String`
509− /// - throws: One of the following errors contained in `JSON.Error`:
510− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
511− /// `JSON` dictionary.
512− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
513− /// descendant `JSON` array.
514− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
515− /// corresponding `JSON` value.
516− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
517− /// instance does not match the decoded value.
518− public func getString(at path: JSONPathType..., or fallback: @autoclosure() -> String) throws -> String {
519− return try mapOptional(at: path, fallback: fallback, transform: String.init)
520− }
521−
522− /// Retrieves a `Bool` from a path into JSON or a fallback if not found.
523− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
524− /// - parameter fallback: `Bool` to use when one is missing at the subscript.
525− /// - returns: A truthy `Bool`
526− /// - throws: One of the following errors contained in `JSON.Error`:
527− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
528− /// `JSON` dictionary.
529− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
530− /// descendant `JSON` array.
531− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
532− /// corresponding `JSON` value.
533− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
534− /// instance does not match the decoded value.
535− public func getBool(at path: JSONPathType..., or fallback: @autoclosure() -> Bool) throws -> Bool {
536− return try mapOptional(at: path, fallback: fallback, transform: Bool.init)
537− }
538−
539− /// Retrieves a `[JSON]` from a path into JSON or a fallback if not found.
540− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
541− /// - parameter fallback: `Array` to use when one is missing at the subscript.
542− /// - returns: An `Array` of `JSON` elements
543− /// - throws: One of the following errors contained in `JSON.Error`:
544− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
545− /// `JSON` dictionary.
546− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
547− /// descendant `JSON` array.
548− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
549− /// corresponding `JSON` value.
550− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
551− /// instance does not match the decoded value.
552− public func getArray(at path: JSONPathType..., or fallback: @autoclosure() -> [JSON]) throws -> [JSON] {
553− return try mapOptional(at: path, fallback: fallback, transform: JSON.getArray)
554− }
555−
556− /// Attempts to decodes many values from a desendant JSON array at a path
557− /// into the recieving structure, returning a fallback if not found.
558− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
559− /// - parameter fallback: `Array` to use when one is missing at the subscript.
560− /// - returns: An `Array` of decoded elements
561− /// - throws: One of the following errors contained in `JSON.Error`:
562− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
563− /// `JSON` dictionary.
564− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
565− /// descendant `JSON` array.
566− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
567− /// corresponding `JSON` value.
568− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
569− /// instance does not match the decoded value.
570− /// * Any error that arises from decoding the value.
571− public func decodedArray<Decoded: JSONDecodable>(at path: JSONPathType..., or fallback: @autoclosure() -> [Decoded]) throws -> [Decoded] {
572− return try mapOptional(at: path, fallback: fallback, transform: JSON.decodedArray)
573− }
574−
575− /// Retrieves a `[String: JSON]` from a path into JSON or a fallback if not
576− /// found.
577− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
578− /// - parameter fallback: `Dictionary` to use when one is missing at the subscript.
579− /// - returns: An `Dictionary` of `String` mapping to `JSON` elements
580− /// - throws: One of the following errors contained in `JSON.Error`:
581− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
582− /// `JSON` dictionary.
583− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
584− /// descendant `JSON` array.
585− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
586− /// corresponding `JSON` value.
587− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
588− /// instance does not match the decoded value.
589− public func getDictionary(at path: JSONPathType..., or fallback: @autoclosure() -> [String: JSON]) throws -> [String: JSON] {
590− return try mapOptional(at: path, fallback: fallback, transform: JSON.getDictionary)
591− }
592−
593− /// Attempts to decode many values from a descendant JSON object at a path
594− /// into the receiving structure, returning a fallback if not found.
595− /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
596− /// - parameter fallback: Value to use when one is missing at the subscript
597− /// - returns: A `Dictionary` of `String` mapping to decoded elements.
598− /// - throws: One of the following errors contained in `JSON.Error`:
599− /// * `KeyNotFound`: A key `path` does not exist inside a descendant
600− /// `JSON` dictionary.
601− /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a
602− /// descendant `JSON` array.
603− /// * `UnexpectedSubscript`: A `path` item cannot be used with the
604− /// corresponding `JSON` value.
605− /// * `TypeNotConvertible`: The target value's type inside of the `JSON`
606− /// instance does not match the decoded value.
607− /// * Any error that arises from decoding the value.
608− public func decodedDictionary<Decoded: JSONDecodable>(at path: JSONPathType..., or fallback: @autoclosure() -> [String: Decoded]) throws -> [String: Decoded] {
609− return try mapOptional(at: path, fallback: fallback, transform: JSON.decodedDictionary)
610− }
611−
612−
613−}
tests/JSONTestSuite/parsers/test_Freddy_20161018/test_Freddy/main.swiftdeleted−40
@@ -1,40 +0,0 @@
1−//
2−// main.swift
3−// test_Freddy
4−//
5−// Created by nst on 10/08/16.
6−// Copyright © 2016 Nicolas Seriot. All rights reserved.
7−//
8−
9−import Foundation
10−
11−func main() {
12−
13− guard ProcessInfo.processInfo.arguments.count == 2 else {
14− let url = URL(fileURLWithPath: ProcessInfo.processInfo.arguments[0])
15− let programName = url.lastPathComponent
16− print("Usage: ./\(programName) file.json")
17− exit(1)
18− }
19−
20− let path = ProcessInfo.processInfo.arguments[1]
21− let url = NSURL.fileURL(withPath:path)
22−
23− do {
24− let data = try Data(contentsOf:url)
25− do {
26− let o = try JSONParser.parse(utf8: data)
27− exit(0)
28− } catch {
29− exit(1)
30− }
31−
32− } catch let e {
33− print("*** CANNOT READ DATA AT \(url)")
34− print(e)
35− exit(1)
36− }
37−
38−}
39−
40−main()
tests/JSONTestSuite/parsers/test_Freddy_2_1_0/bin/test_Freddy_2_1_0deleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/project.pbxprojdeleted−300
@@ -1,300 +0,0 @@
1−// !$*UTF8*$!
2−{
3− archiveVersion = 1;
4− classes = {
5− };
6− objectVersion = 46;
7− objects = {
8−
9−/* Begin PBXBuildFile section */
10− 03D84ABB1D5B0A1000776402 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D84ABA1D5B0A1000776402 /* main.swift */; };
11− 03F8F7811D5B75600021630C /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F7781D5B75600021630C /* JSON.swift */; };
12− 03F8F7821D5B75600021630C /* JSONDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F7791D5B75600021630C /* JSONDecodable.swift */; };
13− 03F8F7831D5B75600021630C /* JSONEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77A1D5B75600021630C /* JSONEncodable.swift */; };
14− 03F8F7841D5B75600021630C /* JSONEncodingDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77B1D5B75600021630C /* JSONEncodingDetector.swift */; };
15− 03F8F7851D5B75600021630C /* JSONLiteralConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77C1D5B75600021630C /* JSONLiteralConvertible.swift */; };
16− 03F8F7861D5B75600021630C /* JSONParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77D1D5B75600021630C /* JSONParser.swift */; };
17− 03F8F7871D5B75600021630C /* JSONParsing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77E1D5B75600021630C /* JSONParsing.swift */; };
18− 03F8F7881D5B75600021630C /* JSONSerializing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F77F1D5B75600021630C /* JSONSerializing.swift */; };
19− 03F8F7891D5B75600021630C /* JSONSubscripting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F8F7801D5B75600021630C /* JSONSubscripting.swift */; };
20−/* End PBXBuildFile section */
21−
22−/* Begin PBXCopyFilesBuildPhase section */
23− 03D84AB51D5B0A1000776402 /* CopyFiles */ = {
24− isa = PBXCopyFilesBuildPhase;
25− buildActionMask = 2147483647;
26− dstPath = /usr/share/man/man1;
27− dstSubfolderSpec = 0;
28− files = (
29− );
30− runOnlyForDeploymentPostprocessing = 1;
31− };
32−/* End PBXCopyFilesBuildPhase section */
33−
34−/* Begin PBXFileReference section */
35− 03D84AB71D5B0A1000776402 /* test_Freddy */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = test_Freddy; sourceTree = BUILT_PRODUCTS_DIR; };
36− 03D84ABA1D5B0A1000776402 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
37− 03F8F7781D5B75600021630C /* JSON.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSON.swift; path = test_Freddy/JSON.swift; sourceTree = "<group>"; };
38− 03F8F7791D5B75600021630C /* JSONDecodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONDecodable.swift; path = test_Freddy/JSONDecodable.swift; sourceTree = "<group>"; };
39− 03F8F77A1D5B75600021630C /* JSONEncodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONEncodable.swift; path = test_Freddy/JSONEncodable.swift; sourceTree = "<group>"; };
40− 03F8F77B1D5B75600021630C /* JSONEncodingDetector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONEncodingDetector.swift; path = test_Freddy/JSONEncodingDetector.swift; sourceTree = "<group>"; };
41− 03F8F77C1D5B75600021630C /* JSONLiteralConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONLiteralConvertible.swift; path = test_Freddy/JSONLiteralConvertible.swift; sourceTree = "<group>"; };
42− 03F8F77D1D5B75600021630C /* JSONParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONParser.swift; path = test_Freddy/JSONParser.swift; sourceTree = "<group>"; };
43− 03F8F77E1D5B75600021630C /* JSONParsing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONParsing.swift; path = test_Freddy/JSONParsing.swift; sourceTree = "<group>"; };
44− 03F8F77F1D5B75600021630C /* JSONSerializing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONSerializing.swift; path = test_Freddy/JSONSerializing.swift; sourceTree = "<group>"; };
45− 03F8F7801D5B75600021630C /* JSONSubscripting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONSubscripting.swift; path = test_Freddy/JSONSubscripting.swift; sourceTree = "<group>"; };
46−/* End PBXFileReference section */
47−
48−/* Begin PBXFrameworksBuildPhase section */
49− 03D84AB41D5B0A1000776402 /* Frameworks */ = {
50− isa = PBXFrameworksBuildPhase;
51− buildActionMask = 2147483647;
52− files = (
53− );
54− runOnlyForDeploymentPostprocessing = 0;
55− };
56−/* End PBXFrameworksBuildPhase section */
57−
58−/* Begin PBXGroup section */
59− 03D84AAE1D5B0A1000776402 = {
60− isa = PBXGroup;
61− children = (
62− 03F8F7781D5B75600021630C /* JSON.swift */,
63− 03F8F7791D5B75600021630C /* JSONDecodable.swift */,
64− 03F8F77A1D5B75600021630C /* JSONEncodable.swift */,
65− 03F8F77B1D5B75600021630C /* JSONEncodingDetector.swift */,
66− 03F8F77C1D5B75600021630C /* JSONLiteralConvertible.swift */,
67− 03F8F77D1D5B75600021630C /* JSONParser.swift */,
68− 03F8F77E1D5B75600021630C /* JSONParsing.swift */,
69− 03F8F77F1D5B75600021630C /* JSONSerializing.swift */,
70− 03F8F7801D5B75600021630C /* JSONSubscripting.swift */,
71− 03D84AB91D5B0A1000776402 /* test_Freddy */,
72− 03D84AB81D5B0A1000776402 /* Products */,
73− );
74− sourceTree = "<group>";
75− };
76− 03D84AB81D5B0A1000776402 /* Products */ = {
77− isa = PBXGroup;
78− children = (
79− 03D84AB71D5B0A1000776402 /* test_Freddy */,
80− );
81− name = Products;
82− sourceTree = "<group>";
83− };
84− 03D84AB91D5B0A1000776402 /* test_Freddy */ = {
85− isa = PBXGroup;
86− children = (
87− 03D84ABA1D5B0A1000776402 /* main.swift */,
88− );
89− path = test_Freddy;
90− sourceTree = "<group>";
91− };
92−/* End PBXGroup section */
93−
94−/* Begin PBXNativeTarget section */
95− 03D84AB61D5B0A1000776402 /* test_Freddy */ = {
96− isa = PBXNativeTarget;
97− buildConfigurationList = 03D84ABE1D5B0A1000776402 /* Build configuration list for PBXNativeTarget "test_Freddy" */;
98− buildPhases = (
99− 03D84AB31D5B0A1000776402 /* Sources */,
100− 03D84AB41D5B0A1000776402 /* Frameworks */,
101− 03D84AB51D5B0A1000776402 /* CopyFiles */,
102− );
103− buildRules = (
104− );
105− dependencies = (
106− );
107− name = test_Freddy;
108− productName = test_Freddy;
109− productReference = 03D84AB71D5B0A1000776402 /* test_Freddy */;
110− productType = "com.apple.product-type.tool";
111− };
112−/* End PBXNativeTarget section */
113−
114−/* Begin PBXProject section */
115− 03D84AAF1D5B0A1000776402 /* Project object */ = {
116− isa = PBXProject;
117− attributes = {
118− LastSwiftUpdateCheck = 0800;
119− LastUpgradeCheck = 0800;
120− ORGANIZATIONNAME = "Nicolas Seriot";
121− TargetAttributes = {
122− 03D84AB61D5B0A1000776402 = {
123− CreatedOnToolsVersion = 8.0;
124− DevelopmentTeam = VBYRKYS73S;
125− DevelopmentTeamName = "Nicolas Seriot";
126− ProvisioningStyle = Automatic;
127− };
128− };
129− };
130− buildConfigurationList = 03D84AB21D5B0A1000776402 /* Build configuration list for PBXProject "test_Freddy" */;
131− compatibilityVersion = "Xcode 3.2";
132− developmentRegion = English;
133− hasScannedForEncodings = 0;
134− knownRegions = (
135− en,
136− );
137− mainGroup = 03D84AAE1D5B0A1000776402;
138− productRefGroup = 03D84AB81D5B0A1000776402 /* Products */;
139− projectDirPath = "";
140− projectRoot = "";
141− targets = (
142− 03D84AB61D5B0A1000776402 /* test_Freddy */,
143− );
144− };
145−/* End PBXProject section */
146−
147−/* Begin PBXSourcesBuildPhase section */
148− 03D84AB31D5B0A1000776402 /* Sources */ = {
149− isa = PBXSourcesBuildPhase;
150− buildActionMask = 2147483647;
151− files = (
152− 03F8F7881D5B75600021630C /* JSONSerializing.swift in Sources */,
153− 03F8F7821D5B75600021630C /* JSONDecodable.swift in Sources */,
154− 03F8F7851D5B75600021630C /* JSONLiteralConvertible.swift in Sources */,
155− 03F8F7871D5B75600021630C /* JSONParsing.swift in Sources */,
156− 03F8F7861D5B75600021630C /* JSONParser.swift in Sources */,
157− 03F8F7831D5B75600021630C /* JSONEncodable.swift in Sources */,
158− 03D84ABB1D5B0A1000776402 /* main.swift in Sources */,
159− 03F8F7811D5B75600021630C /* JSON.swift in Sources */,
160− 03F8F7891D5B75600021630C /* JSONSubscripting.swift in Sources */,
161− 03F8F7841D5B75600021630C /* JSONEncodingDetector.swift in Sources */,
162− );
163− runOnlyForDeploymentPostprocessing = 0;
164− };
165−/* End PBXSourcesBuildPhase section */
166−
167−/* Begin XCBuildConfiguration section */
168− 03D84ABC1D5B0A1000776402 /* Debug */ = {
169− isa = XCBuildConfiguration;
170− buildSettings = {
171− ALWAYS_SEARCH_USER_PATHS = NO;
172− CLANG_ANALYZER_NONNULL = YES;
173− CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
174− CLANG_CXX_LIBRARY = "libc++";
175− CLANG_ENABLE_MODULES = YES;
176− CLANG_ENABLE_OBJC_ARC = YES;
177− CLANG_WARN_BOOL_CONVERSION = YES;
178− CLANG_WARN_CONSTANT_CONVERSION = YES;
179− CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
180− CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
181− CLANG_WARN_EMPTY_BODY = YES;
182− CLANG_WARN_ENUM_CONVERSION = YES;
183− CLANG_WARN_INT_CONVERSION = YES;
184− CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
185− CLANG_WARN_UNREACHABLE_CODE = YES;
186− CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
187− CODE_SIGN_IDENTITY = "-";
188− COPY_PHASE_STRIP = NO;
189− DEBUG_INFORMATION_FORMAT = dwarf;
190− ENABLE_STRICT_OBJC_MSGSEND = YES;
191− ENABLE_TESTABILITY = YES;
192− GCC_C_LANGUAGE_STANDARD = gnu99;
193− GCC_DYNAMIC_NO_PIC = NO;
194− GCC_NO_COMMON_BLOCKS = YES;
195− GCC_OPTIMIZATION_LEVEL = 0;
196− GCC_PREPROCESSOR_DEFINITIONS = (
197− "DEBUG=1",
198− "$(inherited)",
199− );
200− GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
201− GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
202− GCC_WARN_UNDECLARED_SELECTOR = YES;
203− GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
204− GCC_WARN_UNUSED_FUNCTION = YES;
205− GCC_WARN_UNUSED_VARIABLE = YES;
206− MACOSX_DEPLOYMENT_TARGET = 10.11;
207− MTL_ENABLE_DEBUG_INFO = YES;
208− ONLY_ACTIVE_ARCH = YES;
209− SDKROOT = macosx;
210− SWIFT_OPTIMIZATION_LEVEL = "-Onone";
211− };
212− name = Debug;
213− };
214− 03D84ABD1D5B0A1000776402 /* Release */ = {
215− isa = XCBuildConfiguration;
216− buildSettings = {
217− ALWAYS_SEARCH_USER_PATHS = NO;
218− CLANG_ANALYZER_NONNULL = YES;
219− CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
220− CLANG_CXX_LIBRARY = "libc++";
221− CLANG_ENABLE_MODULES = YES;
222− CLANG_ENABLE_OBJC_ARC = YES;
223− CLANG_WARN_BOOL_CONVERSION = YES;
224− CLANG_WARN_CONSTANT_CONVERSION = YES;
225− CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
226− CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
227− CLANG_WARN_EMPTY_BODY = YES;
228− CLANG_WARN_ENUM_CONVERSION = YES;
229− CLANG_WARN_INT_CONVERSION = YES;
230− CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
231− CLANG_WARN_UNREACHABLE_CODE = YES;
232− CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
233− CODE_SIGN_IDENTITY = "-";
234− COPY_PHASE_STRIP = NO;
235− DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
236− ENABLE_NS_ASSERTIONS = NO;
237− ENABLE_STRICT_OBJC_MSGSEND = YES;
238− GCC_C_LANGUAGE_STANDARD = gnu99;
239− GCC_NO_COMMON_BLOCKS = YES;
240− GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
241− GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
242− GCC_WARN_UNDECLARED_SELECTOR = YES;
243− GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
244− GCC_WARN_UNUSED_FUNCTION = YES;
245− GCC_WARN_UNUSED_VARIABLE = YES;
246− MACOSX_DEPLOYMENT_TARGET = 10.11;
247− MTL_ENABLE_DEBUG_INFO = NO;
248− SDKROOT = macosx;
249− };
250− name = Release;
251− };
252− 03D84ABF1D5B0A1000776402 /* Debug */ = {
253− isa = XCBuildConfiguration;
254− buildSettings = {
255− FRAMEWORK_SEARCH_PATHS = (
256− "$(inherited)",
257− "$(PROJECT_DIR)",
258− );
259− PRODUCT_NAME = "$(TARGET_NAME)";
260− SWIFT_VERSION = 2.3;
261− };
262− name = Debug;
263− };
264− 03D84AC01D5B0A1000776402 /* Release */ = {
265− isa = XCBuildConfiguration;
266− buildSettings = {
267− FRAMEWORK_SEARCH_PATHS = (
268− "$(inherited)",
269− "$(PROJECT_DIR)",
270− );
271− PRODUCT_NAME = "$(TARGET_NAME)";
272− SWIFT_VERSION = 2.3;
273− };
274− name = Release;
275− };
276−/* End XCBuildConfiguration section */
277−
278−/* Begin XCConfigurationList section */
279− 03D84AB21D5B0A1000776402 /* Build configuration list for PBXProject "test_Freddy" */ = {
280− isa = XCConfigurationList;
281− buildConfigurations = (
282− 03D84ABC1D5B0A1000776402 /* Debug */,
283− 03D84ABD1D5B0A1000776402 /* Release */,
284− );
285− defaultConfigurationIsVisible = 0;
286− defaultConfigurationName = Release;
287− };
288− 03D84ABE1D5B0A1000776402 /* Build configuration list for PBXNativeTarget "test_Freddy" */ = {
289− isa = XCConfigurationList;
290− buildConfigurations = (
291− 03D84ABF1D5B0A1000776402 /* Debug */,
292− 03D84AC01D5B0A1000776402 /* Release */,
293− );
294− defaultConfigurationIsVisible = 0;
295− defaultConfigurationName = Release;
296− };
297−/* End XCConfigurationList section */
298− };
299− rootObject = 03D84AAF1D5B0A1000776402 /* Project object */;
300−}
tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7
@@ -1,7 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<Workspace
3− version = "1.0">
4− <FileRef
5− location = "self:test_Freddy.xcodeproj">
6− </FileRef>
7−</Workspace>
tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/project.xcworkspace/xcshareddata/test_Freddy.xcscmblueprintdeleted−30
@@ -1,30 +0,0 @@
1−{
2− "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A",
3− "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4−
5− },
6− "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
7− "6ADA245F937D8ED6D99F5A7865E19F5267A169E2" : 0,
8− "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A" : 0
9− },
10− "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "7B3DFA55-F9BF-41D8-8FD5-204D3162EB03",
11− "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
12− "6ADA245F937D8ED6D99F5A7865E19F5267A169E2" : "dropbox\/JSON\/test_Freddy\/Vendor\/Freddy\/",
13− "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A" : "dropbox\/"
14− },
15− "DVTSourceControlWorkspaceBlueprintNameKey" : "test_Freddy",
16− "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17− "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "JSON\/test_Freddy\/test_Freddy.xcodeproj",
18− "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19− {
20− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/bignerdranch\/Freddy.git",
21− "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
22− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "6ADA245F937D8ED6D99F5A7865E19F5267A169E2"
23− },
24− {
25− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "\/Users\/nst\/Dropbox\/dropbox.git",
26− "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
27− "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "ED13D74FC1ED9BC322EA1859E5AD7D001676FA6A"
28− }
29− ]
30−}
tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_Freddy.xcschemedeleted−91
@@ -1,91 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<Scheme
3− LastUpgradeVersion = "0800"
4− version = "1.3">
5− <BuildAction
6− parallelizeBuildables = "YES"
7− buildImplicitDependencies = "YES">
8− <BuildActionEntries>
9− <BuildActionEntry
10− buildForTesting = "YES"
11− buildForRunning = "YES"
12− buildForProfiling = "YES"
13− buildForArchiving = "YES"
14− buildForAnalyzing = "YES">
15− <BuildableReference
16− BuildableIdentifier = "primary"
17− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
18− BuildableName = "test_Freddy"
19− BlueprintName = "test_Freddy"
20− ReferencedContainer = "container:test_Freddy.xcodeproj">
21− </BuildableReference>
22− </BuildActionEntry>
23− </BuildActionEntries>
24− </BuildAction>
25− <TestAction
26− buildConfiguration = "Debug"
27− selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28− selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29− shouldUseLaunchSchemeArgsEnv = "YES">
30− <Testables>
31− </Testables>
32− <MacroExpansion>
33− <BuildableReference
34− BuildableIdentifier = "primary"
35− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
36− BuildableName = "test_Freddy"
37− BlueprintName = "test_Freddy"
38− ReferencedContainer = "container:test_Freddy.xcodeproj">
39− </BuildableReference>
40− </MacroExpansion>
41− <AdditionalOptions>
42− </AdditionalOptions>
43− </TestAction>
44− <LaunchAction
45− buildConfiguration = "Debug"
46− selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
47− selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
48− launchStyle = "0"
49− useCustomWorkingDirectory = "NO"
50− ignoresPersistentStateOnLaunch = "NO"
51− debugDocumentVersioning = "YES"
52− debugServiceExtension = "internal"
53− allowLocationSimulation = "YES">
54− <BuildableProductRunnable
55− runnableDebuggingMode = "0">
56− <BuildableReference
57− BuildableIdentifier = "primary"
58− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
59− BuildableName = "test_Freddy"
60− BlueprintName = "test_Freddy"
61− ReferencedContainer = "container:test_Freddy.xcodeproj">
62− </BuildableReference>
63− </BuildableProductRunnable>
64− <AdditionalOptions>
65− </AdditionalOptions>
66− </LaunchAction>
67− <ProfileAction
68− buildConfiguration = "Release"
69− shouldUseLaunchSchemeArgsEnv = "YES"
70− savedToolIdentifier = ""
71− useCustomWorkingDirectory = "NO"
72− debugDocumentVersioning = "YES">
73− <BuildableProductRunnable
74− runnableDebuggingMode = "0">
75− <BuildableReference
76− BuildableIdentifier = "primary"
77− BlueprintIdentifier = "03D84AB61D5B0A1000776402"
78− BuildableName = "test_Freddy"
79− BlueprintName = "test_Freddy"
80− ReferencedContainer = "container:test_Freddy.xcodeproj">
81− </BuildableReference>
82− </BuildableProductRunnable>
83− </ProfileAction>
84− <AnalyzeAction
85− buildConfiguration = "Debug">
86− </AnalyzeAction>
87− <ArchiveAction
88− buildConfiguration = "Release"
89− revealArchiveInOrganizer = "YES">
90− </ArchiveAction>
91−</Scheme>
tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22
@@ -1,22 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3−<plist version="1.0">
4−<dict>
5− <key>SchemeUserState</key>
6− <dict>
7− <key>test_Freddy.xcscheme</key>
8− <dict>
9− <key>orderHint</key>
10− <integer>0</integer>
11− </dict>
12− </dict>
13− <key>SuppressBuildableAutocreation</key>
14− <dict>
15− <key>03D84AB61D5B0A1000776402</key>
16− <dict>
17− <key>primary</key>
18− <true/>
19− </dict>
20− </dict>
21−</dict>
22−</plist>
tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSON.swiftdeleted−95
@@ -1,95 +0,0 @@
1−//
2−// JSON.swift
3−// Freddy
4−//
5−// Created by Matthew D. Mathias on 3/17/15.
6−// Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
7−//
8−
9−/// An enum to describe the structure of JSON.
10−public enum JSON {
11− /// A case for denoting an array with an associated value of `[JSON]`
12− case Array([JSON])
13− /// A case for denoting a dictionary with an associated value of `[Swift.String: JSON]`
14− case Dictionary([Swift.String: JSON])
15− /// A case for denoting a double with an associated value of `Swift.Double`.
16− case Double(Swift.Double)
17− /// A case for denoting an integer with an associated value of `Swift.Int`.
18− case Int(Swift.Int)
19− /// A case for denoting a string with an associated value of `Swift.String`.
20− case String(Swift.String)
21− /// A case for denoting a boolean with an associated value of `Swift.Bool`.
22− case Bool(Swift.Bool)
23− /// A case for denoting null.
24− case Null
25−}
26−
27−// MARK: - Errors
28−
29−extension JSON {
30−
31− /// An enum to encapsulate errors that may arise in working with `JSON`.
32− public enum Error: ErrorType {
33− /// The `index` is out of bounds for a JSON array
34− case IndexOutOfBounds(index: Swift.Int)
35−
36− /// The `key` was not found in the JSON dictionary
37− case KeyNotFound(key: Swift.String)
38−
39− /// The JSON is not subscriptable with `type`
40− case UnexpectedSubscript(type: JSONPathType.Type)
41−
42− /// Unexpected JSON `value` was found that is not convertible `to` type
43− case ValueNotConvertible(value: JSON, to: Any.Type)
44− }
45−
46−}
47−
48−// MARK: - Test Equality
49−
50−/// Return `true` if `lhs` is equal to `rhs`.
51−public func ==(lhs: JSON, rhs: JSON) -> Bool {
52− switch (lhs, rhs) {
53− case (.Array(let arrL), .Array(let arrR)):
54− return arrL == arrR
55− case (.Dictionary(let dictL), .Dictionary(let dictR)):
56− return dictL == dictR
57− case (.String(let strL), .String(let strR)):
58− return strL == strR
59− case (.Double(let dubL), .Double(let dubR)):
60− return dubL == dubR
61− case (.Double(let dubL), .Int(let intR)):
62− return dubL == Double(intR)
63− case (.Int(let intL), .Int(let intR)):
64− return intL == intR
65− case (.Int(let intL), .Double(let dubR)):
66− return Double(intL) == dubR
67− case (.Bool(let bL), .Bool(let bR)):
68− return bL == bR
69− case (.Null, .Null):
70− return true
71− default:
72− return false
73− }
74−}
75−
76−extension JSON: Equatable {}
77−
78−// MARK: - Printing
79−
80−extension JSON: CustomStringConvertible {
81−
82− /// A textual representation of `self`.
83− public var description: Swift.String {
84− switch self {
85− case .Array(let arr): return Swift.String(arr)
86− case .Dictionary(let dict): return Swift.String(dict)
87− case .String(let string): return string
88− case .Double(let double): return Swift.String(double)
89− case .Int(let int): return Swift.String(int)
90− case .Bool(let bool): return Swift.String(bool)
91− case .Null: return "null"
92− }
93− }
94−
95−}
tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONDecodable.swiftdeleted−151
@@ -1,151 +0,0 @@
1−//
2−// JSONDecodable.swift
3−// Freddy
4−//
5−// Created by Matthew D. Mathias on 3/24/15.
6−// Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
7−//
8−
9−/// A protocol to provide functionality for creating a model object with a `JSON`
10−/// value.
11−public protocol JSONDecodable {
12−
13− /// Creates an instance of the model with a `JSON` instance.
14− /// - parameter json: An instance of a `JSON` value from which to
15− /// construct an instance of the implementing type.
16− /// - throws: Any `JSON.Error` for errors derived from inspecting the
17− /// `JSON` value, or any other error involved in decoding.
18− init(json: JSON) throws
19−
20−}
21−
22−extension Double: JSONDecodable {
23−
24− /// An initializer to create an instance of `Double` from a `JSON` value.
25− /// - parameter json: An instance of `JSON`.
26− /// - throws: The initializer will throw an instance of `JSON.Error` if
27− /// an instance of `Double` cannot be created from the `JSON` value that was
28− /// passed to this initializer.
29− public init(json: JSON) throws {
30− switch json {
31− case let .Double(double):
32− self = double
33− case let .Int(int):
34− self = Swift.Double(int)
35− default:
36− throw JSON.Error.ValueNotConvertible(value: json, to: Swift.Double)
37− }
38− }
39−
40−}
41−
42−extension Int: JSONDecodable {
43−
44− /// An initializer to create an instance of `Int` from a `JSON` value.
45− /// - parameter json: An instance of `JSON`.
46− /// - throws: The initializer will throw an instance of `JSON.Error` if
47− /// an instance of `Int` cannot be created from the `JSON` value that was
48− /// passed to this initializer.
49− public init(json: JSON) throws {
50− switch json {
51− case let .Double(double) where double <= Double(Swift.Int.max):
52− self = Swift.Int(double)
53− case let .Int(int):
54− self = int
55− default:
56− throw JSON.Error.ValueNotConvertible(value: json, to: Swift.Int)
57− }
58− }
59−
60−}
61−
62−extension String: JSONDecodable {
63−
64− /// An initializer to create an instance of `String` from a `JSON` value.
65− /// - parameter json: An instance of `JSON`.
66− /// - throws: The initializer will throw an instance of `JSON.Error` if
67− /// an instance of `String` cannot be created from the `JSON` value that was
68− /// passed to this initializer.
69− public init(json: JSON) throws {
70− guard case let .String(string) = json else {
71− throw JSON.Error.ValueNotConvertible(value: json, to: Swift.String)
72− }
73− self = string
74− }
75−
76−}
77−
78−extension Bool: JSONDecodable {
79−
80− /// An initializer to create an instance of `Bool` from a `JSON` value.
81− /// - parameter json: An instance of `JSON`.
82− /// - throws: The initializer will throw an instance of `JSON.Error` if
83− /// an instance of `Bool` cannot be created from the `JSON` value that was
84− /// passed to this initializer.
85− public init(json: JSON) throws {
86− guard case let .Bool(bool) = json else {
87− throw JSON.Error.ValueNotConvertible(value: json, to: Swift.Bool)
88− }
89− self = bool
90− }
91−
92−}
93−
94−extension RawRepresentable where RawValue: JSONDecodable {
95−
96− /// An initializer to create an instance of `RawRepresentable` from a `JSON` value.
97− /// - parameter json: An instance of `JSON`.
98− /// - throws: The initializer will throw an instance of `JSON.Error` if
99− /// an instance of `RawRepresentable` cannot be created from the `JSON` value that was
100− /// passed to this initializer.
101− public init(json: JSON) throws {
102− let raw = try json.decode(type: RawValue.self)
103− guard let value = Self(rawValue: raw) else {
104− throw JSON.Error.ValueNotConvertible(value: json, to: Self.self)
105− }
106− self = value
107− }
108−}
109−
110−internal extension JSON {
111−
112− /// Retrieves a `[JSON]` from the JSON.
113− /// - returns: An `Array` of `JSON` elements
114− /// - throws: Any of the `JSON.Error` cases thrown by `decode(type:)`.
115− /// - seealso: `JSON.decode(_:type:)`
116− static func getArray(json: JSON) throws -> [JSON] {
117− // Ideally should be expressed as a conditional protocol implementation on Swift.Array.
118− guard case let .Array(array) = json else {
119− throw Error.ValueNotConvertible(value: json, to: Swift.Array<JSON>)
120− }
121− return array
122− }
123−
124− /// Retrieves a `[String: JSON]` from the JSON.
125− /// - returns: An `Dictionary` of `String` mapping to `JSON` elements
126− /// - throws: Any of the `JSON.Error` cases thrown by `decode(type:)`.
127− /// - seealso: `JSON.decode(_:type:)`
128− static func getDictionary(json: JSON) throws -> [Swift.String: JSON] {
129− // Ideally should be expressed as a conditional protocol implementation on Swift.Dictionary.
130− guard case let .Dictionary(dictionary) = json else {
131− throw Error.ValueNotConvertible(value: json, to: Swift.Dictionary<Swift.String, JSON>)
132− }
133− return dictionary
134− }
135−
136− /// Attempts to decode many values from a descendant JSON array at a path
137− /// into JSON.
138− /// - parameter type: If the context this method is called from does not
139− /// make the return type clear, pass a type implementing `JSONDecodable`
140− /// to disambiguate the type to decode with.
141− /// - returns: An `Array` of decoded elements
142− /// - throws: Any of the `JSON.Error` cases thrown by `decode(type:)`, as
143− /// well as any error that arises from decoding the contained values.
144− /// - seealso: `JSON.decode(_:type:)`
145− static func getArrayOf<Decoded: JSONDecodable>(json: JSON) throws -> [Decoded] {
146− // Ideally should be expressed as a conditional protocol implementation on Swift.Dictionary.
147− // This implementation also doesn't do the `type = Type.self` trick.
148− return try getArray(json).map(Decoded.init)
149− }
150−
151−}
tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONEncodable.swiftdeleted−83
@@ -1,83 +0,0 @@
1−//
2−// JSONEncodable.swift
3−// Freddy
4−//
5−// Created by Matthew Mathias on 1/4/16.
6−// Copyright © 2016 Big Nerd Ranch. All rights reserved.
7−//
8−
9−import Foundation
10−
11−/// A protocol to facilitate encoding and decoding of `JSON`.
12−public protocol JSONEncodable {
13− /// Converts an instance of a conforming type to `JSON`.
14− /// - returns: An instance of `JSON`.
15− /// - Note: If conforming to `JSONEncodable` with a custom type of your own, you should return an instance of
16− /// `JSON.Dictionary`.
17− func toJSON() -> JSON
18−}
19−
20−extension Array where Element: JSONEncodable {
21− /// Converts an instance of `Array` whose elements conform to `JSONEncodable` to `JSON`.
22− /// - returns: An instance of `JSON` where the enum case is `.Array`.
23− public func toJSON() -> JSON {
24− let arrayOfJSON = self.map { $0.toJSON() }
25− return .Array(arrayOfJSON)
26− }
27−}
28−
29−extension Dictionary where Value: JSONEncodable {
30− /// Converts an instance of `Dictionary` whose values conform to `JSONEncodable` to `JSON`. The keys in the resulting
31− /// `JSON.Dictionary` will be of type `String`.
32− /// - returns: An instance of `JSON` where the enum case is `.Dictionary`.
33− public func toJSON() -> JSON {
34− var jsonDictionary = [String: JSON]()
35−
36− for (k, v) in self {
37− let key = String(k)
38− jsonDictionary[key] = v.toJSON()
39− }
40−
41− return .Dictionary(jsonDictionary)
42− }
43−}
44−
45−extension Int: JSONEncodable {
46− /// Converts an instance of a conforming type to `JSON`.
47− /// - returns: An instance of `JSON` where the enum case is `.Int`.
48− public func toJSON() -> JSON {
49− return .Int(self)
50− }
51−}
52−
53−extension Double: JSONEncodable {
54− /// Converts an instance of a conforming type to `JSON`.
55− /// - returns: An instance of `JSON` where the enum case is `.Double`.
56− public func toJSON() -> JSON {
57− return .Double(self)
58− }
59−}
60−
61−extension String: JSONEncodable {
62− /// Converts an instance of a conforming type to `JSON`.
63− /// - returns: An instance of `JSON` where the enum case is `.String`.
64− public func toJSON() -> JSON {
65− return .String(self)
66− }
67−}
68−
69−extension Bool: JSONEncodable {
70− /// Converts an instance of a conforming type to `JSON`.
71− /// - returns: An instance of `JSON` where the enum case is `.Bool`.
72− public func toJSON() -> JSON {
73− return .Bool(self)
74− }
75−}
76−
77−extension RawRepresentable where RawValue: JSONEncodable {
78− /// Converts an instance of a conforming type to `JSON`.
79− /// - returns: An instance of `JSON` where the enum case is whatever the underlying `RawValue` converts to.
80− public func toJSON() -> JSON {
81− return rawValue.toJSON()
82− }
83−}
tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONEncodingDetector.swiftdeleted−110
@@ -1,110 +0,0 @@
1−//
2−// JSONEncodingDetector.swift
3−// Freddy
4−//
5−// Created by Robert Edwards on 1/27/16.
6−// Copyright © 2016 Big Nerd Ranch. All rights reserved.
7−//
8−
9−/// Struct for attempting to detect the Unicode encoding used with the data supplied to the JSONParser
10−public struct JSONEncodingDetector {
11−
12− //// The Unicode encodings looked for during detection
13− public enum Encoding {
14− //// UTF-8
15− case UTF8
16− //// UTF-16 Little Endian
17− case UTF16LE
18− //// UTF-16 Big Endian
19− case UTF16BE
20− //// UTF-32 Little Endian
21− case UTF32LE
22− //// UTF-32 Big Endian
23− case UTF32BE
24− }
25−
26− //// The Unicode encodings supported by JSONParser.swift
27− public static let supportedEncodings: [Encoding] = [.UTF8]
28−
29− typealias ByteStreamPrefixInformation = (encoding: Encoding, byteOrderMarkLength: Int)
30−
31− //// Attempts to detect the Unicode encoding used for a given set of data.
32− ////
33− //// This function initially looks for a Byte Order Mark in the following form:
34− ////
35− //// Bytes | Encoding Form
36− //// --------------|----------------
37− //// 00 00 FE FF | UTF-32, big-endian
38− //// FF FE 00 00 | UTF-32, little-endian
39− //// FE FF | UTF-16, big-endian
40− //// FF FE | UTF-16, little-endian
41− //// EF BB BF | UTF-8
42− ////
43− //// If a BOM is not found then we detect using the following approach described in
44− //// the JSON RFC http://www.ietf.org/rfc/rfc4627.txt:
45− ////
46− //// Since the first two characters of a JSON text will always be ASCII
47− //// characters [RFC0020], it is possible to determine whether an octet
48− //// stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
49− //// at the pattern of nulls in the first four octets.
50− ////
51− //// 00 00 00 xx UTF-32BE
52− //// 00 xx 00 xx UTF-16BE
53− //// xx 00 00 00 UTF-32LE
54− //// xx 00 xx 00 UTF-16LE
55− //// xx xx xx xx UTF-8
56− ////
57− //// - parameter header: The front Slice of data being read and evaluated.
58− //// - returns: A tuple containing the detected Unicode encoding and the lenght of the byte order mark.
59− static func detectEncoding(header: Slice<UnsafeBufferPointer<UInt8>>) -> ByteStreamPrefixInformation {
60−
61− guard let prefix = prefixFromHeader(header) else {
62− return (.UTF8, 0)
63− }
64−
65− if let prefixInfo = JSONEncodingDetector.encodingFromBOM(prefix) {
66− return prefixInfo
67− } else {
68− switch prefix {
69− case(0, 0, 0?, _):
70− return (.UTF32BE, 0)
71− case(_, 0, 0?, 0?):
72− return (.UTF32LE, 0)
73− case (0, _, 0?, _), (0, _, _, _):
74− return (.UTF16BE, 0)
75− case (_, 0, _, 0?), (_, 0, _, _):
76− return (.UTF16LE, 0)
77− default:
78− return (.UTF8, 0)
79− }
80− }
81− }
82−
83− private typealias EncodingBytePrefix = (UInt8, UInt8, UInt8?, UInt8?)
84−
85− private static func prefixFromHeader(header: Slice<UnsafeBufferPointer<UInt8>>) -> EncodingBytePrefix? {
86− if header.count >= 4 {
87− return(header[0], header[1], header[2], header[3])
88− } else if header.count >= 2 {
89− return (header[0], header[1], nil, nil)
90− }
91− return nil
92− }
93−
94− private static func encodingFromBOM(prefix: EncodingBytePrefix) -> ByteStreamPrefixInformation? {
95− switch prefix {
96− case(0xFE, 0xFF, _, _):
97− return (.UTF16BE, 2)
98− case(0x00, 0x00, 0xFE?, 0xFF?):
99− return (.UTF32BE, 4)
100− case(0xEF, 0xBB, 0xBF?, _):
101− return (.UTF8, 3)
102− case(0xFF, 0xFE, 0?, 0?):
103− return (.UTF32LE, 4)
104− case(0xFF, 0xFE, _, _):
105− return (.UTF16LE, 2)
106− default:
107− return nil
108− }
109− }
110−}
tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONLiteralConvertible.swiftdeleted−130
@@ -1,130 +0,0 @@
1−//
2−// JSONLiteralConvertible.swift
3−// Freddy
4−//
5−// Created by Zachary Waldowski on 5/11/15.
6−// Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
7−//
8−
9−// MARK: - ArrayLiteralConvertible
10−
11−extension JSON: ArrayLiteralConvertible {
12−
13− /// Create an instance by copying each element of the `collection` into a
14− /// new `Array`.
15− public init<Collection: CollectionType where Collection.Generator.Element == JSON>(_ collection: Collection) {
16− self = .Array(Swift.Array(collection))
17− }
18−
19− /// Create an instance initialized with `elements`.
20− public init(arrayLiteral elements: JSON...) {
21− self.init(elements)
22− }
23−
24−}
25−
26−// MARK: - DictionaryLiteralConvertible
27−
28−extension JSON: DictionaryLiteralConvertible {
29−
30− /// Create an instance by copying each key/value pair of the `pairs` into
31− /// a new `Dictionary`.
32− public init<Dictionary: SequenceType where Dictionary.Generator.Element == (Swift.String, JSON)>(_ pairs: Dictionary) {
33− var dictionary = Swift.Dictionary<Swift.String, JSON>(minimumCapacity: pairs.underestimateCount())
34− for (key, value) in pairs {
35− dictionary[key] = value
36− }
37− self = .Dictionary(dictionary)
38− }
39−
40− /// Create an instance initialized with `pairs`.
41− public init(dictionaryLiteral pairs: (Swift.String, JSON)...) {
42− self.init(pairs)
43− }
44−
45−}
46−
47−// MARK: - FloatLiteralConvertible
48−
49−extension JSON: FloatLiteralConvertible {
50−
51− /// Create an instance initialized to `Double` `value`.
52− public init(_ value: Swift.Double) {
53− self = .Double(value)
54− }
55−
56− /// Create a literal instance initialized to `value`.
57− public init(floatLiteral value: Swift.Double) {
58− self.init(value)
59− }
60−
61−}
62−
63−// MARK: - IntegerLiteralConvertible
64−
65−extension JSON: IntegerLiteralConvertible {
66−
67− /// Create an instance initialized to `Int` by `value`.
68− public init(_ value: Swift.Int) {
69− self = .Int(value)
70− }
71−
72− /// Create a literal instance initialized to `value`.
73− public init(integerLiteral value: Swift.Int) {
74− self.init(value)
75− }
76−
77−}
78−
79−// MARK: - StringLiteralConvertible
80−
81−extension JSON: StringLiteralConvertible {
82−
83− /// Create an instance initialized to `String` by `text`.
84− public init(_ text: Swift.String) {
85− self = .String(text)
86− }
87−
88− /// Create a literal instance initialized to `value`.
89− public init(stringLiteral value: StringLiteralType) {
90− self.init(value)
91− }
92−
93− /// Create a literal instance initialized to `value`.
94− public init(extendedGraphemeClusterLiteral value: StringLiteralType) {
95− self.init(value)
96− }
97−
98− /// Create a literal instance initialized to `value`.
99− public init(unicodeScalarLiteral value: StringLiteralType) {
100− self.init(value)
101− }
102−
103−}
104−
105−// MARK: - BooleanLiteralConvertible
106−
107−extension JSON: BooleanLiteralConvertible {
108−
109− /// Create an instance initialized to `Bool` by `value`.
110− public init(_ value: Swift.Bool) {
111− self = .Bool(value)
112− }
113−
114− /// Create a literal instance initialized to `value`.
115− public init(booleanLiteral value: Swift.Bool) {
116− self.init(value)
117− }
118−
119−}
120−
121−// MARK: - NilLiteralConvertible
122−
123−extension JSON: NilLiteralConvertible {
124−
125− /// Create an instance initialized with `nil`.
126− public init(nilLiteral: ()) {
127− self = .Null
128− }
129−
130−}
tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONParser.swiftdeleted−903

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONParsing.swiftdeleted−126

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONSerializing.swiftdeleted−43

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/JSONSubscripting.swiftdeleted−643

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Freddy_2_1_0/test_Freddy/main.swiftdeleted−37

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_JSONKit/JSONKit.hdeleted−251

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_JSONKit/JSONKit.mdeleted−3065

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_JSONKit/bin/test-JSONKitdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit.xcodeproj/project.pbxprojdeleted−252

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test-JSONKit.xcschemedeleted−91

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_JSONKit/test-JSONKit/main.mdeleted−73

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Json.NET/Program.csdeleted−46

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/Newtonsoft.Json.dlldeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/System.Runtime.Serialization.Primitives.dlldeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/test_Json.NET.deps.jsondeleted−49

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/test_Json.NET.dlldeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/test_Json.NET.pdbdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Json.NET/bin/Release/netcoreapp1.0/publish/test_Json.NET.runtimeconfig.jsondeleted−8

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Json.NET/project.jsondeleted−21

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Json.NET/project.lock.jsondeleted−6741

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Lua_JSON/JSON.luadeleted−1451

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Lua_JSON/test_JSON.luadeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/bin/test_ObjCNSJSONSerializerdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer.xcodeproj/project.pbxprojdeleted−246

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_ObjCNSJSONSerializer.xcschemedeleted−97

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer/a.outdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer/a.out.dSYM/Contents/Info.plistdeleted−20

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer/a.out.dSYM/Contents/Resources/DWARF/a.outdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer/findings_dir/plot_datadeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ObjCNSJSONSerializer/test_ObjCNSJSONSerializer/main.mdeleted−32

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/Accessors.swiftdeleted−255

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/DecimalNumber.swiftdeleted−236

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/Decoder.swiftdeleted−294

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/Encoder.swiftdeleted−167

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/JSON.swiftdeleted−170

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/JSONError.swiftdeleted−1619

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/JSONObject.swiftdeleted−215

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/ObjectiveC.swiftdeleted−233

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/Parser.swiftdeleted−674

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/bin/test_PMJSONdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON.xcodeproj/project.pbxprojdeleted−296

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_PMJSON.xcschemedeleted−97

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_1_0/test_PMJSON/main.swiftdeleted−46

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/Accessors.swiftdeleted−255

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/DecimalNumber.swiftdeleted−236

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/Decoder.swiftdeleted−502

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/Encoder.swiftdeleted−215

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/JSON.swiftdeleted−170

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/JSONError.swiftdeleted−1619

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/JSONObject.swiftdeleted−215

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/ObjectiveC.swiftdeleted−331

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/Parser.swiftdeleted−745

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/bin/test_PMJSONdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON.xcodeproj/project.pbxprojdeleted−296

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_PMJSON.xcschemedeleted−97

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_PMJSON_1_2_0/test_PMJSON/main.swiftdeleted−46

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4.hdeleted−35

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4Parser.hdeleted−248

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4Parser.mdeleted−287

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamParser.hdeleted−131

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamParser.mdeleted−317

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamParserState.hdeleted−82

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamParserState.mdeleted−355

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamTokeniser.hdeleted−40

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamTokeniser.mdeleted−395

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamWriter.hdeleted−210

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamWriter.mdeleted−358

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamWriterState.hdeleted−69

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4StreamWriterState.mdeleted−147

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4Writer.hdeleted−103

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/SBJson4Writer.mdeleted−102

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/bin/test_SBJSONdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/project.pbxprojdeleted−290

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlistdeleted−5

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_SBJSON.xcschemedeleted−91

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_SBJSON/test_SBJSON/main.mdeleted−38

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/project.pbxprojdeleted−361

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/project.xcworkspace/xcshareddata/STJSON.xcscmblueprintdeleted−30

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/STJSON.xcschemedeleted−91

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/STJSONTests.xcschemedeleted−56

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_STJSON/STJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−32

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_STJSON/STJSON/STJSONParser.swiftdeleted−663

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_STJSON/STJSON/main.swiftdeleted−47

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_STJSON/STJSONTests/Info.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_STJSON/STJSONTests/STJSONTests.swiftdeleted−92

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_STJSON/bin/STJSONdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Info.plistdeleted−563

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/MacOS/Squeakdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/English.lproj/Localizable.stringsdeleted−9

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/English.lproj/MainMenu.nibdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/Squeak.icnsdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakChanges.icnsdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakGeneric.icnsdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakImage.icnsdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakPlugin.icnsdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakProject.icnsdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakScript.icnsdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak.app/Contents/Resources/SqueakSources.icnsdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/Squeak5.1-16549-32bit.imagedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_Squeak_JSON_tonyg/test_JSON.stdeleted−9

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_TouchJSON/bin/test_TouchJSONdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON.xcodeproj/project.pbxprojdeleted−262

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_TouchJSON.xcschemedeleted−97

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON/CJSONDeserializer.hdeleted−96

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON/CJSONDeserializer.mdeleted−1240

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_TouchJSON/test_TouchJSON/main.mdeleted−25

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_cJSON/bin/test-cJSONdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_cJSON/cJSON.cdeleted−754

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_cJSON/cJSON.hdeleted−153

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/project.pbxprojdeleted−257

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlistdeleted−5

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test-cJSON.xcschemedeleted−91

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_cJSON/test-cJSON.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_cJSON/test-cJSON/main.cdeleted−69

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/bin/test_ccandeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/common.hdeleted−18

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_10.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_101.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_11.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_12.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_125.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_127.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_13.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_136.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_137.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_139.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_14.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_140.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_145.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_147.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_149.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_15.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_150.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_151.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_153.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_154.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_155.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_156.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_157.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_158.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_159.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_16.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_160.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_161.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_162.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_163.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_164.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_165.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_169.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_17.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_171.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_172.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_173.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_175.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_176.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_177.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_178.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_179.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_18.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_180.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_181.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_183.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_184.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_185.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_186.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_187.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_188.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_189.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_19.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_190.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_191.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_192.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_193.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_194.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_195.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_197.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_198.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_199.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_2.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_20.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_200.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_201.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_202.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_203.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_204.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_205.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_206.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_207.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_208.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_209.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_21.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_210.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_211.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_212.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_213.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_214.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_216.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_217.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_218.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_219.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_22.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_220.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_221.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_222.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_223.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_23.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_24.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_25.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_26.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_27.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_28.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_29.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_3.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_30.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_31.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_32.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_33.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_34.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_35.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_36.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_37.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_4.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_40.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_44.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_46.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_5.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_54.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_55.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_59.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_6.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_63.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_64.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_66.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_69.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_7.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_77.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_78.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_79.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_8.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_80.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_81.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_82.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_83.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_85.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_86.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_87.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_9.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/n_91.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_100.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_102.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_103.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_104.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_105.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_106.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_107.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_108.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_109.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_110.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_111.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_112.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_113.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_114.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_115.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_116.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_117.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_118.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_119.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_120.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_121.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_122.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_123.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_124.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_126.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_128.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_129.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_130.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_131.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_132.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_133.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_134.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_135.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_138.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_141.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_142.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_143.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_144.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_146.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_148.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_152.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_166.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_167.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_168.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_170.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_174.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_182.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_196.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_215.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_38.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_39.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_41.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_42.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_43.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_45.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_47.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_48.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_49.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_50.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_51.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_52.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_53.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_56.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_57.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_58.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_60.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_61.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_62.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_65.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_67.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_68.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_70.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_71.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_72.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_73.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_74.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_75.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_76.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_84.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_88.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_89.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_90.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_92.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_93.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_94.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_95.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_96.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_97.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_98.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/nst_files/y_99.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/run-construction.cdeleted−191

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/run-decode-encode.cdeleted−77

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/run-stringify.cdeleted−108

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/run-validate.cdeleted−49

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/test-stringsdeleted−224

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/test-strings-reencodeddeleted−90

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/_test/x.pydeleted−21

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/json.cdeleted−1381

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/json/json.hdeleted−117

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan.xcodeproj/project.pbxprojdeleted−262

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_ccan.xcschemedeleted−91

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_ccan_json/test_ccan/test_ccan/main.cdeleted−44

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_dkjson.luadeleted−25

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_go/test_jsondeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_go/test_json.godeleted−30

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_haskell-aeson/.gitignoredeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_haskell-aeson/package.yamldeleted−12

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_haskell-aeson/src/Main.hsdeleted−29

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_haskell-aeson/stack.yamldeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_haskell-aeson/testaesondeleted−8

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_haskell-aeson/testaeson.cabaldeleted−21

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/bin/test_janssondeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_jansson/dump.cdeleted−467

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/error.cdeleted−63

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/hashtable.cdeleted−356

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/hashtable.hdeleted−184

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/hashtable_seed.cdeleted−277

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/jansson.hdeleted−298

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/jansson_config.hdeleted−43

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/jansson_private.hdeleted−109

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/load.cdeleted−1110

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/lookup3.hdeleted−381

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/memory.cdeleted−69

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/pack_unpack.cdeleted−871

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/strbuffer.cdeleted−111

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/strbuffer.hdeleted−34

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/strconv.cdeleted−145

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/project.pbxprojdeleted−309

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlistdeleted−5

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_jansson.xcschemedeleted−91

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/test_jansson.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/test_jansson/main.cdeleted−208

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/utf.cdeleted−187

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/utf.hdeleted−27

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jansson/value.cdeleted−1048

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/META-INF/MANIFEST.MFdeleted−3

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/README.txtdeleted−5

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/TestJSONParsing.classdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/TestJSONParsing.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/TestJSONParsing.javadeleted−40

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_com_leastfixedpoint_json_1_0/com.leastfixedpoint.json-1.0.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_gson_2_7/META-INF/MANIFEST.MFdeleted−3

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_gson_2_7/README.txtdeleted−5

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_gson_2_7/TestJSONParsing.classdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_gson_2_7/TestJSONParsing.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_gson_2_7/TestJSONParsing.javadeleted−51

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_gson_2_7/gson-2.7.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/META-INF/MANIFEST.MFdeleted−3

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/README.txtdeleted−5

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/TestJSONParsing.classdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/TestJSONParsing.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/TestJSONParsing.javadeleted−48

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/jackson-annotations-2.2.3.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/jackson-core-2.8.4.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_jackson_2_8_4/jackson-databind-2.3.1.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_nanojson_1_0/META-INF/MANIFEST.MFdeleted−3

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_nanojson_1_0/README.txtdeleted−5

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_nanojson_1_0/TestJSONParsing.classdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_nanojson_1_0/TestJSONParsing.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_nanojson_1_0/TestJSONParsing.javadeleted−45

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_nanojson_1_0/nanojson-1.0.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/META-INF/MANIFEST.MFdeleted−3

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/README.txtdeleted−3

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/TestJSONParsing.classdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/TestJSONParsing.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/TestJSONParsing.javadeleted−43

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_java_simple_json_1_1_1/json-simple-1.1.1.jardeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_jsmn/bin/test_jsmndeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_jsmn/jsmn.cdeleted−311

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsmn/jsmn.hdeleted−76

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/project.pbxprojdeleted−253

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlistdeleted−23

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_jsmn.xcschemedeleted−101

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsmn/test_jsmn/test_jsmn/main.cdeleted−50

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-jq.pydeleted−34

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-parser/bin/test_json-parserdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-parser/test_json-parser.xcodeproj/project.pbxprojdeleted−258

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-parser/test_json-parser.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-parser/test_json-parser.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-parser/test_json-parser.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/test_json-parser.xcschemedeleted−91

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-parser/test_json-parser.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-parser/test_json-parser/json.cdeleted−1011

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-parser/test_json-parser/json.hdeleted−283

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-parser/test_json-parser/main.cdeleted−66

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust-serde_json/rj/.gitignoredeleted−2

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust-serde_json/rj/Cargo.tomldeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust-serde_json/rj/READMEdeleted−2

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust-serde_json/rj/src/main.rsdeleted−30

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/Cargo.lockdeleted−14

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/Cargo.tomldeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/READMEdeleted−2

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/src/main.rsdeleted−42

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.cargo-lockdeleted

No changes to the content.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/json-74a82b4ec4439e90/dep-lib-jsondeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/json-74a82b4ec4439e90/lib-jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/json-74a82b4ec4439e90/lib-json.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-b5d63a9d8da2968e/bin-tjdeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-b5d63a9d8da2968e/bin-tj.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-b5d63a9d8da2968e/dep-bin-tjdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bb890ae6f101bb25/bin-tjdeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bb890ae6f101bb25/bin-tj.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bb890ae6f101bb25/dep-bin-tjdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bf24d0bdc8d0f4d6/bin-tjdeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bf24d0bdc8d0f4d6/bin-tj.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/.fingerprint/tj-bf24d0bdc8d0f4d6/dep-bin-tjdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/deps/libjson-6bbf4c11dd6d7c25.rlibdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/tjdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/tj.dSYM/Contents/Info.plistdeleted−20

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rust/target/debug/tj.dSYM/Contents/Resources/DWARF/tjdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/Cargo.lockdeleted−14

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/Cargo.tomldeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/READMEdeleted−2

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/src/main.rsdeleted−32

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.cargo-lockdeleted

No changes to the content.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-8f8b750d20f3bf10/bin-rjdeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-8f8b750d20f3bf10/bin-rj.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-8f8b750d20f3bf10/dep-bin-rjdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-da0f8f63b87cf531/bin-rjdeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-da0f8f63b87cf531/bin-rj.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rj-da0f8f63b87cf531/dep-bin-rjdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rustc-serialize-80c565222c5ccdbb/dep-lib-rustc-serializedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rustc-serialize-80c565222c5ccdbb/lib-rustc-serializedeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/.fingerprint/rustc-serialize-80c565222c5ccdbb/lib-rustc-serialize.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/deps/librustc_serialize-3561541d79c18212.rlibdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/rjdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/rj.dSYM/Contents/Info.plistdeleted−20

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json-rustc_serialize/rj/target/debug/rj.dSYM/Contents/Resources/DWARF/rjdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_json.crdeleted−19

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json.jsdeleted−13

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json.phpdeleted−21

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json.pldeleted−32

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json.pydeleted−39

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json.rbdeleted−23

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker/bin/jsonCheckerdeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/JSON_checker.cdeleted−400

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/JSON_checker.hdeleted−13

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker.xcodeproj/project.pbxprojdeleted−253

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/jsonChecker.xcschemedeleted−91

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker/jsonChecker/jsonChecker/main.cdeleted−53

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker2/FSM.rtfdeleted−103

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker2/bin/jsonChecker2deleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/JSON_checker.cdeleted−402

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/JSON_checker.hdeleted−13

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker/main.cdeleted−53

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker2.xcodeproj/project.pbxprojdeleted−253

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker2.xcodeproj/project.xcworkspace/contents.xcworkspacedatadeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker2.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstatedeleted

Binary file not shown.

tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker2.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/jsonChecker.xcschemedeleted−97

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonChecker2/jsonChecker2/jsonChecker2.xcodeproj/xcuserdata/nst.xcuserdatad/xcschemes/xcschememanagement.plistdeleted−22

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json_re.rbdeleted−33

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_json_xs.pldeleted−28

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_jsonlite.rdeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_oj_compat.rbdeleted−25

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_oj_strict.rbdeleted−25

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_qt/build.shdeleted−4

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_qt/main.cppdeleted−25

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_qt/test_qt.prodeleted−12

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_rjson.rdeleted−7

This diff is too big to show here.

tests/JSONTestSuite/parsers/test_yajl.rbdeleted−24

This diff is too big to show here.

tests/JSONTestSuite/results/logs.txtdeleted−2048

This diff is too big to show here.

tests/JSONTestSuite/results/parsing.htmldeleted−2816

This diff is too big to show here.

tests/JSONTestSuite/results/parsing_pruned.htmldeleted−2661

This diff is too big to show here.

tests/JSONTestSuite/results/pruned_results.pngdeleted

Binary file not shown.

tests/JSONTestSuite/results/style.cssdeleted−89

This diff is too big to show here.

tests/JSONTestSuite/results/transform.htmldeleted−1492

This diff is too big to show here.

tests/JSONTestSuite/run_tests.pydeleted−673

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_object_key_lone_2nd_surrogate.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_1st_surrogate_but_2nd_missing.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_1st_valid_surrogate_2nd_invalid.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_UTF-16LE_with_BOM.jsondeleted

Binary file not shown.

tests/JSONTestSuite/test_parsing/i_string_UTF-8_invalid_sequence.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_and_escape_valid.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_pair.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_incomplete_surrogates_escape_valid.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_invalid_lonely_surrogate.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_invalid_surrogate.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_inverted_surrogates_U+1D11E.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_lone_second_surrogate.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_not_in_unicode_range.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_truncated-utf-8.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_unicode_U+10FFFE_nonchar.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_unicode_U+1FFFE_nonchar.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_unicode_U+FDD0_nonchar.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_string_unicode_U+FFFE_nonchar.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_structure_500_nested_arrays.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/i_structure_UTF-8_BOM_empty_object.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_1_true_without_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_a_invalid_utf8.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_colon_instead_of_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_comma_after_close.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_comma_and_number.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_double_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_double_extra_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_extra_close.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_extra_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_incomplete.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_incomplete_invalid_value.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_inner_array_no_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_invalid_utf8.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_items_separated_by_semicolon.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_just_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_just_minus.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_missing_value.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_newlines_unclosed.jsondeleted−3

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_number_and_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_number_and_several_commas.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_spaces_vertical_tab_formfeed.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_star_inside.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_unclosed.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_unclosed_trailing_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_unclosed_with_new_lines.jsondeleted−3

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_array_unclosed_with_object_inside.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_incomplete_false.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_incomplete_null.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_incomplete_true.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_++.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_+1.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_+Inf.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_-01.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_-1.0..jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_-2..jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_-NaN.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_.-1.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_.2e-3.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_0.1.2.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_0.3e+.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_0.3e.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_0.e1.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_0_capital_E+.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_0_capital_E.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_0e+.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_0e.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_1.0e+.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_1.0e-.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_1.0e.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_1_000.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_1eE2.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_2.e+3.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_2.e-3.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_2.e3.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_9.e+.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_Inf.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_NaN.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_U+FF11_fullwidth_digit_one.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_expression.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_hex_1_digit.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_hex_2_digits.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_infinity.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_invalid+-.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_invalid-negative-real.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-bigger-int.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-exponent.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-int.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_minus_infinity.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_minus_sign_with_trailing_garbage.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_minus_space_1.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_neg_int_starting_with_zero.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_neg_real_without_int_part.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_neg_with_garbage_at_end.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_real_garbage_after_e.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_real_with_invalid_utf8_after_e.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_real_without_fractional_part.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_starting_with_dot.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_then_00.jsondeleted

Binary file not shown.

tests/JSONTestSuite/test_parsing/n_number_with_alpha.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_with_alpha_char.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_number_with_leading_zero.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_bad_value.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_bracket_key.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_comma_instead_of_colon.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_double_colon.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_emoji.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_garbage_at_end.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_key_with_single_quotes.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_missing_colon.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_missing_key.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_missing_semicolon.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_missing_value.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_no-colon.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_non_string_key.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_non_string_key_but_huge_number_instead.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_pi_in_key_and_trailing_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_repeated_null_null.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_several_trailing_commas.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_single_quote.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_trailing_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_trailing_comment.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_trailing_comment_open.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open_incomplete.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_two_commas_in_a_row.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_unquoted_key.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_unterminated-value.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_with_single_string.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_object_with_trailing_garbage.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_single_space.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u1.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u1x.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_UTF8_surrogate_U+D800.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_accentuated_char_no_quotes.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_backslash_00.jsondeleted

Binary file not shown.

tests/JSONTestSuite/test_parsing/n_string_escape_x.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_escaped_backslash_bad.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_escaped_ctrl_char_tab.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_escaped_emoji.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_incomplete_escape.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_incomplete_escaped_character.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_incomplete_surrogate.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_incomplete_surrogate_escape_invalid.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_invalid-utf-8-in-escape.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_invalid_backslash_esc.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_invalid_unicode_escape.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_invalid_utf-8.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_invalid_utf8_after_escape.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_iso_latin_1.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_leading_uescaped_thinspace.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_lone_utf8_continuation_byte.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_no_quotes_with_bad_escape.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_2_bytes.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_6_bytes.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_6_bytes_null.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_single_doublequote.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_single_quote.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_single_string_no_double_quotes.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_start_escape_unclosed.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_unescaped_crtl_char.jsondeleted

Binary file not shown.

tests/JSONTestSuite/test_parsing/n_string_unescaped_newline.jsondeleted−2

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_unescaped_tab.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_unicode_CapitalU.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_string_with_trailing_garbage.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_..jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_100000_opening_arrays.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_U+2060_word_joined.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_UTF8_BOM_no_data.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_array_trailing_garbage.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_array_with_extra_array_close.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_array_with_unclosed_string.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_ascii-unicode-identifier.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_capitalized_True.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_close_unopened_array.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_comma_instead_of_closing_brace.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_double_array.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_end_array.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_incomplete_UTF8_BOM.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_lone-invalid-utf-8.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_lone-open-bracket.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_no_data.jsondeleted

No changes to the content.

tests/JSONTestSuite/test_parsing/n_structure_null-byte-outside-string.jsondeleted

Binary file not shown.

tests/JSONTestSuite/test_parsing/n_structure_null.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_number_with_trailing_garbage.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_object_followed_by_closing_object.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_object_unclosed_no_value.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_object_with_comment.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_object_with_trailing_garbage.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_array_apostrophe.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_array_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_array_object.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_array_open_object.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_array_open_string.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_array_string.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_object.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_object_close_array.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_object_comma.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_object_open_array.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_object_open_string.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_object_string_with_apostrophes.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_open_open.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_single_point.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_single_star.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_trailing_#.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_uescaped_LF_before_string.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_unclosed_array.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_unclosed_array_partial_null.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_false.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_true.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_unclosed_object.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_unicode-identifier.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_whitespace_U+2060_word_joiner.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/n_structure_whitespace_formfeed.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_array_arraysWithSpaces.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_array_empty-string.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_array_empty.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_array_ending_with_newline.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_array_false.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_array_heterogeneous.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_array_null.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_array_with_1_and_newline.jsondeleted−2

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_array_with_leading_space.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_array_with_several_null.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_array_with_trailing_space.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_0e+1.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_0e1.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_after_space.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_double_close_to_zero.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_double_huge_neg_exp.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_huge_exp.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_int_with_exp.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_minus_zero.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_neg_int_huge_exp.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_negative_int.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_negative_one.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_negative_zero.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_pos_double_huge_exp.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_real_capital_e.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_real_capital_e_neg_exp.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_real_capital_e_pos_exp.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_real_exponent.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_real_fraction_exponent.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_real_neg_exp.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_real_neg_overflow.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_real_pos_exponent.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_real_pos_overflow.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_real_underflow.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_simple_int.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_simple_real.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_too_big_neg_int.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_too_big_pos_int.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_number_very_big_negative_int.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object_basic.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object_duplicated_key.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object_duplicated_key_and_value.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object_empty.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object_empty_key.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object_escaped_null_in_key.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object_extreme_numbers.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object_long_strings.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object_simple.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object_string_unicode.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_object_with_newlines.jsondeleted−3

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pair.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pairs.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_allowed_escapes.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_backslash_and_u_escaped_zero.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_backslash_doublequotes.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_comments.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_double_escape_a.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_double_escape_n.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_escaped_control_character.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_escaped_noncharacter.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_in_array.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_in_array_with_leading_space.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_last_surrogates_1_and_2.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_newline_uescaped.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_null_escape.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_one-byte-utf-8.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_pi.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_simple_ascii.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_space.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_three-byte-utf-8.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_two-byte-utf-8.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_u+2028_line_sep.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_u+2029_par_sep.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_uEscape.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_unescaped_char_delete.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_unicode.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_unicodeEscapedBackslash.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_unicode_2.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_unicode_U+2064_invisible_plus.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_unicode_escaped_double_quote.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_utf16BE_no_BOM.jsondeleted

Binary file not shown.

tests/JSONTestSuite/test_parsing/y_string_utf16LE_no_BOM.jsondeleted

Binary file not shown.

tests/JSONTestSuite/test_parsing/y_string_utf8.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_string_with_del_character.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_structure_lonely_false.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_structure_lonely_int.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_structure_lonely_negative_real.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_structure_lonely_null.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_structure_lonely_string.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_structure_lonely_true.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_structure_string_empty.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_structure_trailing_newline.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_structure_true_in_array.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_parsing/y_structure_whitespace_array.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/number_1.0.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/number_1.000000000000000005.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/number_1000000000000000.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/number_10000000000000000999.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/number_1e-999.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/number_1e6.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/object_key_nfc_nfd.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/object_key_nfd_nfc.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/object_same_key_different_values.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/object_same_key_same_value.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/object_same_key_unclear_values.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/string_1_escaped_invalid_codepoint.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/string_1_invalid_codepoint.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/string_2_escaped_invalid_codepoints.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/string_2_invalid_codepoints.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/string_3_escaped_invalid_codepoints.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/string_3_invalid_codepoints.jsondeleted−1

This diff is too big to show here.

tests/JSONTestSuite/test_transform/string_with_escaped_NULL.jsondeleted−1

This diff is too big to show here.

tests/Options.hs+2−26

This diff is too big to show here.

tests/PropUtils.hsdeleted−208

This diff is too big to show here.

tests/Properties.hs+444−17

This diff is too big to show here.

tests/PropertyGeneric.hsdeleted−116

This diff is too big to show here.

tests/PropertyKeys.hsdeleted−40

This diff is too big to show here.

tests/PropertyRTFunctors.hsdeleted−51

This diff is too big to show here.

tests/PropertyRoundTrip.hsdeleted−74

This diff is too big to show here.

tests/PropertyTH.hsdeleted−130

This diff is too big to show here.

tests/SerializationFormatSpec.hsdeleted−294

This diff is too big to show here.

tests/Tests.hs+3−5

This diff is too big to show here.

tests/Types.hs+5−70

This diff is too big to show here.

tests/UnitTests.hs+254−424

This diff is too big to show here.

tests/UnitTests/NullaryConstructors.hs+3−8

This diff is too big to show here.

tests/golden/generic.expecteddeleted−48

This diff is too big to show here.

tests/golden/simple.expecteddeleted−22

This diff is too big to show here.

travis/cabal_macros.hdeleted−448

This diff is too big to show here.

travis/install.sh−11

This diff is too big to show here.

travis/script.sh+1−8

This diff is too big to show here.