module Data.Syntax.Printer.ByteString.Lazy (
Printer,
runPrinter
)
where
import Control.Monad
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as BS
import Data.ByteString.Lazy.Builder
import Data.SemiIsoFunctor
import Data.Syntax
import Data.Syntax.Printer.Consumer
newtype Printer a = Printer { getConsumer :: Consumer Builder a }
deriving (SemiIsoFunctor, SemiIsoApply, SemiIsoAlternative, SemiIsoMonad)
instance Syntax Printer ByteString where
anyChar = Printer . Consumer $ Right . word8
take n = Printer . Consumer $ Right . lazyByteString . BS.take (fromIntegral n)
takeWhile p = Printer . Consumer $ Right . lazyByteString . BS.takeWhile p
takeWhile1 p = Printer . Consumer $ Right . lazyByteString <=< notNull . BS.takeWhile p
where notNull t | BS.null t = Left "takeWhile1 failed"
| otherwise = Right t
takeTill1 p = Printer . Consumer $ Right . lazyByteString <=< notNull . BS.takeWhile (not . p)
where notNull t | BS.null t = Left "takeTill1 failed"
| otherwise = Right t
runPrinter :: Printer a -> a -> Either String Builder
runPrinter = runConsumer . getConsumer