module Mason.Builder.Dynamic ( DynBuilder , DynamicBackend(..) -- * Runners , toStrictByteString , toLazyByteString , hPutBuilderLen , hPutBuilder , sendBuilder ) where import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as BL import qualified Mason.Builder as B import qualified Mason.Builder.Internal as B import Network.Socket (Socket) import System.IO (Handle) data DynamicBackend = DynGrowingBuffer !B.GrowingBuffer | DynChannel !B.Channel | DynPutEnv !B.PutEnv instance B.Buildable DynamicBackend where byteString bs = B.Builder $ \env buf -> case env of DynGrowingBuffer e -> B.unBuilder (B.byteString bs) e buf DynChannel e -> B.unBuilder (B.byteString bs) e buf DynPutEnv e -> B.unBuilder (B.byteString bs) e buf flush = B.Builder $ \env buf -> case env of DynGrowingBuffer e -> B.unBuilder B.flush e buf DynChannel e -> B.unBuilder B.flush e buf DynPutEnv e -> B.unBuilder B.flush e buf allocate n = B.Builder $ \env buf -> case env of DynGrowingBuffer e -> B.unBuilder (B.allocate n) e buf DynChannel e -> B.unBuilder (B.allocate n) e buf DynPutEnv e -> B.unBuilder (B.allocate n) e buf -- | Builder with a fixed set of backends. This helps reducing code size -- and unoptimised code especially on complex/recursive structures, at the cost of -- extensibility. type DynBuilder = B.BuilderFor DynamicBackend toStrictByteString :: DynBuilder -> B.ByteString toStrictByteString b = B.toStrictByteString $ B.Builder $ B.unBuilder b . DynGrowingBuffer {-# INLINE toStrictByteString #-} toLazyByteString :: DynBuilder -> BL.ByteString toLazyByteString b = B.toLazyByteString $ B.Builder $ B.unBuilder b . DynChannel {-# INLINE toLazyByteString #-} hPutBuilder :: Handle -> DynBuilder -> IO () hPutBuilder h b = B.hPutBuilder h $ B.Builder $ B.unBuilder b . DynPutEnv {-# INLINE hPutBuilder #-} hPutBuilderLen :: Handle -> DynBuilder -> IO Int hPutBuilderLen h b = B.hPutBuilderLen h $ B.Builder $ B.unBuilder b . DynPutEnv {-# INLINE hPutBuilderLen #-} sendBuilder :: Socket -> DynBuilder -> IO Int sendBuilder h b = B.sendBuilder h $ B.Builder $ B.unBuilder b . DynPutEnv {-# INLINE sendBuilder #-}