module Jsonifier.Poke where

import qualified Jsonifier.Ffi as Ffi
import Jsonifier.Prelude
import qualified Jsonifier.Text as Text
import PtrPoker.Poke

null :: Poke
null :: Poke
null =
  ByteString -> Poke
byteString ByteString
"null"

{-# INLINE boolean #-}
boolean :: Bool -> Poke
boolean :: Bool -> Poke
boolean =
  Poke -> Poke -> Bool -> Poke
forall a. a -> a -> Bool -> a
bool Poke
false Poke
true

true :: Poke
true :: Poke
true =
  ByteString -> Poke
byteString ByteString
"true"

false :: Poke
false :: Poke
false =
  ByteString -> Poke
byteString ByteString
"false"

{-# INLINE string #-}
string :: Text -> Poke
string :: Text -> Poke
string =
  (ByteArray# -> Int -> Int -> Poke) -> Text -> Poke
forall x. (ByteArray# -> Int -> Int -> x) -> Text -> x
Text.destruct ((ByteArray# -> Int -> Int -> Poke) -> Text -> Poke)
-> (ByteArray# -> Int -> Int -> Poke) -> Text -> Poke
forall a b. (a -> b) -> a -> b
$ \ByteArray#
arr Int
off Int
len ->
    (Ptr Word8 -> IO (Ptr Word8)) -> Poke
Poke ((Ptr Word8 -> IO (Ptr Word8)) -> Poke)
-> (Ptr Word8 -> IO (Ptr Word8)) -> Poke
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr ->
      Ptr Word8 -> ByteArray# -> CSize -> CSize -> IO (Ptr Word8)
Ffi.encodeString Ptr Word8
ptr ByteArray#
arr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
off) (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)

-- |
-- > "key":value
{-# INLINE objectRow #-}
objectRow :: Text -> Poke -> Poke
objectRow :: Text -> Poke -> Poke
objectRow Text
keyBody Poke
valuePoke =
  Text -> Poke
string Text
keyBody Poke -> Poke -> Poke
forall a. Semigroup a => a -> a -> a
<> Poke
colon Poke -> Poke -> Poke
forall a. Semigroup a => a -> a -> a
<> Poke
valuePoke

{-# INLINE array #-}
array :: Foldable f => f Poke -> Poke
array :: f Poke -> Poke
array f Poke
f =
  (Bool, Poke) -> Poke
forall a b. (a, b) -> b
snd
    ( ((Bool, Poke) -> Poke -> (Bool, Poke))
-> (Bool, Poke) -> f Poke -> (Bool, Poke)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl'
        (\(Bool
first, Poke
acc) Poke
p -> (Bool
False, Poke
acc Poke -> Poke -> Poke
forall a. Semigroup a => a -> a -> a
<> if Bool
first then Poke
p else Poke
comma Poke -> Poke -> Poke
forall a. Semigroup a => a -> a -> a
<> Poke
p))
        (Bool
True, Poke
openingSquareBracket)
        f Poke
f
    )
    Poke -> Poke -> Poke
forall a. Semigroup a => a -> a -> a
<> Poke
closingSquareBracket

{-# INLINE object #-}
object :: Poke -> Poke
object :: Poke -> Poke
object Poke
body =
  Poke
openingCurlyBracket Poke -> Poke -> Poke
forall a. Semigroup a => a -> a -> a
<> Poke
body Poke -> Poke -> Poke
forall a. Semigroup a => a -> a -> a
<> Poke
closingCurlyBracket

{-# INLINE objectBody #-}
objectBody :: Foldable f => f Poke -> Poke
objectBody :: f Poke -> Poke
objectBody =
  ((Bool, Poke) -> Poke -> (Bool, Poke))
-> (Bool, Poke) -> f Poke -> (Bool, Poke)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl'
    (\(Bool
first, Poke
acc) Poke
p -> (Bool
False, Poke
acc Poke -> Poke -> Poke
forall a. Semigroup a => a -> a -> a
<> if Bool
first then Poke
p else Poke
comma Poke -> Poke -> Poke
forall a. Semigroup a => a -> a -> a
<> Poke
p))
    (Bool
True, Poke
forall a. Monoid a => a
mempty)
    (f Poke -> (Bool, Poke))
-> ((Bool, Poke) -> Poke) -> f Poke -> Poke
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (Bool, Poke) -> Poke
forall a b. (a, b) -> b
snd

emptyArray :: Poke
emptyArray :: Poke
emptyArray =
  ByteString -> Poke
byteString ByteString
"[]"

emptyObject :: Poke
emptyObject :: Poke
emptyObject =
  ByteString -> Poke
byteString ByteString
"{}"

openingSquareBracket :: Poke
openingSquareBracket :: Poke
openingSquareBracket =
  Word8 -> Poke
word8 Word8
91

closingSquareBracket :: Poke
closingSquareBracket :: Poke
closingSquareBracket =
  Word8 -> Poke
word8 Word8
93

openingCurlyBracket :: Poke
openingCurlyBracket :: Poke
openingCurlyBracket =
  Word8 -> Poke
word8 Word8
123

closingCurlyBracket :: Poke
closingCurlyBracket :: Poke
closingCurlyBracket =
  Word8 -> Poke
word8 Word8
125

colon :: Poke
colon :: Poke
colon =
  Word8 -> Poke
word8 Word8
58

comma :: Poke
comma :: Poke
comma =
  Word8 -> Poke
word8 Word8
44

doubleQuote :: Poke
doubleQuote :: Poke
doubleQuote =
  Word8 -> Poke
word8 Word8
34