module Data.Binary.Machine where import Data.ByteString (ByteString) import Data.Binary.Get (Decoder(..), Get, pushChunk, runGetIncremental) import Data.Binary.Put (Put, runPut) import Data.Machine (MachineT(..), ProcessT, Step(Await, Yield), Is(Refl), auto, stopped) import qualified Data.ByteString.Lazy as Lazy streamGet :: Monad m => Get a -> ProcessT m ByteString (Either String a) streamGet getA = processDecoder' (runGetIncremental getA) (streamGet getA) processGet :: Monad m => Get a -> ProcessT m ByteString (Either String a) processGet getA = processDecoder (runGetIncremental getA) processDecoder :: Monad m => Decoder a -> ProcessT m ByteString (Either String a) processDecoder decA = processDecoder' decA stopped processDecoder' :: Monad m => Decoder a -> ProcessT m ByteString (Either String a) -> ProcessT m ByteString (Either String a) processDecoder' decA r = MachineT . return $ Await f Refl stopped where f xs = case pushChunk decA xs of Fail _ _ e -> yield' $ Left e Done _ _ a -> yield' $ Right a decA' -> processDecoder' decA' r yield' ea = MachineT . return $ Yield ea r processPut :: Monad m => (a -> Put) -> ProcessT m a ByteString processPut f = auto $ Lazy.toStrict . runPut . f