{-# LANGUAGE BangPatterns #-} module HaskellWorks.Data.Json.Extract ( extractJsonSnippet ) where import qualified Data.ByteString as BS import Data.Word8 import HaskellWorks.Data.Json.Conduit.Words import HaskellWorks.Data.Json.Type data ExtractJsonState = ExtractJsonStringEscaped | ExtractJsonStringInJson | ExtractJsonStringInNumber | ExtractJsonStringInString extractJsonSnippet :: BS.ByteString -> Maybe (JsonType, BS.ByteString) extractJsonSnippet bs = case extractJsonSnippet' 0 ExtractJsonStringInJson bs of Just (jsonType, len) -> Just (jsonType, BS.take len bs) Nothing -> Nothing extractJsonSnippet' :: Int -> ExtractJsonState -> BS.ByteString -> Maybe (JsonType, Int) extractJsonSnippet' n ExtractJsonStringInJson bs = case BS.uncons bs of Just (!c, !cs) | isLeadingDigit c -> extractJsonSnippet' (n + 1) ExtractJsonStringInNumber cs Just (!c, !cs) | c == _quotedbl -> extractJsonSnippet' (n + 1) ExtractJsonStringInString cs Just (!c, _) | c == _t -> Just (JsonTypeBool, n + 1) Just (!c, _) | c == _f -> Just (JsonTypeBool, n + 1) Just (!c, _) | c == _n -> Just (JsonTypeNull, n + 1) Just (!c, _) | c == _braceleft -> Just (JsonTypeObject, n + 1) Just (!c, _) | c == _bracketleft -> Just (JsonTypeArray, n + 1) Just _ -> Nothing Nothing -> Nothing extractJsonSnippet' n ExtractJsonStringInString bs = case BS.uncons bs of Just (!c, !cs) | c == _backslash -> extractJsonSnippet' (n + 1) ExtractJsonStringEscaped cs Just (!c, _) | c == _quotedbl -> Just (JsonTypeString, n + 1) Just (_ , !cs) -> extractJsonSnippet' (n + 1) ExtractJsonStringInString cs Nothing -> Nothing extractJsonSnippet' n ExtractJsonStringEscaped bs = case BS.uncons bs of Just (_, !cs) -> extractJsonSnippet' (n + 1) ExtractJsonStringInString cs Nothing -> Nothing extractJsonSnippet' n ExtractJsonStringInNumber bs = case BS.uncons bs of Just (!c, !cs) | isTrailingDigit c -> extractJsonSnippet' (n + 1) ExtractJsonStringInNumber cs Just _ -> Just (JsonTypeNumber, n) Nothing -> Just (JsonTypeNumber, n)