{-# LANGUAGE RankNTypes #-} -- | -- -- Builder structures to help with turning 'Json' into a textual encoding. -- module Waargonaut.Encode.Builder where import Data.String (IsString, fromString) import Data.Monoid ((<>)) import Data.Text (Text) import qualified Data.Text.Lazy.Builder as T import qualified Data.Text.Lazy.Builder.Int as T import Data.ByteString (ByteString) import qualified Data.ByteString.Builder as B import qualified Data.ByteString.Builder.Prim as BP import Waargonaut.Types.Json (JType (..), Json (..)) import Waargonaut.Types.Whitespace (WS) import Waargonaut.Encode.Builder.JArray (jArrayBuilder) import Waargonaut.Encode.Builder.JNumber (jNumberBuilder) import Waargonaut.Encode.Builder.JObject (jObjectBuilder) import Waargonaut.Encode.Builder.JString (jStringBuilder) import Waargonaut.Encode.Builder.Types (Builder (..)) -- | A 'T.Text' builder textBuilder :: Builder Text T.Builder textBuilder = Builder T.singleton T.fromText T.decimal -- | A 'B.ByteString' builder bsBuilder :: Builder ByteString B.Builder bsBuilder = Builder (BP.primBounded BP.charUtf8) B.byteString B.intDec -- | A general builder function for working with 'JType' values. -- jTypesBuilder :: ( IsString t , Monoid b ) => Builder t b -> (Builder t b -> WS -> b) -> JType WS Json -> b jTypesBuilder bldr s jt = let (jBuilt, tws') = case jt of JNull tws -> (fromChunk bldr (fromString "null"), tws) JBool b tws -> (fromChunk bldr (fromString $ if b then "true" else "false"), tws) JNum jn tws -> (jNumberBuilder bldr jn, tws) JStr js tws -> (jStringBuilder bldr js, tws) JArr js tws -> (jArrayBuilder bldr s waargonautBuilder js, tws) JObj jobj tws -> (jObjectBuilder bldr s waargonautBuilder jobj, tws) in jBuilt <> s bldr tws' -- | Using the given whitespace builder, create a builder for a given 'Json' value. waargonautBuilder :: ( IsString t , Monoid b ) => (Builder t b -> WS -> b) -> Builder t b -> Json -> b waargonautBuilder ws bldr (Json jt) = jTypesBuilder bldr ws jt