Z-Data-0.5.0.0: Array, vector and text
Copyright(c) Dong Han 2017-2019
(c) Tao He 2018-2019
LicenseBSD
Maintainerwinterland1989@gmail.com
Stabilityexperimental
Portabilitynon-portable
Safe HaskellNone
LanguageHaskell2010

Z.Data.Builder.Base

Description

A Builder records a buffer writing function, which can be mappend in O(1) via composition.

  • When building a short strict Bytes with build/buildWith, we double the buffer each time buffer is full.
  • When building a large lazy [Bytes] with buildChunks/buildChunksWith, we insert a new chunk when buffer is full.

Most of the time using combinators from this module to build Builder s is enough, but in case of rolling something shining from the ground, keep an eye on correct BuildResult handling.

Synopsis

Builder type

newtype Builder a Source #

Builder is a monad to help compose BuilderStep. With next BuilderStep continuation, we can do interesting things like perform some action, or interleave the build process.

Notes on IsString instance: Builder ()'s IsString instance use stringModifiedUTF8, which is different from stringUTF8 in that it DOES NOT PROVIDE UTF8 GUARANTEES! :

  • \NUL will be written as xC0 x80.
  • \xD800 ~ \xDFFF will be encoded in three bytes as normal UTF-8 codepoints.

Constructors

Builder 

Fields

Instances

Instances details
Monad Builder Source # 
Instance details

Defined in Z.Data.Builder.Base

Methods

(>>=) :: Builder a -> (a -> Builder b) -> Builder b #

(>>) :: Builder a -> Builder b -> Builder b #

return :: a -> Builder a #

Functor Builder Source # 
Instance details

Defined in Z.Data.Builder.Base

Methods

fmap :: (a -> b) -> Builder a -> Builder b #

(<$) :: a -> Builder b -> Builder a #

Applicative Builder Source # 
Instance details

Defined in Z.Data.Builder.Base

Methods

pure :: a -> Builder a #

(<*>) :: Builder (a -> b) -> Builder a -> Builder b #

liftA2 :: (a -> b -> c) -> Builder a -> Builder b -> Builder c #

(*>) :: Builder a -> Builder b -> Builder b #

(<*) :: Builder a -> Builder b -> Builder a #

Show (Builder a) Source # 
Instance details

Defined in Z.Data.Builder.Base

Methods

showsPrec :: Int -> Builder a -> ShowS #

show :: Builder a -> String #

showList :: [Builder a] -> ShowS #

a ~ () => IsString (Builder a) Source #

This instance simple write literals' bytes into buffer, which is different from stringUTF8 in that it DOES NOT PROVIDE UTF8 GUARANTEES! :

Instance details

Defined in Z.Data.Builder.Base

Methods

fromString :: String -> Builder a #

Semigroup (Builder ()) Source # 
Instance details

Defined in Z.Data.Builder.Base

Methods

(<>) :: Builder () -> Builder () -> Builder () #

sconcat :: NonEmpty (Builder ()) -> Builder () #

stimes :: Integral b => b -> Builder () -> Builder () #

Monoid (Builder ()) Source # 
Instance details

Defined in Z.Data.Builder.Base

Methods

mempty :: Builder () #

mappend :: Builder () -> Builder () -> Builder () #

mconcat :: [Builder ()] -> Builder () #

Arbitrary (Builder ()) Source # 
Instance details

Defined in Z.Data.Builder.Base

Methods

arbitrary :: Gen (Builder ()) #

shrink :: Builder () -> [Builder ()] #

CoArbitrary (Builder ()) Source # 
Instance details

Defined in Z.Data.Builder.Base

Methods

coarbitrary :: Builder () -> Gen b -> Gen b #

data Buffer Source #

Helper type to help ghc unpack

Constructors

Buffer 

Fields

freezeBuffer :: Buffer -> IO Bytes Source #

Freeze buffer and return a Bytes.

Note the mutable buffer array will be shrinked with shrinkMutablePrimArray, which may not able to be reused.

data BuildResult Source #

BuildSignals abstract signals to the caller of a BuildStep. There are three signals: Done, BufferFull, or InsertBytes signals

type BuildStep = Buffer -> IO BuildResult Source #

BuilderStep is a function that fill buffer under given conditions.

Running a builder

buildWith :: Int -> Builder a -> Bytes Source #

Run Builder with doubling buffer strategy, which is suitable for building short bytes.

buildChunksWith :: Int -> Int -> Builder a -> [Bytes] Source #

Run Builder with inserting chunk strategy, which is suitable for building a list of bytes chunks and processing them in a streaming ways.

Note the building process is lazy, building happens when list chunks are consumed.

buildText :: HasCallStack => Builder a -> Text Source #

Build some bytes and validate if it's UTF8 bytes.

unsafeBuildText :: Builder a -> Text Source #

