{-# LANGUAGE MultiParamTypeClasses #-}

{- |
    Module      :  SDP.Text.Builder
    Copyright   :  (c) Andrey Mulik 2021
    License     :  BSD-style
    Maintainer  :  work.a.mulik@gmail.com
    Portability :  non-portable (requires non-portable module)
    
    "SDP.Text.Builder" provides @sdp@ instances for text 'Builder'.
    
    Note that 'Builder' is a service type for efficient @Text@ creation which
    isn't intended for element-wise operations and content changes. 'Linear'
    instance provided for convenience and many functions (folds, selections,
    etc.) creates intermediate structures (text, string, etc.).
-}
module SDP.Text.Builder
(
  -- * Export
  module SDP.Linear,
  
  -- * Builder
  Builder, fromText, toLazyText, fromLazyText, flush
)
where

import Prelude ()
import SDP.SafePrelude
import SDP.Text.Lazy
import SDP.Linear

import Data.Text.Lazy.Builder

default ()

--------------------------------------------------------------------------------

instance Nullable Builder
  where
    isNull :: Builder -> Bool
isNull = (Builder -> Builder -> Bool
forall a. Eq a => a -> a -> Bool
== Builder
forall a. Monoid a => a
mempty)
    lzero :: Builder
lzero  = Builder
forall a. Monoid a => a
mempty

instance Linear Builder Char
  where
    fromFoldable :: f Char -> Builder
fromFoldable = Text -> Builder
fromLazyText (Text -> Builder) -> (f Char -> Text) -> f Char -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f Char -> Text
forall l e (f :: * -> *). (Linear l e, Foldable f) => f e -> l
fromFoldable
    fromListN :: Int -> [Char] -> Builder
fromListN    = Text -> Builder
fromLazyText (Text -> Builder)
-> (Int -> [Char] -> Text) -> Int -> [Char] -> Builder
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
... Int -> [Char] -> Text
forall l e. Linear l e => Int -> [e] -> l
fromListN
    replicate :: Int -> Char -> Builder
replicate    = Text -> Builder
fromText (Text -> Builder)
-> (Int -> Char -> Text) -> Int -> Char -> Builder
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
... Int -> Char -> Text
forall l e. Linear l e => Int -> e -> l
replicate
    fromList :: [Char] -> Builder
fromList     = [Char] -> Builder
fromString
    single :: Char -> Builder
single       = Char -> Builder
singleton
    
    toHead :: Char -> Builder -> Builder
toHead Char
e Builder
es = Char -> Builder
singleton Char
e Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
es
    toLast :: Builder -> Char -> Builder
toLast Builder
es Char
e = Builder
es Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
singleton Char
e
    
    listL :: Builder -> [Char]
listL = Text -> [Char]
forall l e. Linear l e => l -> [e]
listL (Text -> [Char]) -> (Builder -> Text) -> Builder -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    listR :: Builder -> [Char]
listR = Text -> [Char]
forall l e. Linear l e => l -> [e]
listR (Text -> [Char]) -> (Builder -> Text) -> Builder -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    ++ :: Builder -> Builder -> Builder
(++)  = Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
(<>)
    
    reverse :: Builder -> Builder
reverse = Text -> Builder
fromLazyText (Text -> Builder) -> (Builder -> Text) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
forall l e. Linear l e => l -> l
reverse (Text -> Text) -> (Builder -> Text) -> Builder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    
    concatMap :: (a -> Builder) -> f a -> Builder
concatMap = (a -> Builder) -> f a -> Builder
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap
    concat :: f Builder -> Builder
concat    = f Builder -> Builder
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold
    
    force :: Builder -> Builder
force = Text -> Builder
fromLazyText (Text -> Builder) -> (Builder -> Text) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    
    tail :: Builder -> Builder
tail = Text -> Builder
fromLazyText (Text -> Builder) -> (Builder -> Text) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
forall l e. Linear l e => l -> l
tail (Text -> Text) -> (Builder -> Text) -> Builder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    init :: Builder -> Builder
init = Text -> Builder
fromLazyText (Text -> Builder) -> (Builder -> Text) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
forall l e. Linear l e => l -> l
init (Text -> Text) -> (Builder -> Text) -> Builder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    head :: Builder -> Char
head = Text -> Char
forall l e. Linear l e => l -> e
head (Text -> Char) -> (Builder -> Text) -> Builder -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    last :: Builder -> Char
last = Text -> Char
forall l e. Linear l e => l -> e
last (Text -> Char) -> (Builder -> Text) -> Builder -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    
    partition :: (Char -> Bool) -> Builder -> (Builder, Builder)
partition   Char -> Bool
f = (Text -> Builder) -> (Text, Text) -> (Builder, Builder)
forall a b. (a -> b) -> (a, a) -> (b, b)
both Text -> Builder
fromLazyText ((Text, Text) -> (Builder, Builder))
-> (Builder -> (Text, Text)) -> Builder -> (Builder, Builder)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> (Text, Text)
forall l e. Linear l e => (e -> Bool) -> l -> (l, l)
partition Char -> Bool
f (Text -> (Text, Text))
-> (Builder -> Text) -> Builder -> (Text, Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    intersperse :: Char -> Builder -> Builder
intersperse Char
e = Text -> Builder
fromLazyText (Text -> Builder) -> (Builder -> Text) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Text -> Text
forall l e. Linear l e => e -> l -> l
intersperse Char
e (Text -> Text) -> (Builder -> Text) -> Builder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    filter :: (Char -> Bool) -> Builder -> Builder
filter      Char -> Bool
p = Text -> Builder
fromLazyText (Text -> Builder) -> (Builder -> Text) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> Text
forall l e. Linear l e => (e -> Bool) -> l -> l
filter Char -> Bool
p (Text -> Text) -> (Builder -> Text) -> Builder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    
    nubBy :: Equal Char -> Builder -> Builder
nubBy Equal Char
f = Text -> Builder
fromLazyText (Text -> Builder) -> (Builder -> Text) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Equal Char -> Text -> Text
forall l e. Linear l e => Equal e -> l -> l
nubBy Equal Char
f (Text -> Text) -> (Builder -> Text) -> Builder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    nub :: Builder -> Builder
nub     = Text -> Builder
fromLazyText (Text -> Builder) -> (Builder -> Text) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
.   Text -> Text
forall l e. (Linear l e, Eq e) => l -> l
nub   (Text -> Text) -> (Builder -> Text) -> Builder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    
    ofoldr :: (Int -> Char -> b -> b) -> b -> Builder -> b
ofoldr  Int -> Char -> b -> b
f b
base = (Int -> Char -> b -> b) -> b -> Text -> b
forall l e b. Linear l e => (Int -> e -> b -> b) -> b -> l -> b
ofoldr  Int -> Char -> b -> b
f b
base (Text -> b) -> (Builder -> Text) -> Builder -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    ofoldl :: (Int -> b -> Char -> b) -> b -> Builder -> b
ofoldl  Int -> b -> Char -> b
f b
base = (Int -> b -> Char -> b) -> b -> Text -> b
forall l e b. Linear l e => (Int -> b -> e -> b) -> b -> l -> b
ofoldl  Int -> b -> Char -> b
f b
base (Text -> b) -> (Builder -> Text) -> Builder -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    ofoldr' :: (Int -> Char -> b -> b) -> b -> Builder -> b
ofoldr' Int -> Char -> b -> b
f b
base = (Int -> Char -> b -> b) -> b -> Text -> b
forall l e b. Linear l e => (Int -> e -> b -> b) -> b -> l -> b
ofoldr' Int -> Char -> b -> b
f b
base (Text -> b) -> (Builder -> Text) -> Builder -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    ofoldl' :: (Int -> b -> Char -> b) -> b -> Builder -> b
ofoldl' Int -> b -> Char -> b
f b
base = (Int -> b -> Char -> b) -> b -> Text -> b
forall l e b. Linear l e => (Int -> b -> e -> b) -> b -> l -> b
ofoldl' Int -> b -> Char -> b
f b
base (Text -> b) -> (Builder -> Text) -> Builder -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    
    o_foldr :: (Char -> b -> b) -> b -> Builder -> b
o_foldr  Char -> b -> b
f b
base = (Char -> b -> b) -> b -> Text -> b
forall l e b. Linear l e => (e -> b -> b) -> b -> l -> b
o_foldr  Char -> b -> b
f b
base (Text -> b) -> (Builder -> Text) -> Builder -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    o_foldl :: (b -> Char -> b) -> b -> Builder -> b
o_foldl  b -> Char -> b
f b
base = (b -> Char -> b) -> b -> Text -> b
forall l e b. Linear l e => (b -> e -> b) -> b -> l -> b
o_foldl  b -> Char -> b
f b
base (Text -> b) -> (Builder -> Text) -> Builder -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    o_foldr' :: (Char -> b -> b) -> b -> Builder -> b
o_foldr' Char -> b -> b
f b
base = (Char -> b -> b) -> b -> Text -> b
forall l e b. Linear l e => (e -> b -> b) -> b -> l -> b
o_foldr' Char -> b -> b
f b
base (Text -> b) -> (Builder -> Text) -> Builder -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    o_foldl' :: (b -> Char -> b) -> b -> Builder -> b
o_foldl' b -> Char -> b
f b
base = (b -> Char -> b) -> b -> Text -> b
forall l e b. Linear l e => (b -> e -> b) -> b -> l -> b
o_foldl' b -> Char -> b
f b
base (Text -> b) -> (Builder -> Text) -> Builder -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText

--------------------------------------------------------------------------------

instance IsFile Builder
  where
    hGetContents :: Handle -> io Builder
hGetContents     = (Text -> Builder) -> io Text -> io Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Builder
fromLazyText (io Text -> io Builder)
-> (Handle -> io Text) -> Handle -> io Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> io Text
forall file (io :: * -> *).
(IsFile file, MonadIO io) =>
Handle -> io file
hGetContents
    hPutContents :: Handle -> Builder -> io ()
hPutContents Handle
hdl = Handle -> Text -> io ()
forall file (io :: * -> *).
(IsFile file, MonadIO io) =>
Handle -> file -> io ()
hPutContents Handle
hdl (Text -> io ()) -> (Builder -> Text) -> Builder -> io ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText

instance IsTextFile Builder
  where
    hGetLine :: Handle -> io Builder
hGetLine      = (Text -> Builder) -> io Text -> io Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Builder
fromLazyText (io Text -> io Builder)
-> (Handle -> io Text) -> Handle -> io Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> io Text
forall text (io :: * -> *).
(IsTextFile text, MonadIO io) =>
Handle -> io text
hGetLine
    hPutStrLn :: Handle -> Builder -> io ()
hPutStrLn Handle
hdl = Handle -> Text -> io ()
forall text (io :: * -> *).
(IsTextFile text, MonadIO io) =>
Handle -> text -> io ()
hPutStrLn Handle
hdl (Text -> io ()) -> (Builder -> Text) -> Builder -> io ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText
    hPutStr :: Handle -> Builder -> io ()
hPutStr   Handle
hdl = Handle -> Text -> io ()
forall text (io :: * -> *).
(IsTextFile text, MonadIO io) =>
Handle -> text -> io ()
hPutStr   Handle
hdl (Text -> io ()) -> (Builder -> Text) -> Builder -> io ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText