{-# LANGUAGE CPP #-}
module Throughput.BlazePutMonad (
Put
, PutM(..)
, runPut
, runPutM
, putBuilder
, execPut
, flush
, putWrite
, putWord8
, putByteString
, putLazyByteString
, putWord16be
, putWord32be
, putWord64be
, putWord16le
, putWord32le
, putWord64le
, putWordhost
, putWord16host
, putWord32host
, putWord64host
) where
import Data.Monoid
import Blaze.ByteString.Builder (Builder, toLazyByteString)
import qualified Blaze.ByteString.Builder as B
import Data.Word
import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
#ifdef APPLICATIVE_IN_BASE
import Control.Applicative
#endif
data PairS a = PairS a {-# UNPACK #-}!Builder
sndS :: PairS a -> Builder
sndS (PairS _ b) = b
newtype PutM a = Put { unPut :: PairS a }
type Put = PutM ()
instance Functor PutM where
fmap f m = Put $ let PairS a w = unPut m in PairS (f a) w
{-# INLINE fmap #-}
#ifdef APPLICATIVE_IN_BASE
instance Applicative PutM where
pure = return
m <*> k = Put $
let PairS f w = unPut m
PairS x w' = unPut k
in PairS (f x) (w `mappend` w')
#endif
instance Monad PutM where
return a = Put $ PairS a mempty
{-# INLINE return #-}
m >>= k = Put $
let PairS a w = unPut m
PairS b w' = unPut (k a)
in PairS b (w `mappend` w')
{-# INLINE (>>=) #-}
m >> k = Put $
let PairS _ w = unPut m
PairS b w' = unPut k
in PairS b (w `mappend` w')
{-# INLINE (>>) #-}
tell :: Builder -> Put
tell b = Put $ PairS () b
{-# INLINE tell #-}
putBuilder :: Builder -> Put
putBuilder = tell
{-# INLINE putBuilder #-}
execPut :: PutM a -> Builder
execPut = sndS . unPut
{-# INLINE execPut #-}
runPut :: Put -> L.ByteString
runPut = toLazyByteString . sndS . unPut
{-# INLINE runPut #-}
runPutM :: PutM a -> (a, L.ByteString)
runPutM (Put (PairS f s)) = (f, toLazyByteString s)
{-# INLINE runPutM #-}
flush :: Put
flush = tell B.flush
{-# INLINE flush #-}
putWord8 :: Word8 -> Put
putWord8 = tell . B.fromWord8
{-# INLINE putWord8 #-}
putWrite :: B.Write -> Put
putWrite = tell . B.fromWrite
putByteString :: S.ByteString -> Put
putByteString = tell . B.fromByteString
{-# INLINE putByteString #-}
putLazyByteString :: L.ByteString -> Put
putLazyByteString = tell . B.fromLazyByteString
{-# INLINE putLazyByteString #-}
putWord16be :: Word16 -> Put
putWord16be = tell . B.fromWord16be
{-# INLINE putWord16be #-}
putWord16le :: Word16 -> Put
putWord16le = tell . B.fromWord16le
{-# INLINE putWord16le #-}
putWord32be :: Word32 -> Put
putWord32be = tell . B.fromWord32be
{-# INLINE putWord32be #-}
putWord32le :: Word32 -> Put
putWord32le = tell . B.fromWord32le
{-# INLINE putWord32le #-}
putWord64be :: Word64 -> Put
putWord64be = tell . B.fromWord64be
{-# INLINE putWord64be #-}
putWord64le :: Word64 -> Put
putWord64le = tell . B.fromWord64le
{-# INLINE putWord64le #-}
putWordhost :: Word -> Put
putWordhost = tell . B.fromWordhost
{-# INLINE putWordhost #-}
putWord16host :: Word16 -> Put
putWord16host = tell . B.fromWord16host
{-# INLINE putWord16host #-}
putWord32host :: Word32 -> Put
putWord32host = tell . B.fromWord32host
{-# INLINE putWord32host #-}
putWord64host :: Word64 -> Put
putWord64host = tell . B.fromWord64host
{-# INLINE putWord64host #-}