{-# LANGUAGE EmptyDataDecls #-}
{-# 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 Data.Aeson.Internal.Prelude hiding (empty)

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.Time (Day, LocalTime, TimeOfDay, ZonedTime)
import Data.Time.Calendar.Month.Compat (Month)
import Data.Time.Calendar.Quarter.Compat (Quarter)
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 {
      forall tag. 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 :: forall a. Builder -> Encoding' a
unsafeToEncoding = Builder -> Encoding' a
forall a. Builder -> Encoding' a
Encoding

encodingToLazyByteString :: Encoding' a -> BSL.ByteString
encodingToLazyByteString :: forall a. 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 :: forall a b. Encoding' a -> Encoding' b
retagEncoding = Builder -> Encoding' b
forall a. Builder -> Encoding' a
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)

-- | @since 2.2.0.0
instance IsString (Encoding' a) where
  fromString :: String -> Encoding' a
fromString = String -> Encoding' a
forall a. String -> Encoding' a
string

-- | 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 a. Builder -> Encoding' a
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 :: forall a. 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 a. Builder -> Encoding' a
Encoding Builder
EB.emptyArray_

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

wrapArray :: Encoding' a -> Encoding
wrapArray :: forall a. 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 :: forall a. 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 a. Builder -> Encoding' a
Encoding Builder
EB.null_

bool :: Bool -> Encoding
bool :: Bool -> Encoding
bool Bool
True = Builder -> Encoding
forall a. Builder -> Encoding' a
Encoding Builder
"true"
bool Bool
False = Builder -> Encoding
forall a. Builder -> Encoding' a
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 :: forall a. (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 a b. (a -> b -> b) -> b -> [a] -> b
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 :: forall k v m.
(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 >*< :: forall a b. 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 :: forall a. Encoding' a
empty = Builder -> Encoding' a
forall a. Builder -> Encoding' a
Encoding Builder
forall a. Monoid a => a
mempty

econcat :: [Encoding' a] -> Encoding' a
econcat :: forall a. [Encoding' a] -> Encoding' a
econcat = (Encoding' a -> Encoding' a -> Encoding' a)
-> Encoding' a -> [Encoding' a] -> Encoding' a
forall a b. (a -> b -> b) -> b -> [a] -> b
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 >< :: forall a. Encoding' a -> Encoding' a -> Encoding' a
>< Encoding Builder
b = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. 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 :: forall a. Text -> Encoding' a
text = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Text -> Encoding' a
lazyText Text
t = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. ShortText -> Encoding' a
shortText ShortText
t = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. String -> Encoding' a
string = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Encoding' a
comma        = Builder -> Encoding' a
forall a. Builder -> Encoding' a
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Char -> Builder
char7 Char
','
colon :: forall a. Encoding' a
colon        = Builder -> Encoding' a
forall a. Builder -> Encoding' a
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Char -> Builder
char7 Char
':'
openBracket :: forall a. Encoding' a
openBracket  = Builder -> Encoding' a
forall a. Builder -> Encoding' a
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Char -> Builder
char7 Char
'['
closeBracket :: forall a. Encoding' a
closeBracket = Builder -> Encoding' a
forall a. Builder -> Encoding' a
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Char -> Builder
char7 Char
']'
openCurly :: forall a. Encoding' a
openCurly    = Builder -> Encoding' a
forall a. Builder -> Encoding' a
Encoding (Builder -> Encoding' a) -> Builder -> Encoding' a
forall a b. (a -> b) -> a -> b
$ Char -> Builder
char7 Char
'{'
closeCurly :: forall a. Encoding' a
closeCurly   = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
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 :: forall a. RealFloat a => (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 a. Builder -> Encoding' a
Encoding Builder
"\"+inf\"" else Builder -> Encoding
forall a. Builder -> Encoding' a
Encoding Builder
"\"-inf\""
    | Bool
otherwise    = a -> Encoding
e a
d
{-# INLINE realFloatToEncoding #-}

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

int8Text :: Int8 -> Encoding' a
int8Text :: forall a. Int8 -> Encoding' a
int8Text = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Int16 -> Encoding' a
int16Text = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Int32 -> Encoding' a
int32Text = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Int64 -> Encoding' a
int64Text = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Int -> Encoding' a
intText = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Word8 -> Encoding' a
word8Text = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Word16 -> Encoding' a
word16Text = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Word32 -> Encoding' a
word32Text = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Word64 -> Encoding' a
word64Text = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Word -> Encoding' a
wordText = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Integer -> Encoding' a
integerText = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. 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 a. Builder -> Encoding' a
Encoding Builder
"\"+inf\"" else Builder -> Encoding' a
forall a. Builder -> Encoding' a
Encoding Builder
"\"-inf\""
    | Bool
otherwise = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. 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 a. Builder -> Encoding' a
Encoding Builder
"\"+inf\"" else Builder -> Encoding' a
forall a. Builder -> Encoding' a
Encoding Builder
"\"-inf\""
    | Bool
otherwise = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Scientific -> Encoding' a
scientificText = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Day -> Encoding' a
day = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Month -> Encoding' a
month = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. Quarter -> Encoding' a
quarter = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. LocalTime -> Encoding' a
localTime = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. UTCTime -> Encoding' a
utcTime = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. TimeOfDay -> Encoding' a
timeOfDay = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 :: forall a. ZonedTime -> Encoding' a
zonedTime = Builder -> Encoding' a
forall a. Builder -> Encoding' a
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 a. Builder -> Encoding' a
Encoding (Builder -> Encoding) -> (Value -> Builder) -> Value -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Builder
EB.encodeToBuilder