{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}

module Data.Aeson.Encoding.Internal
    (
    -- * Encoding
      Encoding' (..)
    , Encoding
    , encodingToLazyByteString
    , unsafeToEncoding
    , retagEncoding
    , Series (..)
    , pairs
    , pair
    , pairStr
    , unsafePairSBS
    , pair'
    -- * Predicates
    , nullEncoding
    -- * Encoding constructors
    , emptyArray_
    , emptyObject_
    , wrapObject
    , wrapArray
    , null_
    , bool
    , key
    , text
    , lazyText
    , shortText
    , string
    , list
    , dict
    , tuple
    , (>*<)
    , InArray
    , empty
    , (><)
    , econcat
    -- ** Decimal numbers
    , int8, int16, int32, int64, int
    , word8, word16, word32, word64, word
    , integer, float, double, scientific
    -- ** Decimal numbers as Text
    , int8Text, int16Text, int32Text, int64Text, intText
    , word8Text, word16Text, word32Text, word64Text, wordText
    , integerText, floatText, doubleText, scientificText
    -- ** Time
    , day
    , month
    , quarter
    , localTime
    , utcTime
    , timeOfDay
    , zonedTime
    -- ** value
    , value
    -- ** JSON tokens
    , comma, colon, openBracket, closeBracket, openCurly, closeCurly
    ) where

import Prelude.Compat

import Data.Aeson.Types.Internal (Value, Key)
import Data.ByteString.Builder (Builder, char7, toLazyByteString)
import Data.ByteString.Short (ShortByteString)
import qualified Data.Aeson.Key as Key
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Scientific (Scientific)
import Data.Text (Text)
import Data.Time (Day, LocalTime, TimeOfDay, UTCTime, ZonedTime)
import Data.Time.Calendar.Month.Compat (Month)
import Data.Time.Calendar.Quarter.Compat (Quarter)
import Data.Typeable (Typeable)
import Data.Word (Word8, Word16, Word32, Word64)
import qualified Data.Aeson.Encoding.Builder as EB
import qualified Data.ByteString.Builder as B
import qualified Data.ByteString.Lazy as BSL
import qualified Data.Text.Lazy as LT
import qualified Data.Text.Short as ST

-- | An encoding of a JSON value.
--
-- @tag@ represents which kind of JSON the Encoding is encoding to,
-- we reuse 'Text' and 'Value' as tags here.
newtype Encoding' tag = Encoding {
      Encoding' tag -> Builder
fromEncoding :: Builder
      -- ^ Acquire the underlying bytestring builder.
    } deriving (Typeable)

-- | Often used synonym for 'Encoding''.
type Encoding = Encoding' Value

-- | Make Encoding from Builder.
--
-- Use with care! You have to make sure that the passed Builder
-- is a valid JSON Encoding!
unsafeToEncoding :: Builder -> Encoding' a
unsafeToEncoding :: Builder -> Encoding' a
unsafeToEncoding = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding

