aeson-value-parser 0.14.2 → 0.14.3
raw patch · 3 files changed
+53/−7 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Aeson.ValueParser: elementOr :: Int -> Value a -> Array a -> Array a
+ Aeson.ValueParser: oneOfPossibleFields :: [Text] -> Value a -> Object (Maybe a)
+ Aeson.ValueParser: possibleElement :: Int -> Value a -> Array (Maybe a)
+ Aeson.ValueParser: possibleField :: Text -> Value a -> Object (Maybe a)
Files
- aeson-value-parser.cabal +1/−1
- library/Aeson/ValueParser.hs +51/−5
- library/Aeson/ValueParser/Error.hs +1/−1
aeson-value-parser.cabal view
@@ -1,5 +1,5 @@ name: aeson-value-parser-version: 0.14.2+version: 0.14.3 synopsis: An API for parsing "aeson" JSON tree into Haskell types description: category: Data, JSON, Parsing
library/Aeson/ValueParser.hs view
@@ -22,11 +22,15 @@ oneOfFields, fieldOr, oneOfFieldsOr,+ possibleField,+ oneOfPossibleFields, fieldMap, foldlFields, -- * Array parsers Array, element,+ elementOr,+ possibleElement, elementVector, foldlElements, foldrElements,@@ -177,16 +181,42 @@ oneOfFields :: [Text] -> Value a -> Object a oneOfFields keys valueParser = asum (fmap (flip field valueParser) keys) -fieldOr :: Text -> Value a -> Object a -> Object a-fieldOr name parser alt =- join $ mplus- (field name (catchError (fmap pure parser) (pure . throwError . Error.named name)))- (pure alt)+{-| Applies the value parser to the existing field, propagating its errors accordingly.+ Only if the field does not exist, it executes /Alternative branch/.+ IOW, it won't execute /Alternative branch/ if /Field parser/ fails.+ This is what distinguishes @fieldOr name parser@ from the seemingly same @mplus (field name parser)@ -}+fieldOr :: Text {-^ Field name -} -> Value a {-^ Field parser -} -> Object a {-^ Alternative branch -} -> Object a+fieldOr name (Value fieldParser) alt = join $ Object $ ReaderT $ \ object -> except $ case HashMap.lookup name object of+ Just value -> case runExcept (runReaderT fieldParser value) of+ Right parsedValue -> Right (return parsedValue)+ Left error -> Left (Error.named name error)+ Nothing -> Right alt +{-| Same as `fieldOr`,+ with the only difference that it enumerates the provided list of field names+ parsing the first existing one. -} oneOfFieldsOr :: [Text] -> Value a -> Object a -> Object a oneOfFieldsOr names valueParser objectParser = foldr (\ name -> fieldOr name valueParser) objectParser names +{-| Applies the value parser to the existing field, propagating its errors accordingly, but+ unlike `field` it doesn't fail if the field does not exist.+ The `Maybe` wrapper is there to cover such a case. -}+{-# INLINE possibleField #-}+possibleField :: Text -> Value a -> Object (Maybe a)+possibleField key (Value effect) = Object $ ReaderT $ \ object -> except $ case HashMap.lookup key object of+ Just value -> case runExcept (runReaderT effect value) of+ Right parsedValue -> Right (Just parsedValue)+ Left error -> Left (Error.named key error)+ Nothing -> Right Nothing++{-| Same as `possibleField`,+ with the only difference that it enumerates the provided list of field names+ parsing the first existing one. -}+{-# INLINE oneOfPossibleFields #-}+oneOfPossibleFields :: [Text] -> Value a -> Object (Maybe a)+oneOfPossibleFields keys valueParser = oneOfFieldsOr keys (fmap Just valueParser) (pure Nothing)+ {-# INLINE fieldMap #-} fieldMap :: Value a -> Object (HashMap Text a) fieldMap fieldParser = Object $ ReaderT $ except . HashMap.traverseWithKey mapping where@@ -223,6 +253,22 @@ Right result -> Right result Left error -> Left (Error.indexed index error) Nothing -> Left (Error.Error (pure (fromString (show index))) "Array contains no element by this index")++{-# INLINE elementOr #-}+elementOr :: Int -> Value a -> Array a -> Array a+elementOr index elementParser alt = join $ Array $ ReaderT $ \ array -> except $ case array Vector.!? index of+ Just element -> case run elementParser element of+ Right result -> Right (return result)+ Left error -> Left (Error.indexed index error)+ Nothing -> Right alt++{-# INLINE possibleElement #-}+possibleElement :: Int -> Value a -> Array (Maybe a)+possibleElement index elementParser = Array $ ReaderT $ \ array -> except $ case array Vector.!? index of+ Just element -> case run elementParser element of+ Right result -> Right (Just result)+ Left error -> Left (Error.indexed index error)+ Nothing -> Right Nothing {-# INLINE elementVector #-} elementVector :: Value a -> Array (Vector a)
library/Aeson/ValueParser/Error.hs view
@@ -7,7 +7,7 @@ data Error = Error [Text] {-^ Path -} Text {-^ Message -} instance Semigroup Error where- (<>) a _ = a+ (<>) _ b = b instance Monoid Error where mempty = Error [] ""