aeson 1.3.0.0 → 1.3.1.0
raw patch · 10 files changed
+64/−68 lines, 10 filesdep ~base-compatPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base-compat
API changes (from Hackage documentation)
Files
- Data/Aeson/Encoding/Builder.hs +1/−1
- Data/Aeson/Text.hs +1/−1
- Data/Aeson/Types/FromJSON.hs +23/−28
- Data/Aeson/Types/Generic.hs +0/−5
- Data/Aeson/Types/ToJSON.hs +17/−13
- README.markdown +1/−2
- aeson.cabal +2/−16
- benchmarks/aeson-benchmarks.cabal +1/−1
- changelog.md +6/−1
- tests/UnitTests.hs +12/−0
Data/Aeson/Encoding/Builder.hs view
@@ -44,7 +44,7 @@ import Data.ByteString.Builder.Prim as BP import Data.ByteString.Builder.Scientific (scientificBuilder) import Data.Char (chr, ord)-import Data.Monoid ((<>))+import Data.Semigroup ((<>)) import Data.Scientific (Scientific, base10Exponent, coefficient) import Data.Text.Encoding (encodeUtf8BuilderEscaped) import Data.Time (UTCTime(..))
Data/Aeson/Text.hs view
@@ -25,7 +25,7 @@ import Data.Aeson.Types (Value(..), ToJSON(..)) import Data.Aeson.Encoding (encodingToLazyByteString)-import Data.Monoid ((<>))+import Data.Semigroup ((<>)) import Data.Scientific (FPFormat(..), Scientific, base10Exponent) import Data.Text.Lazy.Builder import Data.Text.Lazy.Builder.Scientific (formatScientificBuilder)
Data/Aeson/Types/FromJSON.hs view
@@ -97,7 +97,7 @@ import Data.Int (Int16, Int32, Int64, Int8) import Data.List.NonEmpty (NonEmpty(..)) import Data.Maybe (fromMaybe)-import Data.Monoid ((<>))+import Data.Semigroup ((<>)) import Data.Proxy (Proxy(..)) import Data.Ratio ((%), Ratio) import Data.Scientific (Scientific)@@ -976,7 +976,7 @@ instance (FromRecord arity f) => FromTaggedObject'' arity f True where parseFromTaggedObject'' opts fargs _ =- Tagged . parseRecord opts fargs Nothing+ Tagged . parseRecord opts fargs instance (GFromJSON arity f) => FromTaggedObject'' arity f False where parseFromTaggedObject'' opts fargs contentsFieldName = Tagged .@@ -993,57 +993,52 @@ class ConsFromJSON' arity f isRecord where consParseJSON' :: Options -> FromArgs arity a- -> Maybe Text -- ^ A dummy label- -- (Nothing to use proper label) -> Value -> Tagged isRecord (Parser (f a)) instance ( IsRecord f isRecord , ConsFromJSON' arity f isRecord ) => ConsFromJSON arity f where- consParseJSON opts fargs v = let- (v2,lab) = case (unwrapUnaryRecords opts,isUnary (undefined :: f a)) of- -- use a dummy object with a dummy label- (True,True) -> (object [(pack "dummy",v)], Just $ pack "dummy")- _ ->(v,Nothing)- in (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))- $ consParseJSON' opts fargs lab v2+ consParseJSON opts fargs =+ (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))+ . consParseJSON' opts fargs +instance OVERLAPPING_+ ( GFromJSON arity a, FromRecord arity (S1 s a)+ ) => ConsFromJSON' arity (S1 s a) True where+ consParseJSON' opts fargs+ | unwrapUnaryRecords opts = Tagged . gParseJSON opts fargs+ | otherwise = Tagged . withObject "unary record" (parseRecord opts fargs) -instance (FromRecord arity f) => ConsFromJSON' arity f True where- consParseJSON' opts fargs mlab = Tagged . withObject "record (:*:)"- (parseRecord opts fargs mlab)+instance FromRecord arity f => ConsFromJSON' arity f True where+ consParseJSON' opts fargs =+ Tagged . withObject "record (:*:)" (parseRecord opts fargs) -instance (GFromJSON arity f) => ConsFromJSON' arity f False where- consParseJSON' opts fargs _ = Tagged . gParseJSON opts fargs+instance GFromJSON arity f => ConsFromJSON' arity f False where+ consParseJSON' opts fargs = Tagged . gParseJSON opts fargs -------------------------------------------------------------------------------- class FromRecord arity f where parseRecord :: Options -> FromArgs arity a- -> Maybe Text -- ^ A dummy label- -- (Nothing to use proper label) -> Object -> Parser (f a) instance ( FromRecord arity a , FromRecord arity b ) => FromRecord arity (a :*: b) where- parseRecord opts fargs _ obj =- (:*:) <$> parseRecord opts fargs Nothing obj- <*> parseRecord opts fargs Nothing obj+ parseRecord opts fargs obj =+ (:*:) <$> parseRecord opts fargs obj+ <*> parseRecord opts fargs obj instance OVERLAPPABLE_ (Selector s, GFromJSON arity a) => FromRecord arity (S1 s a) where- parseRecord opts fargs lab =+ parseRecord opts fargs = (<?> Key label) . gParseJSON opts fargs <=< (.: label) where- label = fromMaybe defLabel lab- defLabel = pack . fieldLabelModifier opts $- selName (undefined :: t s a p)+ label = pack . fieldLabelModifier opts $ selName (undefined :: t s a p) instance INCOHERENT_ (Selector s, FromJSON a) => FromRecord arity (S1 s (K1 i (Maybe a))) where- parseRecord _ _ (Just lab) obj = M1 . K1 <$> obj .:? lab- parseRecord opts _ Nothing obj = M1 . K1 <$> obj .:? pack label+ parseRecord opts _ obj = M1 . K1 <$> obj .:? pack label where label = fieldLabelModifier opts $ selName (undefined :: t s (K1 i (Maybe a)) p)@@ -1051,7 +1046,7 @@ -- Parse an Option like a Maybe. instance INCOHERENT_ (Selector s, FromJSON a) => FromRecord arity (S1 s (K1 i (Semigroup.Option a))) where- parseRecord opts fargs lab obj = wrap <$> parseRecord opts fargs lab obj+ parseRecord opts fargs obj = wrap <$> parseRecord opts fargs obj where wrap :: S1 s (K1 i (Maybe a)) p -> S1 s (K1 i (Semigroup.Option a)) p wrap (M1 (K1 a)) = M1 (K1 (Semigroup.Option a))
Data/Aeson/Types/Generic.hs view
@@ -44,12 +44,8 @@ -------------------------------------------------------------------------------- class IsRecord (f :: * -> *) isRecord | f -> isRecord- where- isUnary :: f a -> Bool- isUnary = const True instance (IsRecord f isRecord) => IsRecord (f :*: g) isRecord- where isUnary = const False #if MIN_VERSION_base(4,9,0) instance OVERLAPPING_ IsRecord (M1 S ('MetaSel 'Nothing u ss ds) f) False #else@@ -61,7 +57,6 @@ instance IsRecord (Rec1 f) True instance IsRecord (f :.: g) True instance IsRecord U1 False- where isUnary = const False --------------------------------------------------------------------------------
Data/Aeson/Types/ToJSON.hs view
@@ -80,7 +80,7 @@ import Data.Int (Int16, Int32, Int64, Int8) import Data.List (intersperse) import Data.List.NonEmpty (NonEmpty(..))-import Data.Monoid ((<>))+import Data.Semigroup ((<>)) import Data.Proxy (Proxy(..)) import Data.Ratio (Ratio, denominator, numerator) import Data.Scientific (Scientific)@@ -860,7 +860,7 @@ ) => TaggedObject enc arity (C1 c a) where taggedObject opts targs tagFieldName contentsFieldName =- fromPairs . (tag <>) . contents+ fromPairs . mappend tag . contents where tag = tagFieldName `pair` (fromString (constructorTagModifier opts (conName (undefined :: t c a p)))@@ -956,7 +956,6 @@ class ConsToJSON' enc arity f isRecord where consToJSON' :: Options -> ToArgs enc arity a- -> Bool -- ^ Are we a record with one field? -> f a -> Tagged isRecord enc instance ( IsRecord f isRecord@@ -965,23 +964,28 @@ where consToJSON opts targs = (unTagged :: Tagged isRecord enc -> enc)- . consToJSON' opts targs (isUnary (undefined :: f a))+ . consToJSON' opts targs {-# INLINE consToJSON #-} -instance ( RecordToPairs enc pairs arity f+instance OVERLAPPING_+ ( RecordToPairs enc pairs arity (S1 s f) , FromPairs enc pairs , GToJSON enc arity f- ) => ConsToJSON' enc arity f True+ ) => ConsToJSON' enc arity (S1 s f) True where- consToJSON' opts targs isUn =- Tagged .- case (isUn, unwrapUnaryRecords opts) of- (True, True) -> gToJSON opts targs- _ -> fromPairs . recordToPairs opts targs+ consToJSON' opts targs+ | unwrapUnaryRecords opts = Tagged . gToJSON opts targs+ | otherwise = Tagged . fromPairs . recordToPairs opts targs {-# INLINE consToJSON' #-} +instance ( RecordToPairs enc pairs arity f+ , FromPairs enc pairs+ ) => ConsToJSON' enc arity f True+ where+ consToJSON' opts targs = Tagged . fromPairs . recordToPairs opts targs+ instance GToJSON enc arity f => ConsToJSON' enc arity f False where- consToJSON' opts targs _ = Tagged . gToJSON opts targs+ consToJSON' opts targs = Tagged . gToJSON opts targs {-# INLINE consToJSON' #-} --------------------------------------------------------------------------------@@ -999,7 +1003,7 @@ ) => RecordToPairs enc pairs arity (a :*: b) where recordToPairs opts (targs :: ToArgs enc arity p) (a :*: b) =- pairsOf a <> pairsOf b+ pairsOf a `mappend` pairsOf b where pairsOf :: (RecordToPairs enc pairs arity f) => f p -> pairs pairsOf = recordToPairs opts targs
README.markdown view
@@ -24,5 +24,4 @@ # Authors -This library is written and maintained by Bryan O'Sullivan,-<bos@serpentine.com>.+This library was originally written by Bryan O'Sullivan.
aeson.cabal view
@@ -1,5 +1,5 @@ name: aeson-version: 1.3.0.0+version: 1.3.1.0 license: BSD3 license-file: LICENSE category: Text, Web, JSON@@ -21,20 +21,6 @@ To get started, see the documentation for the @Data.Aeson@ module below. .- Parsing performance on a late 2013 MacBook Pro (2.6GHz Core i7),- running 64-bit GHC 7.10.1, for mostly-English tweets from Twitter's- JSON search API:- .- * 6.4 KB payloads, English: 7570 msg\/sec (47.6 MB\/sec)- .- * 14.6 KB payloads, Japanese: 3261 msg\/sec (46.6 MB\/sec)- .- Encoding performance on the same machine and data:- .- * 6.4 KB payloads, English: 22738 msg\/sec (142.9 MB\/sec)- .- * 14.6 KB payloads, Japanese: 15911 msg\/sec (227.4 MB\/sec)- . (A note on naming: in Greek mythology, Aeson was the father of Jason.) extra-source-files:@@ -116,7 +102,7 @@ build-depends: attoparsec >= 0.13.0.1, base >= 4.5 && < 5,- base-compat >= 0.9.1 && < 0.10,+ base-compat >= 0.9.1 && < 0.11, containers >= 0.4.2, deepseq >= 1.3 && < 1.5, dlist >= 0.6,
benchmarks/aeson-benchmarks.cabal view
@@ -30,7 +30,7 @@ build-depends: attoparsec >= 0.13.0.1, base == 4.*,- base-compat >= 0.9.1 && <0.10,+ base-compat >= 0.9.1 && <0.11, time-locale-compat >=0.1.1 && <0.2, containers, deepseq,
changelog.md view
@@ -1,6 +1,11 @@ For 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). -### 1.3.0.0+### 1.3.1.0++* Fix bug in generically derived `FromJSON` instances that are using `unwrapUnaryRecords`, thanks to Xia Li-yao+* Allow base-compat 0.10.*, thanks to Oleg Grenrus++## 1.3.0.0 Breaking changes: * `GKeyValue` has been renamed to `KeyValuePair`, thanks to Xia Li-yao
tests/UnitTests.hs view
@@ -99,6 +99,7 @@ , testCase "Show Options" showOptions , testGroup "SingleMaybeField" singleMaybeField , testCase "withEmbeddedJSON" withEmbeddedJSONTest+ , testCase "SingleFieldCon" singleFieldCon ] roundTripCamel :: String -> Assertion@@ -533,6 +534,17 @@ withEmbeddedJSONTest :: Assertion withEmbeddedJSONTest = assertEqual "Unquote embedded JSON" (Right $ EmbeddedJSONTest 1) (eitherDecode "{\"prop\":\"1\"}")++-- Regression test for https://github.com/bos/aeson/issues/627+newtype SingleFieldCon = SingleFieldCon Int deriving (Eq, Show, Generic)++instance FromJSON SingleFieldCon where+ parseJSON = genericParseJSON defaultOptions{unwrapUnaryRecords=True}+ -- This option should have no effect on this type++singleFieldCon :: Assertion+singleFieldCon =+ assertEqual "fromJSON" (Right (SingleFieldCon 0)) (eitherDecode "0") deriveJSON defaultOptions{omitNothingFields=True} ''MyRecord