Build some bytes assuming it's UTF8 encoding.

Be carefully use this function because you could constrcut illegal Text values. Check ShowT for UTF8 encoding builders. This functions is intended to be used in debug only.

Basic buiders

bytes :: Bytes -> Builder () Source #

Write a Bytes.

ensureN Source #

Arguments

:: Int

size bound

-> (MutablePrimArray RealWorld Word8 -> Int -> IO Int)

the writer which return a new offset for next write

-> Builder () 

writeN Source #

Arguments

:: Int

size bound

-> (MutablePrimArray RealWorld Word8 -> Int -> IO ())

the writer should write exactly N bytes

-> Builder () 

Pritimive builders

encodePrim :: forall a. Unaligned a => a -> Builder () Source #

Write a primitive type in host byte order.

encodePrimLE :: forall a. Unaligned (LE a) => a -> Builder () Source #

Write a primitive type with little endianess.

encodePrimBE :: forall a. Unaligned (BE a) => a -> Builder () Source #

Write a primitive type with big endianess.

More builders

stringModifiedUTF8 :: String -> Builder () Source #

Encode string with modified UTF-8 encoding, will be rewritten to a memcpy if possible.

charModifiedUTF8 :: Char -> Builder () Source #

Turn Char into Builder with Modified UTF8 encoding

\NUL is encoded as two bytes C0 80 , \xD800 ~ \xDFFF is encoded as a three bytes normal UTF-8 codepoint.

stringUTF8 :: String -> Builder () Source #

Turn String into Builder with UTF8 encoding

Illegal codepoints will be written as replacementChars.

This is different from writing string literals builders via OverloadedStrings, because string literals do not provide UTF8 guarantees.

This function will be rewritten into a memcpy if possible, (running a fast UTF-8 validation at runtime first).

charUTF8 :: Char -> Builder () Source #

Turn Char into Builder with UTF8 encoding

Illegal codepoints will be written as replacementChars.

string7 :: String -> Builder () Source #

Turn String into Builder with ASCII7 encoding

Codepoints beyond 'x7F' will be chopped.

char7 :: Char -> Builder () Source #

Turn Char into Builder with ASCII7 encoding

Codepoints beyond 'x7F' will be chopped.

word7 :: Word8 -> Builder () Source #

Turn Word8 into Builder with ASCII7 encoding

Codepoints beyond 'x7F' will be chopped.

string8 :: String -> Builder () Source #

Turn String into Builder with ASCII8 encoding

Codepoints beyond 'xFF' will be chopped. Note, this encoding is NOT compatible with UTF8 encoding, i.e. bytes written by this builder may not be legal UTF8 encoding bytes.

char8 :: Char -> Builder () Source #

Turn Char into Builder with ASCII8 encoding

Codepoints beyond 'xFF' will be chopped. Note, this encoding is NOT compatible with UTF8 encoding, i.e. bytes written by this builder may not be legal UTF8 encoding bytes.

word8 :: Word8 -> Builder () Source #

Turn Word8 into Builder with ASCII8 encoding, (alias to encodePrim).

Note, this encoding is NOT compatible with UTF8 encoding, i.e. bytes written by this builder may not be legal UTF8 encoding bytes.

text :: Text -> Builder () Source #

Write UTF8 encoded Text using Builder.

Note, if you're trying to write string literals builders, please open OverloadedStrings and use Builders IsString instance, it will be rewritten into a memcpy.

Builder helpers

paren :: Builder () -> Builder () Source #

add (...) to original builder.

curly :: Builder () -> Builder () Source #

add {...} to original builder.

square :: Builder () -> Builder () Source #

add [...] to original builder.

angle :: Builder () -> Builder () Source #

add <...> to original builder.

quotes :: Builder () -> Builder () Source #

add "..." to original builder.

squotes :: Builder () -> Builder () Source #

add '...' to original builder.

colon :: Builder () Source #

write an ASCII :

comma :: Builder () Source #

write an ASCII ,

intercalateVec Source #

Arguments

:: Vec v a 
=> Builder ()

the seperator

-> (a -> Builder ())

value formatter

-> v a

value vector

-> Builder () 

Use separator to connect a vector of builders.

import Z.Data.Builder as B
import Z.Data.Text    as T
import Z.Data.Vector  as V

> T.validate . B.build $ B.intercalateVec "," B.int (V.pack [1,2,3,4] :: V.PrimVector Int)
"1,2,3,4"

intercalateList Source #

Arguments

:: Builder ()

the seperator

-> (a -> Builder ())

value formatter

-> [a]

value list

-> Builder () 

Use separator to connect list of builders.

import Z.Data.Builder as B
import Z.Data.Text    as T
import Z.Data.Vector  as V

T.validate . B.build $ B.intercalateList "," B.int ([1,2,3,4] :: [Int])
"1,2,3,4"