From 0eb29082b14c02587847a1d888127f5b04075954 Mon Sep 17 00:00:00 2001 From: William Rusnack Date: Thu, 11 Apr 2024 14:19:38 -0400 Subject: [PATCH] instance IsList Builder --- Data/ByteString/Builder.hs | 9 --------- Data/ByteString/Builder/Internal.hs | 27 +++++++++++++++++++-------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Data/ByteString/Builder.hs b/Data/ByteString/Builder.hs index 1032526da..8fdd58d67 100644 --- a/Data/ByteString/Builder.hs +++ b/Data/ByteString/Builder.hs @@ -255,7 +255,6 @@ import Prelude hiding (writeFile) import Data.ByteString.Builder.Internal import qualified Data.ByteString.Builder.Prim as P -import qualified Data.ByteString.Lazy.Internal as L import Data.ByteString.Builder.ASCII import Data.ByteString.Builder.RealFloat @@ -265,14 +264,6 @@ import Foreign import GHC.Base (unpackCString#, unpackCStringUtf8#, unpackFoldrCString#, build) --- | Execute a 'Builder' and return the generated chunks as a 'L.LazyByteString'. --- The work is performed lazy, i.e., only when a chunk of the 'L.LazyByteString' --- is forced. -{-# NOINLINE toLazyByteString #-} -- ensure code is shared -toLazyByteString :: Builder -> L.LazyByteString -toLazyByteString = toLazyByteStringWith - (safeStrategy L.smallChunkSize L.defaultChunkSize) L.Empty - {- Not yet stable enough. See note on 'hPut' in Data.ByteString.Builder.Internal -} diff --git a/Data/ByteString/Builder/Internal.hs b/Data/ByteString/Builder/Internal.hs index 109c762e2..1d7be35be 100644 --- a/Data/ByteString/Builder/Internal.hs +++ b/Data/ByteString/Builder/Internal.hs @@ -1,4 +1,6 @@ {-# LANGUAGE Unsafe #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE NoMonoLocalBinds #-} {-# OPTIONS_HADDOCK not-home #-} @@ -99,6 +101,7 @@ module Data.ByteString.Builder.Internal ( , lazyByteString -- ** Execution + , toLazyByteString , toLazyByteStringWith , AllocationStrategy , safeStrategy @@ -128,6 +131,7 @@ module Data.ByteString.Builder.Internal ( ) where import Control.Arrow (second) +import GHC.Exts (IsList(..)) import Data.Semigroup (Semigroup(..)) import Data.List.NonEmpty (NonEmpty(..)) @@ -414,6 +418,12 @@ instance Monoid Builder where {-# INLINE mconcat #-} mconcat = foldr mappend mempty +instance IsList Builder where + type Item Builder = Word8 + fromList = lazyByteStringInsert . fromList + fromListN n = byteString . S.unsafePackLenBytes n + toList = toList . toLazyByteString + -- | Flush the current buffer. This introduces a chunk boundary. {-# INLINE flush #-} flush :: Builder @@ -1040,18 +1050,19 @@ safeStrategy firstSize bufSize = nextBuffer Nothing = newBuffer $ sanitize firstSize nextBuffer (Just (_, minSize)) = newBuffer minSize +-- | Execute a 'Builder' and return the generated chunks as a 'L.LazyByteString'. +-- The work is performed lazy, i.e., only when a chunk of the 'L.LazyByteString' +-- is forced. +{-# NOINLINE toLazyByteString #-} -- ensure code is shared +toLazyByteString :: Builder -> L.LazyByteString +toLazyByteString = toLazyByteStringWith + (safeStrategy L.smallChunkSize L.defaultChunkSize) L.Empty + -- | /Heavy inlining./ Execute a 'Builder' with custom execution parameters. -- -- This function is inlined despite its heavy code-size to allow fusing with -- the allocation strategy. For example, the default 'Builder' execution --- function 'Data.ByteString.Builder.toLazyByteString' is defined as follows. --- --- @ --- {-\# NOINLINE toLazyByteString \#-} --- toLazyByteString = --- toLazyByteStringWith ('safeStrategy' 'L.smallChunkSize' 'L.defaultChunkSize') L.empty --- @ --- +-- function 'Data.ByteString.Builder.toLazyByteString' -- where @L.empty@ is the zero-length 'L.LazyByteString'. -- -- In most cases, the parameters used by 'Data.ByteString.Builder.toLazyByteString' give good