{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Basement.String.Builder
( Builder
, run
, runUnsafe
, emit
, emitChar
, unsafeStringBuilder
) where
import qualified Basement.Block.Base as Block (length)
import qualified Basement.Block.Builder as Block
import Basement.Compat.Base
import Basement.Compat.Semigroup
import Basement.Monad
import Basement.String (String, ValidationFailure, Encoding (UTF8), fromBytes)
import Basement.UArray.Base (UArray)
import qualified Basement.UArray.Base as A
newtype Builder = Builder Block.Builder
deriving (NonEmpty Builder -> Builder
Builder -> Builder -> Builder
(Builder -> Builder -> Builder)
-> (NonEmpty Builder -> Builder)
-> (forall b. Integral b => b -> Builder -> Builder)
-> Semigroup Builder
forall b. Integral b => b -> Builder -> Builder
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: Builder -> Builder -> Builder
<> :: Builder -> Builder -> Builder
$csconcat :: NonEmpty Builder -> Builder
sconcat :: NonEmpty Builder -> Builder
$cstimes :: forall b. Integral b => b -> Builder -> Builder
stimes :: forall b. Integral b => b -> Builder -> Builder
Semigroup, Semigroup Builder
Builder
Semigroup Builder =>
Builder
-> (Builder -> Builder -> Builder)
-> ([Builder] -> Builder)
-> Monoid Builder
[Builder] -> Builder
Builder -> Builder -> Builder
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: Builder
mempty :: Builder
$cmappend :: Builder -> Builder -> Builder
mappend :: Builder -> Builder -> Builder
$cmconcat :: [Builder] -> Builder
mconcat :: [Builder] -> Builder
Monoid)
unsafeStringBuilder :: Block.Builder -> Builder
unsafeStringBuilder :: Builder -> Builder
unsafeStringBuilder = Builder -> Builder
Builder
{-# INLINE unsafeStringBuilder #-}
run :: PrimMonad prim => Builder -> prim (String, Maybe ValidationFailure, UArray Word8)
run :: forall (prim :: * -> *).
PrimMonad prim =>
Builder -> prim (String, Maybe ValidationFailure, UArray Word8)
run (Builder Builder
builder) = do
Block Word8
block <- Builder -> prim (Block Word8)
forall (prim :: * -> *).
PrimMonad prim =>
Builder -> prim (Block Word8)
Block.run Builder
builder
let array :: UArray Word8
array = Offset Word8
-> CountOf Word8 -> UArrayBackend Word8 -> UArray Word8
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
A.UArray Offset Word8
0 (Block Word8 -> CountOf Word8
forall ty. PrimType ty => Block ty -> CountOf ty
Block.length Block Word8
block) (Block Word8 -> UArrayBackend Word8
forall ty. Block ty -> UArrayBackend ty
A.UArrayBA Block Word8
block)
(String, Maybe ValidationFailure, UArray Word8)
-> prim (String, Maybe ValidationFailure, UArray Word8)
forall a. a -> prim a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((String, Maybe ValidationFailure, UArray Word8)
-> prim (String, Maybe ValidationFailure, UArray Word8))
-> (String, Maybe ValidationFailure, UArray Word8)
-> prim (String, Maybe ValidationFailure, UArray Word8)
forall a b. (a -> b) -> a -> b
$ Encoding
-> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
fromBytes Encoding
UTF8 UArray Word8
array
runUnsafe :: PrimMonad prim => Builder -> prim String
runUnsafe :: forall (prim :: * -> *). PrimMonad prim => Builder -> prim String
runUnsafe (Builder Builder
builder) = Builder -> prim String
forall (prim :: * -> *). PrimMonad prim => Builder -> prim String
Block.unsafeRunString Builder
builder
emit :: String -> Builder
emit :: String -> Builder
emit = Builder -> Builder
Builder (Builder -> Builder) -> (String -> Builder) -> String -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. String -> Builder
Block.emitString
emitChar :: Char -> Builder
emitChar :: Char -> Builder
emitChar = Builder -> Builder
Builder (Builder -> Builder) -> (Char -> Builder) -> Char -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Char -> Builder
Block.emitUTF8Char