1-- | This module provides support for parsing values from Text 2-- 'InputStream's using @attoparsec@. /Since: 1.4.0.0./ 3 4module System.IO.Streams.Attoparsec.Text 5 ( -- * Parsing 6 parseFromStream 7 , parserToInputStream 8 , ParseException(..) 9 ) where 10 11------------------------------------------------------------------------------ 12import Data.Attoparsec.Text (Parser) 13import Data.Text (Text) 14------------------------------------------------------------------------------ 15import System.IO.Streams.Internal (InputStream) 16import qualified System.IO.Streams.Internal as Streams 17import System.IO.Streams.Internal.Attoparsec (ParseData (..), ParseException (..), parseFromStreamInternal) 18 19 20------------------------------------------------------------------------------ 21-- | Supplies an @attoparsec@ 'Parser' with an 'InputStream', returning the 22-- final parsed value or throwing a 'ParseException' if parsing fails. 23-- 24-- 'parseFromStream' consumes only as much input as necessary to satisfy the 25-- 'Parser': any unconsumed input is pushed back onto the 'InputStream'. 26-- 27-- If the 'Parser' exhausts the 'InputStream', the end-of-stream signal is sent 28-- to attoparsec. 29-- 30-- Example: 31-- 32-- @ 33-- ghci> import "Data.Attoparsec.Text" 34-- ghci> is <- 'System.IO.Streams.fromList' [\"12345xxx\" :: 'Text'] 35-- ghci> 'parseFromStream' ('Data.Attoparsec.Text.takeWhile' 'Data.Char.isDigit') is 36-- \"12345\" 37-- ghci> 'System.IO.Streams.read' is 38-- Just \"xxx\" 39-- @ 40parseFromStream :: Parser r 41 -> InputStream Text 42 -> IO r 43parseFromStream = parseFromStreamInternal parse feed 44 45------------------------------------------------------------------------------ 46-- | Given a 'Parser' yielding values of type @'Maybe' r@, transforms an 47-- 'InputStream' over byte strings to an 'InputStream' yielding values of type 48-- @r@. 49-- 50-- If the parser yields @Just x@, then @x@ will be passed along downstream, and 51-- if the parser yields @Nothing@, that will be interpreted as end-of-stream. 52-- 53-- Upon a parse error, 'parserToInputStream' will throw a 'ParseException'. 54-- 55-- Example: 56-- 57-- @ 58-- ghci> import "Control.Applicative" 59-- ghci> import "Data.Attoparsec.Text" 60-- ghci> is <- 'System.IO.Streams.fromList' [\"1 2 3 4 5\" :: 'Text'] 61-- ghci> let parser = ('Data.Attoparsec.Text.endOfInput' >> 'Control.Applicative.pure' 'Nothing') \<|\> (Just \<$\> ('Data.Attoparsec.Text.skipWhile' 'Data.Attoparsec.Text.isSpace' *> 'Data.Attoparsec.Text.decimal')) 62-- ghci> 'parserToInputStream' parser is >>= 'System.IO.Streams.toList' 63-- [1,2,3,4,5] 64-- ghci> is' \<- 'System.IO.Streams.fromList' [\"1 2xx3 4 5\" :: 'Text'] >>= 'parserToInputStream' parser 65-- ghci> 'read' is' 66-- Just 1 67-- ghci> 'read' is' 68-- Just 2 69-- ghci> 'read' is' 70-- *** Exception: Parse exception: Failed reading: takeWhile1 71-- @ 72parserToInputStream :: Parser (Maybe r) 73 -> InputStream Text 74 -> IO (InputStream r) 75parserToInputStream = (Streams.makeInputStream .) . parseFromStream 76{-# INLINE parserToInputStream #-} 77