encodingToLazyByteString :: Encoding' a -> BSL.ByteString
encodingToLazyByteString :: Encoding' a -> ByteString
encodingToLazyByteString = Builder -> ByteString
toLazyByteString (Builder -> ByteString)
-> (Encoding' a -> Builder) -> Encoding' a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Encoding' a -> Builder
forall tag. Encoding' tag -> Builder
fromEncoding
{-# INLINE encodingToLazyByteString #-}

retagEncoding :: Encoding' a -> Encoding' b
retagEncoding :: Encoding' a -> Encoding' b
retagEncoding = Builder -> Encoding' b
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' b)
-> (Encoding' a -> Builder) -> Encoding' a -> Encoding' b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Encoding' a -> Builder
forall tag. Encoding' tag -> Builder
fromEncoding

-------------------------------------------------------------------------------
-- Encoding instances
-------------------------------------------------------------------------------

instance Show (Encoding' a) where
    show :: Encoding' a -> String
show (Encoding Builder
e) = ByteString -> String
forall a. Show a => a -> String
show (Builder -> ByteString
toLazyByteString Builder
e)

instance Eq (Encoding' a) where
    Encoding Builder
a == :: Encoding' a -> Encoding' a -> Bool
== Encoding Builder
b = Builder -> ByteString
toLazyByteString Builder
a ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== Builder -> ByteString
toLazyByteString Builder
b

instance Ord (Encoding' a) where
    compare :: Encoding' a -> Encoding' a -> Ordering
compare (Encoding Builder
a) (Encoding Builder
b) =
      ByteString -> ByteString -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Builder -> ByteString
toLazyByteString Builder
a) (Builder -> ByteString
toLazyByteString Builder
b)

-- | A series of values that, when encoded, should be separated by
-- commas. Since 0.11.0.0, the '.=' operator is overloaded to create
-- either @(Text, Value)@ or 'Series'. You can use Series when
-- encoding directly to a bytestring builder as in the following
-- example:
--
-- > toEncoding (Person name age) = pairs ("name" .= name <> "age" .= age)
data Series = Empty
            | Value (Encoding' Series)
            deriving (Typeable)

pair :: Key -> Encoding -> Series
pair :: Key -> Encoding -> Series
pair Key
name Encoding
val = Encoding' Key -> Encoding -> Series
pair' (Key -> Encoding' Key
forall a. Key -> Encoding' a
key Key
name) Encoding
val
{-# INLINE pair #-}

pairStr :: String -> Encoding -> Series
pairStr :: String -> Encoding -> Series
pairStr String
name Encoding
val = Encoding' Key -> Encoding -> Series
pair' (String -> Encoding' Key
forall a. String -> Encoding' a
string String
name) Encoding
val
{-# INLINE pairStr #-}

pair' :: Encoding' Key -> Encoding -> Series
pair' :: Encoding' Key -> Encoding -> Series
pair' Encoding' Key
name Encoding
val = Encoding' Series -> Series
Value (Encoding' Series -> Series) -> Encoding' Series -> Series
forall a b. (a -> b) -> a -> b
$ Encoding -> Encoding' Series
forall a b. Encoding' a -> Encoding' b
retagEncoding (Encoding -> Encoding' Series) -> Encoding -> Encoding' Series
forall a b. (a -> b) -> a -> b
$ Encoding' Key -> Encoding
forall a b. Encoding' a -> Encoding' b
retagEncoding Encoding' Key
name Encoding -> Encoding -> Encoding
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding
forall a. Encoding' a
colon Encoding -> Encoding -> Encoding
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding
val

-- | A variant of a 'pair' where key is already encoded
-- including the quotes and colon.
--
-- @
-- 'pair' "foo" v = 'unsafePair' "\\"foo\\":" v
-- @
--
-- @since 2.0.3.0
--
unsafePairSBS :: ShortByteString -> Encoding -> Series
unsafePairSBS :: ShortByteString -> Encoding -> Series
unsafePairSBS ShortByteString
k Encoding
v = Encoding' Series -> Series
Value (Encoding' Series -> Series) -> Encoding' Series -> Series
forall a b. (a -> b) -> a -> b
$ Encoding -> Encoding' Series
forall a b. Encoding' a -> Encoding' b
retagEncoding (Encoding -> Encoding' Series) -> Encoding -> Encoding' Series
forall a b. (a -> b) -> a -> b
$ Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (ShortByteString -> Builder
B.shortByteString ShortByteString
k) Encoding -> Encoding -> Encoding
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding
v
{-# INLINE unsafePairSBS #-}

instance Semigroup Series where
    Series
Empty   <> :: Series -> Series -> Series
<> Series
a = Series
a
    Value Encoding' Series
a <> Series
b = Encoding' Series -> Series
Value (Encoding' Series -> Series) -> Encoding' Series -> Series
forall a b. (a -> b) -> a -> b
$ Encoding' Series
a Encoding' Series -> Encoding' Series -> Encoding' Series
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< case Series
b of
        Series
Empty   -> Encoding' Series
forall a. Encoding' a
empty
        Value Encoding' Series
x -> Encoding' Series
forall a. Encoding' a
comma Encoding' Series -> Encoding' Series -> Encoding' Series
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding' Series
x

instance Monoid Series where
    mempty :: Series
mempty  = Series
Empty
    mappend :: Series -> Series -> Series
mappend = Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
(<>)

nullEncoding :: Encoding' a -> Bool
nullEncoding :: Encoding' a -> Bool
nullEncoding = ByteString -> Bool
BSL.null (ByteString -> Bool)
-> (Encoding' a -> ByteString) -> Encoding' a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> ByteString
toLazyByteString (Builder -> ByteString)
-> (Encoding' a -> Builder) -> Encoding' a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Encoding' a -> Builder
forall tag. Encoding' tag -> Builder
fromEncoding

emptyArray_ :: Encoding
emptyArray_ :: Encoding
emptyArray_ = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding Builder
EB.emptyArray_

emptyObject_ :: Encoding
emptyObject_ :: Encoding
emptyObject_ = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding Builder
EB.emptyObject_

wrapArray :: Encoding' a -> Encoding
wrapArray :: Encoding' a -> Encoding
wrapArray Encoding' a
e = Encoding' a -> Encoding
forall a b. Encoding' a -> Encoding' b
retagEncoding (Encoding' a -> Encoding) -> Encoding' a -> Encoding
forall a b. (a -> b) -> a -> b
$ Encoding' a
forall a. Encoding' a
openBracket Encoding' a -> Encoding' a -> Encoding' a
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding' a
e Encoding' a -> Encoding' a -> Encoding' a
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding' a
forall a. Encoding' a
closeBracket

wrapObject :: Encoding' a -> Encoding
wrapObject :: Encoding' a -> Encoding
wrapObject Encoding' a
e = Encoding' a -> Encoding
forall a b. Encoding' a -> Encoding' b
retagEncoding (Encoding' a -> Encoding) -> Encoding' a -> Encoding
forall a b. (a -> b) -> a -> b
$ Encoding' a
forall a. Encoding' a
openCurly Encoding' a -> Encoding' a -> Encoding' a
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding' a
e Encoding' a -> Encoding' a -> Encoding' a
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding' a
forall a. Encoding' a
closeCurly

null_ :: Encoding
null_ :: Encoding
null_ = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding Builder
EB.null_

bool :: Bool -> Encoding
bool :: Bool -> Encoding
bool Bool
True = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding Builder
"true"
bool Bool
False = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding Builder
"false"

-- | Encode a series of key/value pairs, separated by commas.
pairs :: Series -> Encoding
pairs :: Series -> Encoding
pairs (Value Encoding' Series
v) = Encoding
forall a. Encoding' a
openCurly Encoding -> Encoding -> Encoding
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding' Series -> Encoding
forall a b. Encoding' a -> Encoding' b
retagEncoding Encoding' Series
v Encoding -> Encoding -> Encoding
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding
forall a. Encoding' a
closeCurly
pairs Series
Empty     = Encoding
emptyObject_
{-# INLINE pairs #-}

list :: (a -> Encoding) -> [a] -> Encoding
list :: (a -> Encoding) -> [a] -> Encoding
list a -> Encoding
_  []     = Encoding
emptyArray_
list a -> Encoding
to' (a
x:[a]
xs) = Encoding
forall a. Encoding' a
openBracket Encoding -> Encoding -> Encoding
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< a -> Encoding
to' a
x Encoding -> Encoding -> Encoding
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< [a] -> Encoding
commas [a]
xs Encoding -> Encoding -> Encoding
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding
forall a. Encoding' a
closeBracket
  where
    commas :: [a] -> Encoding
commas = (a -> Encoding -> Encoding) -> Encoding -> [a] -> Encoding
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\a
v Encoding
vs -> Encoding
forall a. Encoding' a
comma Encoding -> Encoding -> Encoding
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< a -> Encoding
to' a
v Encoding -> Encoding -> Encoding
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding
vs) Encoding
forall a. Encoding' a
empty
{-# INLINE list #-}

-- | Encode as JSON object
dict
    :: (k -> Encoding' Key)                           -- ^ key encoding
    -> (v -> Encoding)                                -- ^ value encoding
    -> (forall a. (k -> v -> a -> a) -> a -> m -> a)  -- ^ @foldrWithKey@ - indexed fold
    -> m                                              -- ^ container
    -> Encoding
dict :: (k -> Encoding' Key)
-> (v -> Encoding)
-> (forall a. (k -> v -> a -> a) -> a -> m -> a)
-> m
-> Encoding
dict k -> Encoding' Key
encodeKey v -> Encoding
encodeVal forall a. (k -> v -> a -> a) -> a -> m -> a
foldrWithKey = Series -> Encoding
pairs (Series -> Encoding) -> (m -> Series) -> m -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (k -> v -> Series -> Series) -> Series -> m -> Series
forall a. (k -> v -> a -> a) -> a -> m -> a
foldrWithKey k -> v -> Series -> Series
go Series
forall a. Monoid a => a
mempty
  where
    go :: k -> v -> Series -> Series
go k
k v
v Series
c = Encoding' Series -> Series
Value (k -> v -> Encoding' Series
forall a. k -> v -> Encoding' a
encodeKV k
k v
v) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<> Series
c
    encodeKV :: k -> v -> Encoding' a
encodeKV k
k v
v = Encoding' Key -> Encoding' a
forall a b. Encoding' a -> Encoding' b
retagEncoding (k -> Encoding' Key
encodeKey k
k) Encoding' a -> Encoding' a -> Encoding' a
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding' a
forall a. Encoding' a
colon Encoding' a -> Encoding' a -> Encoding' a
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding -> Encoding' a
forall a b. Encoding' a -> Encoding' b
retagEncoding (v -> Encoding
encodeVal v
v)
{-# INLINE dict #-}

-- | Type tag for tuples contents, see 'tuple'.
data InArray

infixr 6 >*<
-- | See 'tuple'.
(>*<) :: Encoding' a -> Encoding' b -> Encoding' InArray
Encoding' a
a >*< :: Encoding' a -> Encoding' b -> Encoding' InArray
>*< Encoding' b
b = Encoding' a -> Encoding' InArray
forall a b. Encoding' a -> Encoding' b
retagEncoding Encoding' a
a Encoding' InArray -> Encoding' InArray -> Encoding' InArray
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding' InArray
forall a. Encoding' a
comma Encoding' InArray -> Encoding' InArray -> Encoding' InArray
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding' b -> Encoding' InArray
forall a b. Encoding' a -> Encoding' b
retagEncoding Encoding' b
b
{-# INLINE (>*<) #-}

empty :: Encoding' a
empty :: Encoding' a
empty = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding Builder
forall a. Monoid a => a
mempty

econcat :: [Encoding' a] -> Encoding' a
econcat :: [Encoding' a] -> Encoding' a
econcat = (Encoding' a -> Encoding' a -> Encoding' a)
-> Encoding' a -> [Encoding' a] -> Encoding' a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Encoding' a -> Encoding' a -> Encoding' a
forall a. Encoding' a -> Encoding' a -> Encoding' a
(><) Encoding' a
forall a. Encoding' a
empty

infixr 6 ><
(><) :: Encoding' a -> Encoding' a -> Encoding' a
Encoding Builder
a >< :: Encoding' a -> Encoding' a -> Encoding' a
>< Encoding Builder
b = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
b)
{-# INLINE (><) #-}

-- | Encode as a tuple.
--
-- @
-- toEncoding (X a b c) = tuple $
--     toEncoding a >*<
--     toEncoding b >*<
--     toEncoding c
tuple :: Encoding' InArray -> Encoding
tuple :: Encoding' InArray -> Encoding
tuple Encoding' InArray
b = Encoding' InArray -> Encoding
forall a b. Encoding' a -> Encoding' b
retagEncoding (Encoding' InArray -> Encoding) -> Encoding' InArray -> Encoding
forall a b. (a -> b) -> a -> b
$ Encoding' InArray
forall a. Encoding' a
openBracket Encoding' InArray -> Encoding' InArray -> Encoding' InArray
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding' InArray
b Encoding' InArray -> Encoding' InArray -> Encoding' InArray
forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding' InArray
forall a. Encoding' a
closeBracket
{-# INLINE tuple #-}

key :: Key -> Encoding' a
key :: Key -> Encoding' a
key = Text -> Encoding' a
forall a. Text -> Encoding' a
text (Text -> Encoding' a) -> (Key -> Text) -> Key -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Text
Key.toText

text :: Text -> Encoding' a
text :: Text -> Encoding' a
text = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Text -> Builder) -> Text -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Builder
EB.text

lazyText :: LT.Text -> Encoding' a
lazyText :: Text -> Encoding' a
lazyText Text
t = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$
    Char -> Builder
B.char7 Char
'"' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
    (Text -> Builder -> Builder) -> Builder -> Text -> Builder
forall a. (Text -> a -> a) -> a -> Text -> a
LT.foldrChunks (\Text
x Builder
xs -> Text -> Builder
EB.unquoted Text
x Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
xs) (Char -> Builder
B.char7 Char
'"') Text
t

-- | @since 2.0.2.0
shortText :: ST.ShortText -> Encoding' a
shortText :: ShortText -> Encoding' a
shortText ShortText
t = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$
    Char -> Builder
B.char7 Char
'"' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
    -- TODO: if we can determine whether all characters are >=0x20 && <0x80
    -- we could use underlying ShortByteString directly.
    Text -> Builder
EB.unquoted (ShortText -> Text
ST.toText ShortText
t) Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
B.char7 Char
'"'

string :: String -> Encoding' a
string :: String -> Encoding' a
string = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (String -> Builder) -> String -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Builder
EB.string

-------------------------------------------------------------------------------
-- chars
-------------------------------------------------------------------------------

comma, colon, openBracket, closeBracket, openCurly, closeCurly :: Encoding' a
comma :: Encoding' a
comma        = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Char -> Builder
char7 Char
','
colon :: Encoding' a
colon        = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Char -> Builder
char7 Char
':'
openBracket :: Encoding' a
openBracket  = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Char -> Builder
char7 Char
'['
closeBracket :: Encoding' a
closeBracket = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Char -> Builder
char7 Char
']'
openCurly :: Encoding' a
openCurly    = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Char -> Builder
char7 Char
'{'
closeCurly :: Encoding' a
closeCurly   = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Char -> Builder
char7 Char
'}'

-------------------------------------------------------------------------------
-- Decimal numbers
-------------------------------------------------------------------------------

int8 :: Int8 -> Encoding
int8 :: Int8 -> Encoding
int8 = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Int8 -> Builder) -> Int8 -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int8 -> Builder
B.int8Dec

int16 :: Int16 -> Encoding
int16 :: Int16 -> Encoding
int16 = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Int16 -> Builder) -> Int16 -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int16 -> Builder
B.int16Dec

int32 :: Int32 -> Encoding
int32 :: Int32 -> Encoding
int32 = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Int32 -> Builder) -> Int32 -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Builder
B.int32Dec

int64 :: Int64 -> Encoding
int64 :: Int64 -> Encoding
int64 = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Int64 -> Builder) -> Int64 -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Builder
B.int64Dec

int :: Int -> Encoding
int :: Int -> Encoding
int = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Int -> Builder) -> Int -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Builder
B.intDec

word8 :: Word8 -> Encoding
word8 :: Word8 -> Encoding
word8 = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Word8 -> Builder) -> Word8 -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Builder
B.word8Dec

word16 :: Word16 -> Encoding
word16 :: Word16 -> Encoding
word16 = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Word16 -> Builder) -> Word16 -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Builder
B.word16Dec

word32 :: Word32 -> Encoding
word32 :: Word32 -> Encoding
word32 = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Word32 -> Builder) -> Word32 -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Builder
B.word32Dec

word64 :: Word64 -> Encoding
word64 :: Word64 -> Encoding
word64 = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Word64 -> Builder) -> Word64 -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Builder
B.word64Dec

word :: Word -> Encoding
word :: Word -> Encoding
word = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Word -> Builder) -> Word -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> Builder
B.wordDec

integer :: Integer -> Encoding
integer :: Integer -> Encoding
integer = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding)
-> (Integer -> Builder) -> Integer -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Builder
B.integerDec

float :: Float -> Encoding
float :: Float -> Encoding
float = (Float -> Encoding) -> Float -> Encoding
forall a. RealFloat a => (a -> Encoding) -> a -> Encoding
realFloatToEncoding ((Float -> Encoding) -> Float -> Encoding)
-> (Float -> Encoding) -> Float -> Encoding
forall a b. (a -> b) -> a -> b
$ Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Float -> Builder) -> Float -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Builder
B.floatDec

-- |
--
-- >>> double 42
-- "42.0"
--
-- >>> double (0/0)
-- "null"
--
-- >>> double (1/0)
-- "\"+inf\""
--
-- >>> double (-23/0)
-- "\"-inf\""
--
double :: Double -> Encoding
double :: Double -> Encoding
double = (Double -> Encoding) -> Double -> Encoding
forall a. RealFloat a => (a -> Encoding) -> a -> Encoding
realFloatToEncoding ((Double -> Encoding) -> Double -> Encoding)
-> (Double -> Encoding) -> Double -> Encoding
forall a b. (a -> b) -> a -> b
$ Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Double -> Builder) -> Double -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Builder
B.doubleDec

scientific :: Scientific -> Encoding
scientific :: Scientific -> Encoding
scientific = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding)
-> (Scientific -> Builder) -> Scientific -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> Builder
EB.scientific

realFloatToEncoding :: RealFloat a => (a -> Encoding) -> a -> Encoding
realFloatToEncoding :: (a -> Encoding) -> a -> Encoding
realFloatToEncoding a -> Encoding
e a
d
    | a -> Bool
forall a. RealFloat a => a -> Bool
isNaN a
d      = Encoding
null_
    | a -> Bool
forall a. RealFloat a => a -> Bool
isInfinite a
d = if a
d a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0 then Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding Builder
"\"+inf\"" else Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding Builder
"\"-inf\""
    | Bool
otherwise    = a -> Encoding
e a
d
{-# INLINE realFloatToEncoding #-}

-------------------------------------------------------------------------------
-- Decimal numbers as Text
-------------------------------------------------------------------------------

int8Text :: Int8 -> Encoding' a
int8Text :: Int8 -> Encoding' a
int8Text = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Int8 -> Builder) -> Int8 -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Int8 -> Builder) -> Int8 -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int8 -> Builder
B.int8Dec

int16Text :: Int16 -> Encoding' a
int16Text :: Int16 -> Encoding' a
int16Text = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Int16 -> Builder) -> Int16 -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Int16 -> Builder) -> Int16 -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int16 -> Builder
B.int16Dec

int32Text :: Int32 -> Encoding' a
int32Text :: Int32 -> Encoding' a
int32Text = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Int32 -> Builder) -> Int32 -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Int32 -> Builder) -> Int32 -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Builder
B.int32Dec

int64Text :: Int64 -> Encoding' a
int64Text :: Int64 -> Encoding' a
int64Text = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Int64 -> Builder) -> Int64 -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Int64 -> Builder) -> Int64 -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Builder
B.int64Dec

intText :: Int -> Encoding' a
intText :: Int -> Encoding' a
intText = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a) -> (Int -> Builder) -> Int -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Int -> Builder) -> Int -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Builder
B.intDec

word8Text :: Word8 -> Encoding' a
word8Text :: Word8 -> Encoding' a
word8Text = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Word8 -> Builder) -> Word8 -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Word8 -> Builder) -> Word8 -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Builder
B.word8Dec

