packages feed

json-query 0.2.1.0 → 0.2.2.0

raw patch · 5 files changed

+69/−8 lines, 5 filesdep ~scientific-notationdep ~transformers

Dependency ranges changed: scientific-notation, transformers

Files

CHANGELOG.md view
@@ -1,5 +1,13 @@ # Revision history for json-query +## 0.2.2.0 -- 2023-08-09++* Add `Json.Errors.hPut` to make it less verbose to print+  parse errors.+* Add `Json.Parser.foldSmallArray`+* Add variant of `Json.Path.query` that returns Null when path is+  not found.+ ## 0.2.1.0 -- 2021-07-15  * Allow building with GHC 9.2.3
json-query.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: json-query-version: 0.2.1.0+version: 0.2.2.0 synopsis: Kitchen sink for querying JSON description:   The library complements json-syntax by making available several@@ -31,8 +31,8 @@     , bytestring >=0.10 && <0.12     , contiguous >=0.6.1     , json-syntax >=0.2.2 && <0.3-    , primitive >=0.7 && <0.8-    , primitive-unlifted >=0.1.3 && <0.2+    , primitive >=0.7 && <0.10+    , primitive-unlifted >=0.1.3 && <2.2     , profunctors >=5.6     , scientific-notation >=0.1.5 && <0.2     , text-short >=0.1.3 && <0.2
src/Json/Errors.hs view
@@ -10,18 +10,20 @@     -- * Encoding   , encode   , builderUtf8+  , hPut     -- * Create   , singleton     -- * Conversion   , toSmallArray   ) where +import Control.Monad.ST (runST)+import Data.ByteString.Short.Internal (ShortByteString(SBS)) import Data.Bytes.Builder (Builder) import Data.Primitive (SmallArray) import Data.Text.Short (ShortText)-import Data.ByteString.Short.Internal (ShortByteString(SBS))-import Control.Monad.ST (runST) import Json.Error (Error)+import System.IO (Handle)  import qualified Data.Bytes.Builder as Builder import qualified Data.Bytes.Chunks as ByteChunks@@ -48,6 +50,8 @@ singleton :: Error -> Errors singleton = ErrorsOne +-- | Convert errors to builder. The errors are separated by+-- a pair of characters: comma and space. builderUtf8 :: Errors -> Builder builderUtf8 errs =   let len = countErrors errs@@ -57,6 +61,20 @@       Arr.foldMap         (\e -> Builder.ascii2 ',' ' ' <> Error.builderUtf8 e)         (Arr.slice errArr 1 (len - 1))++-- | Print errors to the provided handle. Typically, @System.IO.stderr@+-- is provided as the handle. Each encoded error is suffixed with a newline.+--+-- This is a convenience function for the common case where, after a+-- failed parse, an application prints out all parse errors and then exits.+hPut :: Handle -> Errors -> IO ()+hPut h errs = do+  let len = countErrors errs+      errArr = makeErrorArray len errs+      bldr = Arr.foldMap+        (\e -> Error.builderUtf8 e <> Builder.ascii '\n')+        errArr+   in ByteChunks.hPut h (Builder.run 128 bldr)  -- | Convert errors to array. toSmallArray :: Errors -> SmallArray Error
src/Json/Parser.hs view
@@ -20,6 +20,7 @@   , members     -- * Arrays   , smallArray+  , foldSmallArray   , traverseMembers     -- * Specific Data Constructors   , object@@ -179,7 +180,7 @@     Nothing -> Left (Errors.singleton (Error{context=p',message="key not found: " <> name}))     Just Member{value} -> runParser (f value) p' --- | Variant of 'key' that supplies the JSON value @null to the+-- | Variant of 'key' that supplies the JSON value @null@ to the -- callback if the key is not found. Using this parser combinators implies -- that there is no distinction between @null@ and an absent value in -- the encoding scheme.@@ -215,6 +216,21 @@         pure (ix + 1)       ) 0 xs     lift (PM.unsafeFreezeSmallArray dst)++-- | Run the parser against every element in a 'SmallArray', updating an+-- accumulator at each step. Folds from left to right. This adjusts+-- the context at each element. Typically, type @a@ is @Value@.+foldSmallArray :: (b -> a -> Parser b) -> b -> SmallArray a -> Parser b+{-# inline foldSmallArray #-}+foldSmallArray f acc0 xs = Parser $ \ !p -> runST do+  -- TODO: make sure tuples get elided+  runExceptT $ do+    (!_,r) <- foldlM+      (\( !ix, !acc) x -> do+        !acc' <- ExceptT (pure (runParser (f acc x) (Index ix p)))+        pure (ix + 1, acc')+      ) (0,acc0) xs+    pure r  -- | Traverse the members. The adjusts the context at each member. traverseMembers :: (Member -> Parser a) -> SmallArray Member -> Parser (SmallArray a)
src/Json/Path.hs view
@@ -9,13 +9,14 @@   , builderUtf8     -- * Lookup   , query+  , query'     -- * Reverse   , reverse   ) where  import Prelude hiding (reverse) -import Json (Value(Object,Array),Member(Member))+import Json (Value(Object,Array,Null),Member(Member)) import Data.Primitive (ByteArray(ByteArray)) import Data.Text.Short (ShortText) import Data.Bytes.Builder (Builder)@@ -53,7 +54,8 @@     <> Builder.ascii ']'     <> go p --- | Search for an element at the given path.+-- | Search for an element at the given path. Returns 'Nothing' if+-- anything in the path is missing. query :: Path -> Value -> Maybe Value query = go where   go Nil v = Just v@@ -68,6 +70,23 @@        in go p e     else Nothing   go _ _ = Nothing++-- | Variant of 'query' that returns 'Null' if anything in the path+-- is missing.+query' :: Path -> Value -> Value+query' = go where+  go Nil v = v+  go (Key k p) (Object mbrs) = go p $ foldr+    (\(Member key val) other -> if key == k+      then val+      else other+    ) Null mbrs+  go (Index i p) (Array vs) = if i < PM.sizeofSmallArray vs+    then+      let !(# e #) = PM.indexSmallArray## vs i+       in go p e+    else Null+  go _ _ = Null  ba2st :: ByteArray -> ShortText ba2st (ByteArray x) = TS.fromShortByteStringUnsafe (SBS x)