packages feed

json-stream 0.4.3.0 → 0.4.4.0

raw patch · 7 files changed

+481/−19 lines, 7 filesdep +conduitdep +primitivePVP ok

version bump matches the API change (PVP)

Dependencies added: conduit, primitive

API changes (from Hackage documentation)

+ Data.JsonStream.Parser: manyReverse :: Parser a -> Parser [a]
+ Data.JsonStream.Parser: valueWith :: (Value -> Parser a) -> Parser a

Files

+ Data/JsonStream/Conduit.hs view
@@ -0,0 +1,25 @@+-- |+-- Module : Data.JsonStream.Conduit+-- License     : BSD-style+--+-- Stability   : experimental+-- Portability : portable+--+-- Use "Data.JsonStream.Parser" parsers in "Data.Conduit".++module Data.JsonStream.Conduit (+  parserConduit+) where++import           Data.ByteString (ByteString)+import qualified Data.Conduit.Internal as C++import           Data.JsonStream.Parser++-- |Use a 'Parser' as a conduit from 'ByteString' input chunks to results, finally returning any parse error or 'Nothing' on success.+parserConduit :: Parser a -> C.ConduitT ByteString a m (Maybe String)+parserConduit ps = C.ConduitT (parsePipe $ runParser ps) where+  parsePipe (ParseYield a p) r = C.HaveOutput (parsePipe p r) a+  parsePipe (ParseNeedData f) r = C.NeedInput (\i -> parsePipe (f i) r) (\() -> r (Just "Incomplete JSON"))+  parsePipe (ParseFailed e) r = r (Just e)+  parsePipe (ParseDone l) r = C.Leftover (r Nothing) l
Data/JsonStream/Parser.hs view
@@ -47,6 +47,7 @@   , eitherDecodeStrict     -- * FromJSON parser   , value+  , valueWith   , string   , byteString     -- * Constant space parsers@@ -74,6 +75,7 @@   , filterI   , takeI   , mapWithFailure+  , manyReverse     -- * SAX-like parsers   , arrayFound   , objectFound@@ -89,6 +91,7 @@  import           Control.Applicative import qualified Data.Aeson                  as AE+import qualified Data.Aeson.Types            as AE import qualified Data.ByteString.Char8       as BS import qualified Data.ByteString.Lazy.Char8  as BL import qualified Data.ByteString.Lazy.Internal as BL@@ -398,7 +401,9 @@         ObjectBegin -> AE.Object . tomap <$> callParse (manyReverse (objectItems aeValue)) tok         _ -> Failed ("aeValue - unexpected token: " ++ show el) --- | Optimized function for aeson objects - evades reversing the objects+-- | Identical to @fmap 'reverse' . 'many'@ but more efficient.+-- If you don't care about the order of the results but plan to fully evaluate the list,+-- this can be slightly more efficient than 'many' as it avoids the accumulating thunks. manyReverse :: Parser a -> Parser [a] manyReverse f = Parser $ \ntok -> loop [] (callParse f ntok)   where@@ -544,21 +549,25 @@     value' _ (JValue AE.Null) ntok = Yield Nothing (Done "" ntok)     value' tok _ _ = callParse (Just <$> valparse) tok --- | Match 'FromJSON' value. Calls parseJSON on the parsed value.------ >>> let json = "[{\"key1\": [1,2], \"key2\": [5,6]}]"--- >>> parseByteString (arrayOf value) json :: [AE.Value]--- [Object (fromList [("key2",Array [Number 5.0,Number 6.0]),("key1",Array [Number 1.0,Number 2.0])])]-value :: AE.FromJSON a => Parser a-value = Parser $ \ntok -> loop (callParse aeValue ntok)+-- | Match values with a 'AE.Parser'.  Returns values for which the given parser succeeds.+valueWith :: (AE.Value -> AE.Parser a) -> Parser a+valueWith jparser = Parser $ \ntok -> loop (callParse aeValue ntok)   where     loop (Done ctx ntp) = Done ctx ntp     loop (Failed err) = Failed err     loop (MoreData (Parser np, ntok)) = MoreData (Parser (loop . np), ntok)     loop (Yield v np) =-      case AE.fromJSON v of+      case AE.parse jparser v of         AE.Error _ -> loop np         AE.Success res -> Yield res (loop np)++-- | Match 'AE.FromJSON' value. Equivalent to @'valueWith' 'AE.parseJSON'@.+--+-- >>> let json = "[{\"key1\": [1,2], \"key2\": [5,6]}]"+-- >>> parseByteString (arrayOf value) json :: [AE.Value]+-- [Object (fromList [("key2",Array [Number 5.0,Number 6.0]),("key1",Array [Number 1.0,Number 2.0])])]+value :: AE.FromJSON a => Parser a+value = valueWith AE.parseJSON  -- | Take maximum n matching items. --
Data/JsonStream/Unescape.hs view
@@ -1,28 +1,48 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE MagicHash                #-} {-# LANGUAGE UnliftedFFITypes         #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE MultiWayIf   #-}  module Data.JsonStream.Unescape (   unescapeText ) where -import           Control.Exception          (evaluate, throw, try)-import           Control.Monad.ST.Unsafe    (unsafeIOToST, unsafeSTToIO) import           Data.ByteString            as B import           Data.ByteString.Internal   as B hiding (c2w)-import qualified Data.Text.Array            as A import           Data.Text.Encoding.Error   (UnicodeException (..)) import           Data.Text.Internal         (Text (..))-import           Data.Text.Internal.Private (runText) import           Data.Text.Unsafe           (unsafeDupablePerformIO)-import           Data.Word                  (Word8)-import           Foreign.C.Types            (CInt (..), CSize (..))+import           Data.Word                  (Word8, Word32) import           Foreign.ForeignPtr         (withForeignPtr)-import           Foreign.Marshal.Utils      (with) import           Foreign.Ptr                (Ptr, plusPtr) import           Foreign.Storable           (peek)++#if MIN_VERSION_text(2,0,0)++import qualified Data.Primitive           as P+import qualified Data.Text.Array          as T+import qualified Data.Text.Internal       as T+import           Data.Bits                (shiftL, shiftR, (.&.), (.|.))+import           Control.Exception        (try, throwIO)+import Foreign.ForeignPtr (ForeignPtr)+import GHC.ForeignPtr (plusForeignPtr)++#else++import           Control.Exception          (evaluate, throw, try)+import           Control.Monad.ST.Unsafe    (unsafeIOToST, unsafeSTToIO)+import           Data.Text.Internal.Private (runText)+import           Foreign.Marshal.Utils      (with)+import qualified Data.Text.Array            as A import           GHC.Base                   (MutableByteArray#)+import           Foreign.C.Types            (CInt (..), CSize (..)) +#endif++#if !MIN_VERSION_text(2,0,0)+ foreign import ccall unsafe "_jstream_decode_string" c_js_decode     :: MutableByteArray# s -> Ptr CSize     -> Ptr Word8 -> Ptr Word8 -> IO CInt@@ -49,3 +69,383 @@ unescapeText :: ByteString -> Either UnicodeException Text unescapeText = unsafeDupablePerformIO . try . evaluate . unescapeText' {-# INLINE unescapeText #-}++#else++withBS :: ByteString -> (ForeignPtr Word8 -> Int -> r) -> r+#if MIN_VERSION_bytestring(0,11,0)+withBS (BS !sfp !slen)       kont = kont sfp slen+#else+withBS (PS !sfp !soff !slen) kont = kont (plusForeignPtr sfp soff) slen+#endif+{-# INLINE withBS #-}++unescapeText :: ByteString -> Either UnicodeException Text+unescapeText = unsafeDupablePerformIO . try . unescapeTextIO++throwDecodeError :: IO a+throwDecodeError =+  let desc = "Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream"+   in throwIO (DecodeError desc Nothing)++-- The following is copied from aeson-2.0 ++-------------------------------------------------------------------------------+-- unescapeTextIO+-------------------------------------------------------------------------------++-- This function is generated using staged-streams+-- See: https://github.com/phadej/staged/blob/master/staged-streams-unicode/src/Unicode/JSON.hs+--+-- Because @aeson@ better to not use template-haskell itself,+-- we dump the splice and prettify it by hand a bit.+--+unescapeTextIO :: ByteString -> IO Text+unescapeTextIO bs = withBS bs $ \fptr len ->+  withForeignPtr fptr $ \begin -> do+    let end :: Ptr Word8+        end = plusPtr begin len++    arr <- P.newPrimArray len++    let write3bytes :: Int -> Word8 -> Word8 -> Word8 -> Ptr Word8 -> IO Text+        write3bytes !out !b1 !b2 !b3 !inp = do+          P.writePrimArray arr out b1+          write2bytes (out + 1) b2 b3 inp++        write2bytes :: Int -> Word8 -> Word8 -> Ptr Word8 -> IO Text+        write2bytes !out !b1 !b2 !inp = do+          P.writePrimArray arr out b1+          write1byte (out + 1) b2 inp++        write1byte :: Int -> Word8 -> Ptr Word8 -> IO Text+        write1byte !out !b1 !inp = do+          P.writePrimArray arr out b1+          state_start (out + 1) inp++        writeCodePoint :: Int -> Ptr Word8 -> Word32 -> IO Text+        writeCodePoint !out !inp !acc+          | acc <= 127 = do+            P.writePrimArray arr out (fromIntegral acc :: Word8)+            state_start (out + 1) (plusPtr inp 1)++          | acc <= 2047 = do+            let b1 = fromIntegral (shiftR acc 6 .|. 192) :: Word8+            let b2 = fromIntegral ((acc .&. 63) .|. 128) :: Word8+            P.writePrimArray arr out b1+            write1byte (out + 1) b2 (plusPtr inp 1)++          | acc <= 65535 = do+            let b1 = fromIntegral (shiftR acc 12 .|. 224) :: Word8+            let b2 = fromIntegral ((shiftR acc 6 .&. 63) .|.  128) :: Word8+            let b3 = fromIntegral ((acc .&. 63) .|. 128) :: Word8+            P.writePrimArray arr out b1+            write2bytes (out + 1) b2 b3 (plusPtr inp 1)++          | otherwise = do+            let b1 = fromIntegral (shiftR acc 18 .|. 240) :: Word8+            let b2 = fromIntegral ((shiftR acc 12 .&. 63) .|. 128) :: Word8+            let b3 = fromIntegral ((shiftR acc 6 .&. 63) .|. 128) :: Word8+            let b4 = fromIntegral ((acc .&. 63) .|. 128) :: Word8+            P.writePrimArray arr out b1+            write3bytes (out + 1) b2 b3 b4 (plusPtr inp 1)++        state_sudone :: Int -> Ptr Word8 -> Word32 -> Word32 -> IO Text+        state_sudone !out !inp !hi !lo+          | 56320 <= lo, lo <= 57343+          = writeCodePoint out inp (65536 + (shiftL (hi - 55296) 10 .|.  (lo - 56320)))+          +          | otherwise+          = throwDecodeError++        state_su4 :: Int -> Ptr Word8 -> Word32 -> Word32 -> IO Text+        state_su4 !out !inp !hi !acc+          | inp == end = throwDecodeError+          | otherwise = do+            w8 <- peek inp+            if | 48 <= w8, w8 <= 57 ->+                 state_sudone out inp hi (shiftL acc 4 .|. fromIntegral (w8 - 48))+               | 65 <= w8, w8 <= 70 ->+                 state_sudone out inp hi (shiftL acc 4 .|. fromIntegral (w8 - 55))+               | 97 <= w8, w8 <= 102 ->+                 state_sudone out inp hi (shiftL acc 4 .|. fromIntegral (w8 - 87))+               | otherwise ->+                 throwDecodeError++        state_su3 :: Int -> Ptr Word8 -> Word32 -> Word32 -> IO Text+        state_su3 !out !inp !hi !acc+          | inp == end = throwDecodeError+          | otherwise = do+            w8 <- peek inp+            if | 48 <= w8, w8 <= 57 ->+                 state_su4 out (plusPtr inp 1) hi (shiftL acc 4 .|. fromIntegral (w8 - 48))+               | 65 <= w8, w8 <= 70 ->+                 state_su4 out (plusPtr inp 1) hi (shiftL acc 4 .|. fromIntegral (w8 - 55))+               | 97 <= w8, w8 <= 102 ->+                 state_su4 out (plusPtr inp 1) hi (shiftL acc 4 .|. fromIntegral (w8 - 87))+               | otherwise ->+                 throwDecodeError++        state_su2 :: Int -> Ptr Word8 -> Word32 -> Word32 -> IO Text+        state_su2 !out !inp !hi !acc+          | inp == end = throwDecodeError+          | otherwise = do+            w8 <- peek inp+            if | 48 <= w8, w8 <= 57 -> +                 state_su3 out (plusPtr inp 1) hi (shiftL acc 4 .|. fromIntegral (w8 - 48))+               | 65 <= w8, w8 <= 70 ->+                 state_su3 out (plusPtr inp 1) hi (shiftL acc 4 .|. fromIntegral (w8 - 55))+               | 97 <= w8, w8 <= 102 ->+                 state_su3 out (plusPtr inp 1) hi (shiftL acc 4 .|. fromIntegral (w8 - 87))+               | otherwise ->+                 throwDecodeError++        state_su1 :: Int -> Ptr Word8 -> Word32 -> IO Text+        state_su1 !out !inp !hi+          | inp == end = throwDecodeError+          | otherwise = do+            w8 <- peek inp+            if | 48 <= w8, w8 <= 57 ->+                 state_su2 out (plusPtr inp 1) hi (fromIntegral (w8 - 48))+               | 65 <= w8, w8 <= 70 ->+                 state_su2 out (plusPtr inp 1) hi (fromIntegral (w8 - 55))+               | 97 <= w8, w8 <= 102 ->+                 state_su2 out (plusPtr inp 1) hi (fromIntegral (w8 - 87))+               | otherwise ->+                 throwDecodeError++        state_su :: Int -> Ptr Word8 -> Word32 -> IO Text+        state_su !out !inp !hi+          | inp == end = throwDecodeError+          | otherwise = do+            w8 <- peek inp+            case w8 of+              117 -> state_su1 out (plusPtr inp 1) hi+              _   -> throwDecodeError++        state_ss :: Int -> Ptr Word8 -> Word32 -> IO Text+        state_ss !out !inp !hi+          | inp == end = throwDecodeError+          | otherwise = do+            w8 <- peek inp+            case w8 of+              92 -> state_su out (plusPtr inp 1) hi+              _  -> throwDecodeError++        state_udone :: Int -> Ptr Word8 -> Word32 -> IO Text+        state_udone !out !inp !acc+          | acc < 55296 || acc > 57343 =+            writeCodePoint out inp acc++          | acc < 56320 =+            state_ss out (plusPtr inp 1) acc++          | otherwise =+            throwDecodeError++        state_u4 :: Int -> Ptr Word8 -> Word32 -> IO Text+        state_u4 !out !inp !acc+          | inp == end = throwDecodeError+          | otherwise = do+            w8 <- peek inp+            if | 48 <= w8, w8 <= 57 ->+                 state_udone out inp (shiftL acc 4 .|. fromIntegral (w8 - 48))+               | 65 <= w8, w8 <= 70 ->+                 state_udone out inp (shiftL acc 4 .|. fromIntegral (w8 - 55))+               | 97 <= w8, w8 <= 102 ->+                 state_udone out inp (shiftL acc 4 .|. fromIntegral (w8 - 87))+               | otherwise ->+                 throwDecodeError++        state_u3 :: Int -> Ptr Word8 -> Word32 -> IO Text+        state_u3 !out !inp !acc+          | inp == end = throwDecodeError+          | otherwise = do+            w8 <- peek inp+            if | 48 <= w8, w8 <= 57 ->+                 state_u4 out (plusPtr inp 1) (shiftL acc 4 .|. fromIntegral (w8 - 48))+               | 65 <= w8, w8 <= 70 ->+                 state_u4 out (plusPtr inp 1) (shiftL acc 4 .|. fromIntegral (w8 - 55))+               | 97 <= w8, w8 <= 102 ->+                 state_u4 out (plusPtr inp 1) (shiftL acc 4 .|. fromIntegral (w8 - 87))+               | otherwise ->+                 throwDecodeError++        state_u2 :: Int -> Ptr Word8 -> Word32 -> IO Text+        state_u2 !out !inp !acc+          | inp == end = throwDecodeError+          | otherwise = do+            w8 <- peek inp+            if | 48 <= w8, w8 <= 57 ->+                 state_u3 out (plusPtr inp 1) (shiftL acc 4 .|. fromIntegral (w8 - 48))+               | 65 <= w8, w8 <= 70 ->+                 state_u3 out (plusPtr inp 1) (shiftL acc 4 .|. fromIntegral (w8 - 55))+               | 97 <= w8, w8 <= 102 ->+                 state_u3 out (plusPtr inp 1) (shiftL acc 4 .|. fromIntegral (w8 - 87))+               | otherwise ->+                 throwDecodeError++        state_u1 :: Int -> Ptr Word8 -> IO Text+        state_u1 !out !inp+          | inp == end = throwDecodeError+          | otherwise = do+            w8 <- peek inp+            if | 48 <= w8, w8 <= 57 ->+                 state_u2 out (plusPtr inp 1) (fromIntegral (w8 - 48))+               | 65 <= w8, w8 <= 70 ->+                 state_u2 out (plusPtr inp 1) (fromIntegral (w8 - 55))+               | 97 <= w8, w8 <= 102 ->+                 state_u2 out (plusPtr inp 1) (fromIntegral (w8 - 87))+               | otherwise ->+                 throwDecodeError++        state_escape :: Int -> Ptr Word8 -> IO Text+        state_escape !out !inp+          | inp == end = throwDecodeError+          | otherwise  = do+            w8 <- peek inp+            case w8 of+              34 -> do+                P.writePrimArray arr out 34+                state_start (out + 1) (plusPtr inp 1)++              92 -> do+                P.writePrimArray arr out 92+                state_start (out + 1) (plusPtr inp 1)++              47 -> do+                P.writePrimArray arr out 47+                state_start (out + 1) (plusPtr inp 1)++              98 -> do+                P.writePrimArray arr out 8+                state_start (out + 1) (plusPtr inp 1)++              102 -> do+                P.writePrimArray arr out 12+                state_start (out + 1) (plusPtr inp 1)++              110 -> do+                P.writePrimArray arr out 10+                state_start (out + 1) (plusPtr inp 1)++              114 -> do+                P.writePrimArray arr out 13+                state_start (out + 1) (plusPtr inp 1)++              116 -> do+                P.writePrimArray arr out 9+                state_start (out + 1) (plusPtr inp 1)++              117 ->+                state_u1 out (plusPtr inp 1)++              _ -> throwDecodeError++        state_input4c :: Int -> Ptr Word8 -> Word8 -> Word8 -> Word8 -> IO Text+        state_input4c !out !inp !b1 !b2 !b3+          | inp == end = throwDecodeError+          | otherwise  = do+            w8 <- peek inp+            if | (w8 .&. 192) == 128+               , let acc    = shiftL (fromIntegral (b1 .&. 7)) 18+               , let acc'   = acc .|. shiftL (fromIntegral (b2 .&. 63)) 12+               , let acc''  = acc' .|. shiftL (fromIntegral (b3 .&. 63)) 6+               , let acc''' = acc'' .|. fromIntegral (w8 .&. 63) :: Word32+               , acc''' >= 65536 && acc''' < 1114112 -> do+                 P.writePrimArray arr out b1+                 write3bytes (out + 1) b2 b3 w8 (plusPtr inp 1)++               | otherwise ->+                 throwDecodeError++        state_input4b :: Int -> Ptr Word8 -> Word8 -> Word8 -> IO Text+        state_input4b !out !inp !b1 !b2+          | inp == end = throwDecodeError+          | otherwise  = do+            w8 <- peek inp+            if | (w8 .&. 192) == 128 ->+                 state_input4c out (plusPtr inp 1) b1 b2 w8++               | otherwise ->+                 throwDecodeError++        state_input4 :: Int -> Ptr Word8 -> Word8 -> IO Text+        state_input4 !out !inp !b1+          | inp == end = throwDecodeError+          | otherwise  = do+            w8 <- peek inp+            if | (w8 .&. 192) == 128 ->+                 state_input4b out (plusPtr inp 1) b1 w8++               | otherwise ->+                 throwDecodeError++        state_input3b :: Int -> Ptr Word8 -> Word8 -> Word8 -> IO Text+        state_input3b !out !inp !b1 !b2+          | inp == end = throwDecodeError+          | otherwise  = do+            w8 <- peek inp+            if | (w8 .&. 192) == 128+               , let acc   = shiftL (fromIntegral (b1 .&. 15)) 12+               , let acc'  = acc .|.  shiftL (fromIntegral (b2 .&. 63)) 6+               , let acc'' = acc' .|. fromIntegral (w8 .&. 63) :: Word32+               , (acc'' >= 2048 && acc'' < 55296) || acc'' > 57343 -> do+                 P.writePrimArray arr out b1+                 write2bytes (out + 1) b2 w8 (plusPtr inp 1)++               | otherwise ->+                 throwDecodeError++        state_input3 :: Int -> Ptr Word8 -> Word8 -> IO Text+        state_input3 !out !inp !b1+          | inp == end = throwDecodeError+          | otherwise  = do+            w8 <- peek inp+            if | (w8 .&. 192) == 128 ->+                 state_input3b out (plusPtr inp 1) b1 w8++               | otherwise ->+                 throwDecodeError++        state_input2 :: Int -> Ptr Word8 -> Word8 -> IO Text+        state_input2 !out !inp !b1+          | inp == end = throwDecodeError+          | otherwise  = do+            w8 <- peek inp+            if | (w8 .&. 192) == 128,+                 let acc = shiftL (fromIntegral (b1 .&. 63)) 6 :: Word32+                     acc' = acc .|. fromIntegral (w8 .&. 63) :: Word32+               , acc' >= 128 -> do+                 P.writePrimArray arr out b1+                 write1byte (out + 1) w8 (plusPtr inp 1)++               | otherwise ->+                 throwDecodeError++        state_start :: Int -> Ptr Word8 -> IO Text+        state_start !out !inp+          | inp == end = do+            P.shrinkMutablePrimArray arr out+            frozenArr <- P.unsafeFreezePrimArray arr+            return $ case frozenArr of+              P.PrimArray ba -> T.Text (T.ByteArray ba) 0 out++          | otherwise = do+            w8 <- peek inp+            if | w8 == 92 -> state_escape out (plusPtr inp 1)+               | w8 < 128 -> do+                 P.writePrimArray arr out w8+                 state_start (out + 1) (plusPtr inp 1)++               | w8 < 192 -> throwDecodeError+               | w8 < 224 -> state_input2 out (plusPtr inp 1) w8+               | w8 < 240 -> state_input3 out (plusPtr inp 1) w8+               | w8 < 248 -> state_input4 out (plusPtr inp 1) w8++               | otherwise -> throwDecodeError++    -- start the state machine+    state_start (0 :: Int) begin++#endif
README.md view
@@ -1,6 +1,6 @@ # json-stream - Applicative incremental JSON parser for Haskell -[![Build Status](https://travis-ci.org/ondrap/json-stream.svg?branch=master)](https://travis-ci.org/ondrap/json-stream) [![Hackage](https://img.shields.io/hackage/v/json-stream.svg)](https://hackage.haskell.org/package/json-stream)+[![Hackage](https://img.shields.io/hackage/v/json-stream.svg)](https://hackage.haskell.org/package/json-stream)  # When to use this library 
changelog.md view
@@ -1,3 +1,10 @@+# 0.4.4.0++- added text 2.0 compatibility+- added conduit interface behind a flag (Dylan Simon)+- added manyReverse (Dylan Simon)+- added valueWith (Dylan Simon)+ # 0.4.3.0  - Aeson 2.0 compatibility
json-stream.cabal view
@@ -1,5 +1,5 @@ name:                json-stream-version:             0.4.3.0+version:             0.4.4.0 synopsis:            Incremental applicative JSON parser description:         Easy to use JSON parser fully supporting incremental parsing.                      Parsing grammar in applicative form.@@ -28,6 +28,10 @@   type: git   location: https://github.com/ondrap/json-stream.git +flag conduit+  description: Support the conduit package+  manual: True+  default: False  library   exposed-modules:     Data.JsonStream.Parser@@ -45,6 +49,10 @@                        , vector                        , unordered-containers                        , scientific+                       , primitive+  if flag(conduit)+    exposed-modules:     Data.JsonStream.Conduit+    build-depends:       conduit    default-language:    Haskell2010   Ghc-Options:         -Wall -fwarn-incomplete-uni-patterns@@ -104,6 +112,8 @@                        , directory                        , QuickCheck                        , quickcheck-unicode+                       , primitive+  -- executable spdtest --   main-is: spdtest.hs
test/ParserSpec.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE CPP                 #-} module ParserSpec where  import Control.Applicative@@ -12,10 +13,14 @@ import Control.Monad (forM_) import Data.Text.Encoding (encodeUtf8) import qualified Data.Vector as Vec-import qualified Data.HashMap.Strict as HMap import System.Directory (getDirectoryContents) import Data.Int import Data.Word+#if MIN_VERSION_aeson(2,0,0)+import qualified Data.Aeson.KeyMap           as AEK+#else+import qualified Data.HashMap.Strict as HMap+#endif  import Data.JsonStream.Parser @@ -124,13 +129,19 @@         msg = parseLazyByteString parser (BL.fromChunks test) :: [BS.ByteString]     msg `shouldBe` ["abcd\\n\\rxyz"] ++ specEdge :: Spec specEdge = describe "Edge cases" $ do   it "Correct incremental parsing 1" $ do     let msg1 = "[ {\"test1\"  :[1,true,false,null,-3.591e+1,[12,13]], \"test2\":\"123\\r\\n\\\"\\u0041\"}]"         pmsg = BL.fromChunks $ map BS.singleton msg1         res = parseLazyByteString value pmsg :: [AE.Value]+#if MIN_VERSION_aeson(2,0,0)+    res `shouldBe` [Array (Vec.fromList [Object $ AEK.fromList [("test2",String "123\r\n\"A"),("test1",Array (Vec.fromList [Number 1.0,Bool True,Bool False,Null,Number (-35.91),Array (Vec.fromList [Number 12.0,Number 13.0])]))]])]+#else     res `shouldBe` [Array (Vec.fromList [Object $ HMap.fromList [("test2",String "123\r\n\"A"),("test1",Array (Vec.fromList [Number 1.0,Bool True,Bool False,Null,Number (-35.91),Array (Vec.fromList [Number 12.0,Number 13.0])]))]])]+#endif    it "Correct incremental parsing 2" $ do     let msg1 = "{\"test1\"  :[1,true,false,null,-3.591e+1,[12,13]], \"test2\":\"test2string\"}"