word16Text :: Word16 -> Encoding' a
word16Text :: Word16 -> Encoding' a
word16Text = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Word16 -> Builder) -> Word16 -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Word16 -> Builder) -> Word16 -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Builder
B.word16Dec

word32Text :: Word32 -> Encoding' a
word32Text :: Word32 -> Encoding' a
word32Text = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Word32 -> Builder) -> Word32 -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Word32 -> Builder) -> Word32 -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Builder
B.word32Dec

word64Text :: Word64 -> Encoding' a
word64Text :: Word64 -> Encoding' a
word64Text = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Word64 -> Builder) -> Word64 -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Word64 -> Builder) -> Word64 -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Builder
B.word64Dec

wordText :: Word -> Encoding' a
wordText :: Word -> Encoding' a
wordText = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Word -> Builder) -> Word -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Word -> Builder) -> Word -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> Builder
B.wordDec

integerText :: Integer -> Encoding' a
integerText :: Integer -> Encoding' a
integerText = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Integer -> Builder) -> Integer -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Integer -> Builder) -> Integer -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Builder
B.integerDec

floatText :: Float -> Encoding' a
floatText :: Float -> Encoding' a
floatText Float
d
    | Float -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Float
d = if Float
d Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
0 then Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding Builder
"\"+inf\"" else Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding Builder
"\"-inf\""
    | Bool
