module Data.Sv.Print.Internal (
printNewline
, printField
, printSpaced
, printRecord
, printRecords
, printHeader
) where
import Control.Lens (review, view)
import Data.Bifoldable (bifoldMap)
import Data.ByteString.Builder as Builder
import Data.Semigroup ((<>))
import Data.Semigroup.Foldable (intercalate1)
import Data.Sv.Print.Options
import Data.Sv.Syntax.Field (Field (Quoted, Unquoted), SpacedField)
import Data.Sv.Syntax.Record (Record (Record), Records (Records, EmptyRecords))
import Data.Sv.Syntax.Sv (Header (Header), Separator)
import Text.Newline
import Text.Space (spaceToChar, Spaced (Spaced))
import Text.Quote
printNewline :: Newline -> Builder
printNewline = Builder.lazyByteString . newlineToString
printField :: PrintOptions s -> Field s -> Builder
printField opts f =
case f of
Unquoted s ->
view build opts s
Quoted q s ->
let qc = quoteToString q
contents = view build opts $ view escape opts (review quoteChar q) s
in qc <> contents <> qc
printSpaced :: PrintOptions s -> SpacedField s -> Builder
printSpaced opts (Spaced b t a) =
let spc = foldMap (Builder.charUtf8 . spaceToChar)
in spc b <> printField opts a <> spc t
printRecord :: PrintOptions s -> Separator -> Record s -> Builder
printRecord opts sep (Record fs) =
intercalate1 (Builder.charUtf8 sep) (fmap (printSpaced opts) fs)
printRecords :: PrintOptions s -> Separator -> Records s -> Builder
printRecords opts sep rs = case rs of
EmptyRecords -> mempty
Records a as ->
printRecord opts sep a <> foldMap (bifoldMap printNewline (printRecord opts sep)) as
printHeader :: PrintOptions s -> Separator -> Header s -> Builder
printHeader opts sep (Header r n) = printRecord opts sep r <> printNewline n