module HaskellWorks.Data.Conduit.Json.Blank
( blankJson
) where
import Control.Monad
import Control.Monad.Trans.Resource (MonadThrow)
import Data.ByteString as BS
import Data.Conduit
import Data.Word
import HaskellWorks.Data.Conduit.Json.Words
import Prelude as P
data BlankState
= Escaped
| InJson
| InString
| InNumber
| InIdent
blankJson :: MonadThrow m => Conduit BS.ByteString m BS.ByteString
blankJson = blankJson' InJson
blankJson' :: MonadThrow m => BlankState -> Conduit BS.ByteString m BS.ByteString
blankJson' lastState = do
mbs <- await
case mbs of
Just bs -> do
let (!cs, Just (!nextState, _)) = unfoldrN (BS.length bs) blankByteString (lastState, bs)
yield cs
blankJson' nextState
Nothing -> return ()
where
blankByteString :: (BlankState, ByteString) -> Maybe (Word8, (BlankState, ByteString))
blankByteString (InJson, bs) = case BS.uncons bs of
Just (!c, !cs) | isLeadingDigit c -> Just (w1 , (InNumber , cs))
Just (!c, !cs) | c == wDoubleQuote -> Just (wOpenParen , (InString , cs))
Just (!c, !cs) | isAlphabetic c -> Just (c , (InIdent , cs))
Just (!c, !cs) -> Just (c , (InJson , cs))
Nothing -> Nothing
blankByteString (InString, bs) = case BS.uncons bs of
Just (!c, !cs) | c == wBackslash -> Just (wSpace , (Escaped , cs))
Just (!c, !cs) | c == wDoubleQuote -> Just (wCloseParen, (InJson , cs))
Just (_ , !cs) -> Just (wSpace , (InString , cs))
Nothing -> Nothing
blankByteString (Escaped, bs) = case BS.uncons bs of
Just (_, !cs) -> Just (wSpace, (InString, cs))
Nothing -> Nothing
blankByteString (InNumber, bs) = case BS.uncons bs of
Just (!c, !cs) | isTrailingDigit c -> Just (w0 , (InNumber , cs))
Just (!c, !cs) | c == wDoubleQuote -> Just (wOpenParen , (InString , cs))
Just (!c, !cs) | isAlphabetic c -> Just (c , (InIdent , cs))
Just (!c, !cs) -> Just (c , (InJson , cs))
Nothing -> Nothing
blankByteString (InIdent, bs) = case BS.uncons bs of
Just (!c, !cs) | isAlphabetic c -> Just (wUnderscore, (InIdent , cs))
Just (!c, !cs) | isLeadingDigit c -> Just (w1 , (InNumber , cs))
Just (!c, !cs) | c == wDoubleQuote -> Just (wOpenParen , (InString , cs))
Just (!c, !cs) -> Just (c , (InJson , cs))
Nothing -> Nothing