otherwise = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Float -> Builder) -> Float -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Float -> Builder) -> Float -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Builder
B.floatDec (Float -> Encoding' a) -> Float -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Float
d

-- |
--
-- >>> doubleText 42
-- "\"42.0\""
--
-- >>> doubleText (0/0)
-- "\"NaN\""
--
-- >>> doubleText (1/0)
-- "\"+inf\""
--
-- >>> doubleText (-23/0)
-- "\"-inf\""
--
doubleText :: Double -> Encoding' a
doubleText :: Double -> Encoding' a
doubleText Double
d
    | Double -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Double
d = if Double
d Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
0 then Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding Builder
"\"+inf\"" else Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding Builder
"\"-inf\""
    | Bool
otherwise = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Double -> Builder) -> Double -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Double -> Builder) -> Double -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Builder
B.doubleDec (Double -> Encoding' a) -> Double -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Double
d

scientificText :: Scientific -> Encoding' a
scientificText :: Scientific -> Encoding' a
scientificText = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Scientific -> Builder) -> Scientific -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder)
-> (Scientific -> Builder) -> Scientific -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> Builder
EB.scientific

-------------------------------------------------------------------------------
-- time
-------------------------------------------------------------------------------

day :: Day -> Encoding' a
day :: Day -> Encoding' a
day = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a) -> (Day -> Builder) -> Day -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Day -> Builder) -> Day -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Builder
EB.day

