@@ -67,6 +67,9 @@ module Data.JsonStream.Parser (
6767 , filterI
6868 , takeI
6969 , toList
70+ -- * SAX-like parsers
71+ , arrayFound
72+ , objectFound
7073) where
7174
7275import Control.Applicative
@@ -222,6 +225,34 @@ array' valparse = Parser $ \tp ->
222225arrayOf :: Parser a -> Parser a
223226arrayOf valparse = array' (const valparse)
224227
228+ -- | Generate start/end objects when an element is found, in between run a parser.
229+ -- The inner parser is not run if an array is not found.
230+ elemFound :: Element -> a -> a -> Parser a -> Parser a
231+ elemFound elsearch start end parser = Parser $ moreData handle
232+ where
233+ handle tok el _
234+ | el == elsearch = Yield start (parseAndAppend (callParse parser tok))
235+ handle tok _ _ = callParse ignoreVal tok
236+
237+ parseAndAppend (Failed err) = Failed err
238+ parseAndAppend (Yield v np) = Yield v (parseAndAppend np)
239+ parseAndAppend (MoreData (Parser np, ntp)) = MoreData (Parser (parseAndAppend . np), ntp)
240+ parseAndAppend (Done ctx ntp) = Yield end (Done ctx ntp)
241+
242+ -- | Generate start/end values when an array is found, in between run a parser.
243+ -- The inner parser is not run if an array is not found.
244+ objectFound :: a -> a -> Parser a -> Parser a
245+ objectFound = elemFound ObjectBegin
246+
247+ -- | Generate start/end values when an object is found, in between run a parser.
248+ -- The inner parser is not run if an array is not found.
249+ --
250+ -- > >>> let test = "[[1,2,3],true,[],false,{\"key\":1}]" :: ByteString
251+ -- > >>> parseByteString (arrayOf (arrayFound 10 20 (1 .! integer))) test :: [Int]
252+ -- > [10,2,20,10,20]
253+ arrayFound :: a -> a -> Parser a -> Parser a
254+ arrayFound = elemFound ArrayBegin
255+
225256-- | Match nith item in an array.
226257arrayWithIndexOf :: Int -> Parser a -> Parser a
227258arrayWithIndexOf idx valparse = array' itemFn
0 commit comments