module Data.Niagra.Builder
(
Builder(..),
singleton,
fromString,
fromText,
fromLazyText,
toText,
toLazyText
)
where
import Data.Niagra.Builder.Internal
import Control.Monad.ST
import Data.Text (Text)
import qualified Data.Text.Lazy as TL
import Data.Foldable
import qualified Data.String as STR
import Data.Sequence (Seq(..), (|>))
import qualified Data.Sequence as S
data Builder = Builder {
runBuilder :: forall s. ((Buffer s, Seq Text) -> ST s (Buffer s, Seq Text))
-> (Buffer s, Seq Text)
-> ST s (Buffer s, Seq Text)
}
evalBuilder :: Builder -> ST s [Text]
evalBuilder (Builder f) = do
(h,t) <- unsafeNewBuffer >>= f return . (,S.empty)
flushed <- bufferToText h
return $ toList $ t |> flushed
instance Monoid Builder where
mempty = empty
mappend = appendBuilder
instance STR.IsString Builder where
fromString = fromString
empty :: Builder
empty = Builder $ \f v -> f v
singleton :: Char -> Builder
singleton c = Builder $ \f tup -> snocVec c tup >>= f
fromString :: String -> Builder
fromString [] = empty
fromString [x] = singleton x
fromString s = Builder $ \f tup -> foldlM (flip snocVec) tup s >>= f
fromText :: Text -> Builder
fromText t = Builder $ \f tup -> appendVec t tup >>= f
fromLazyText :: TL.Text -> Builder
fromLazyText t = Builder $ \f tup -> foldlM (flip appendVec) tup (TL.toChunks t) >>= f
appendBuilder :: Builder -> Builder -> Builder
appendBuilder (Builder a) (Builder b) = Builder $ a . b
toText :: Builder -> Text
toText = TL.toStrict . toLazyText
toLazyText :: Builder -> TL.Text
toLazyText b = runST $ TL.fromChunks <$> evalBuilder b