month :: Month -> Encoding' a
month :: Month -> Encoding' a
month = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Month -> Builder) -> Month -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Month -> Builder) -> Month -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Month -> Builder
EB.month

quarter :: Quarter -> Encoding' a
quarter :: Quarter -> Encoding' a
quarter = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (Quarter -> Builder) -> Quarter -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (Quarter -> Builder) -> Quarter -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Quarter -> Builder
EB.quarter

localTime :: LocalTime -> Encoding' a
localTime :: LocalTime -> Encoding' a
localTime = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (LocalTime -> Builder) -> LocalTime -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder)
-> (LocalTime -> Builder) -> LocalTime -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LocalTime -> Builder
EB.localTime

utcTime :: UTCTime -> Encoding' a
utcTime :: UTCTime -> Encoding' a
utcTime = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (UTCTime -> Builder) -> UTCTime -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder) -> (UTCTime -> Builder) -> UTCTime -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> Builder
EB.utcTime

timeOfDay :: TimeOfDay -> Encoding' a
timeOfDay :: TimeOfDay -> Encoding' a
timeOfDay = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (TimeOfDay -> Builder) -> TimeOfDay -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder)
-> (TimeOfDay -> Builder) -> TimeOfDay -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeOfDay -> Builder
EB.timeOfDay

zonedTime :: ZonedTime -> Encoding' a
zonedTime :: ZonedTime -> Encoding' a
zonedTime = Builder -> Encoding' a
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding' a)
-> (ZonedTime -> Builder) -> ZonedTime -> Encoding' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Builder
EB.quote (Builder -> Builder)
-> (ZonedTime -> Builder) -> ZonedTime -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> Builder
EB.zonedTime

-------------------------------------------------------------------------------
-- Value
-------------------------------------------------------------------------------

value :: Value -> Encoding
value :: Value -> Encoding
value = Builder -> Encoding
forall tag. Builder -> Encoding' tag
Encoding (Builder -> Encoding) -> (Value -> Builder) -> Value -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Builder
EB.encodeToBuilder