array-builder-0.1.2.0: src/Data/Builder/Catenable/Bytes.hs
{-# language BangPatterns #-}
{-# language PatternSynonyms #-}
-- | @Data.Builder.Bytes@ specialized to @Bytes@.
module Data.Builder.Catenable.Bytes
( -- * Type
Builder(..)
-- * Convenient infix operators
, pattern (:<)
, pattern (:>)
-- * Run
, run
) where
import Control.Monad.ST (ST,runST)
import Data.Bytes (Bytes)
import Data.Bytes.Chunks (Chunks(ChunksNil))
import qualified Data.Bytes.Builder as BB
import qualified Data.Bytes.Builder.Unsafe as BBU
infixr 5 :<
infixl 5 :>
data Builder
= Empty
| Cons {-# UNPACK #-} !Bytes !Builder
| Snoc !Builder {-# UNPACK #-} !Bytes
| Append !Builder !Builder
instance Monoid Builder where
{-# inline mempty #-}
mempty = Empty
instance Semigroup Builder where
{-# inline (<>) #-}
(<>) = Append
pattern (:<) :: Bytes -> Builder -> Builder
pattern (:<) x y = Cons x y
pattern (:>) :: Builder -> Bytes -> Builder
pattern (:>) x y = Snoc x y
run :: Builder -> Chunks
{-# noinline run #-}
run b = runST $ do
bldr0 <- BBU.newBuilderState 128
bldr1 <- pushCatenable bldr0 b
BBU.reverseCommitsOntoChunks ChunksNil (BBU.closeBuilderState bldr1)
pushCatenable :: BBU.BuilderState s -> Builder -> ST s (BBU.BuilderState s)
pushCatenable !bldr0 b = case b of
Empty -> pure bldr0
Cons x b1 -> do
bldr1 <- BBU.pasteST (BB.bytes x) bldr0
pushCatenable bldr1 b1
Snoc b1 x -> do
bldr1 <- pushCatenable bldr0 b1
BBU.pasteST (BB.bytes x) bldr1
Append x y -> do
bldr1 <- pushCatenable bldr0 x
pushCatenable bldr1 y