{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
module Waargonaut.Encode.Builder where
import           Data.String                       (IsString, fromString)
#if !MIN_VERSION_base(4,11,0)
import           Data.Monoid                       ((<>))
#endif
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 (..))
textBuilder :: Builder Text T.Builder
textBuilder :: Builder Text Builder
textBuilder = (Char -> Builder)
-> (Text -> Builder) -> (Int -> Builder) -> Builder Text Builder
forall t b. (Char -> b) -> (t -> b) -> (Int -> b) -> Builder t b
Builder
  Char -> Builder
T.singleton
  Text -> Builder
T.fromText
  Int -> Builder
forall a. Integral a => a -> Builder
T.decimal
bsBuilder :: Builder ByteString B.Builder
bsBuilder :: Builder ByteString Builder
bsBuilder = (Char -> Builder)
-> (ByteString -> Builder)
-> (Int -> Builder)
-> Builder ByteString Builder
forall t b. (Char -> b) -> (t -> b) -> (Int -> b) -> Builder t b
Builder
  (BoundedPrim Char -> Char -> Builder
forall a. BoundedPrim a -> a -> Builder
BP.primBounded BoundedPrim Char
BP.charUtf8)
  ByteString -> Builder
B.byteString
  Int -> Builder
B.intDec
jTypesBuilder
  :: ( IsString t
     , Monoid b
     )
  => Builder t b
  -> (Builder t b -> WS -> b)
  -> JType WS Json
  -> b
jTypesBuilder :: Builder t b -> (Builder t b -> WS -> b) -> JType WS Json -> b
jTypesBuilder Builder t b
bldr Builder t b -> WS -> b
s JType WS Json
jt =
  let
    (b
jBuilt, WS
tws') = case JType WS Json
jt of
      JNull     WS
tws -> (Builder t b -> t -> b
forall t b. Builder t b -> t -> b
fromChunk Builder t b
bldr (String -> t
forall a. IsString a => String -> a
fromString String
"null"),                          WS
tws)
      JBool Bool
b   WS
tws -> (Builder t b -> t -> b
forall t b. Builder t b -> t -> b
fromChunk Builder t b
bldr (String -> t
forall a. IsString a => String -> a
fromString (String -> t) -> String -> t
forall a b. (a -> b) -> a -> b
$ if Bool
b then String
"true" else String
"false"), WS
tws)
      JNum JNumber
jn   WS
tws -> (Builder t b -> JNumber -> b
forall b t. Monoid b => Builder t b -> JNumber -> b
jNumberBuilder Builder t b
bldr JNumber
jn,                                      WS
tws)
      JStr JString
js   WS
tws -> (Builder t b -> JString -> b
forall b t. Monoid b => Builder t b -> JString -> b
jStringBuilder Builder t b
bldr JString
js,                                      WS
tws)
      JArr JArray WS Json
js   WS
tws -> (Builder t b
-> (Builder t b -> WS -> b)
-> ((Builder t b -> WS -> b) -> Builder t b -> Json -> b)
-> JArray WS Json
-> b
forall b t ws a.
Monoid b =>
Builder t b
-> (Builder t b -> ws -> b)
-> ((Builder t b -> ws -> b) -> Builder t b -> a -> b)
-> JArray ws a
-> b
jArrayBuilder Builder t b
bldr Builder t b -> WS -> b
s (Builder t b -> WS -> b) -> Builder t b -> Json -> b
forall t b.
(IsString t, Monoid b) =>
(Builder t b -> WS -> b) -> Builder t b -> Json -> b
waargonautBuilder JArray WS Json
js,                   WS
tws)
      JObj JObject WS Json
jobj WS
tws -> (Builder t b
-> (Builder t b -> WS -> b)
-> ((Builder t b -> WS -> b) -> Builder t b -> Json -> b)
-> JObject WS Json
-> b
forall b t ws a.
Monoid b =>
Builder t b
-> (Builder t b -> ws -> b)
-> ((Builder t b -> ws -> b) -> Builder t b -> a -> b)
-> JObject ws a
-> b
jObjectBuilder Builder t b
bldr Builder t b -> WS -> b
s (Builder t b -> WS -> b) -> Builder t b -> Json -> b
forall t b.
(IsString t, Monoid b) =>
(Builder t b -> WS -> b) -> Builder t b -> Json -> b
waargonautBuilder JObject WS Json
jobj,                WS
tws)
  in
    b
jBuilt b -> b -> b
forall a. Semigroup a => a -> a -> a
<> Builder t b -> WS -> b
s Builder t b
bldr WS
tws'
waargonautBuilder
  :: ( IsString t
     , Monoid b
     )
  => (Builder t b -> WS -> b)
  -> Builder t b
  -> Json
  -> b
waargonautBuilder :: (Builder t b -> WS -> b) -> Builder t b -> Json -> b
waargonautBuilder Builder t b -> WS -> b
ws Builder t b
bldr (Json JType WS Json
jt) =
  Builder t b -> (Builder t b -> WS -> b) -> JType WS Json -> b
forall t b.
(IsString t, Monoid b) =>
Builder t b -> (Builder t b -> WS -> b) -> JType WS Json -> b
jTypesBuilder Builder t b
bldr Builder t b -> WS -> b
ws JType WS Json
jt