module Pipes.Aeson.Internal
( DecodingError(..)
, consecutively
, skipSpace
, fromLazy
) where
import Control.Exception (Exception)
import qualified Control.Monad.Trans.Error as E
import qualified Control.Monad.Trans.State.Strict as S
import qualified Data.Aeson as Ae
import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString.Lazy.Internal as BLI
import qualified Data.Char as Char
import Data.Data (Data, Typeable)
import Pipes
import qualified Pipes.Attoparsec as PA
import qualified Pipes.Parse as Pp
import qualified Pipes.Lift as P
data DecodingError
= ParserError PA.ParsingError
| ValueError String
deriving (Show, Eq, Data, Typeable)
instance Exception DecodingError
instance E.Error DecodingError
instance Monad m => E.Error (DecodingError, Producer a m r)
consecutively
:: (Monad m, Ae.FromJSON b)
=> S.StateT (Producer B.ByteString m r) m (Either DecodingError (Int, b))
-> Producer B.ByteString m r
-> Producer (Int, b) m
(Either (DecodingError, Producer B.ByteString m r) r)
consecutively parser = \src -> do
(er, src') <- P.runStateP src prod
return $ case er of
Left e -> Left (e, src')
Right r -> Right r
where
prod = do
eof <- lift (skipSpace >> PA.isEndOfParserInput)
if eof
then do
ra <- lift Pp.draw
case ra of
Left r -> return (Right r)
Right _ -> error "Pipes.Aeson.parseMany: impossible!!"
else do
eb <- lift parser
case eb of
Left e -> return (Left e)
Right b -> yield b >> prod
skipSpace :: Monad m => S.StateT (Producer B.ByteString m r) m ()
skipSpace = do
ma <- Pp.draw
case ma of
Left _ -> return ()
Right a -> do
let a' = B.dropWhile Char.isSpace a
if B.null a'
then skipSpace
else Pp.unDraw a'
fromLazy :: Monad m => BLI.ByteString -> Producer' B.ByteString m ()
fromLazy = BLI.foldrChunks (\e a -> yield e >> a) (return ())