module Jsonifier
(
toByteString,
toWrite,
Json,
null,
true,
false,
bool,
intNumber,
wordNumber,
doubleNumber,
scientificNumber,
textString,
scientificString,
array,
object,
fromByteString,
fromWrite,
)
where
import qualified Data.ByteString as ByteString
import qualified Data.ByteString.Internal as ByteString
import qualified Jsonifier.Poke as Poke
import Jsonifier.Prelude hiding (bool, null)
import qualified Jsonifier.Size as Size
import qualified Jsonifier.Write as Write
import PtrPoker.Poke (Poke)
import qualified PtrPoker.Poke as Poke
import PtrPoker.Write (Write)
import qualified PtrPoker.Write as Write
{-# INLINE toByteString #-}
toByteString :: Json -> ByteString
toByteString :: Json -> ByteString
toByteString =
Write -> ByteString
Write.writeToByteString forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. coerce :: forall a b. Coercible a b => a -> b
coerce
{-# INLINE toWrite #-}
toWrite :: Json -> Write
toWrite :: Json -> Write
toWrite =
coerce :: forall a b. Coercible a b => a -> b
coerce
newtype Json
= Json Write.Write
{-# INLINE write #-}
write :: Int -> Poke.Poke -> Json
write :: Int -> Poke -> Json
write Int
size Poke
poke =
Write -> Json
Json (Int -> Poke -> Write
Write.Write Int
size Poke
poke)
{-# INLINE null #-}
null :: Json
null :: Json
null =
Int -> Poke -> Json
write Int
4 Poke
Poke.null
{-# INLINE true #-}
true :: Json
true :: Json
true =
Int -> Poke -> Json
write Int
4 Poke
Poke.true
{-# INLINE false #-}
false :: Json
false :: Json
false =
Int -> Poke -> Json
write Int
5 Poke
Poke.false
{-# INLINE bool #-}
bool :: Bool -> Json
bool :: Bool -> Json
bool =
\case
Bool
True -> Json
true
Bool
False -> Json
false
{-# INLINE intNumber #-}
intNumber :: Int -> Json
intNumber :: Int -> Json
intNumber =
Write -> Json
Json forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> Write
Write.intAsciiDec
{-# INLINE wordNumber #-}
wordNumber :: Word -> Json
wordNumber :: Word -> Json
wordNumber =
Write -> Json
Json forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Word -> Write
Write.wordAsciiDec
{-# INLINE doubleNumber #-}
doubleNumber :: Double -> Json
doubleNumber :: Double -> Json
doubleNumber =
Write -> Json
Json forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Double -> Write
Write.zeroNonRealDoubleAsciiDec
{-# INLINE scientificNumber #-}
scientificNumber :: Scientific -> Json
scientificNumber :: Scientific -> Json
scientificNumber =
Write -> Json
Json forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Scientific -> Write
Write.scientificAsciiDec
{-# INLINE textString #-}
textString :: Text -> Json
textString :: Text -> Json
textString Text
text =
let size :: Int
size =
Int
2 forall a. Num a => a -> a -> a
+ Text -> Int
Size.stringBody Text
text
poke :: Poke
poke =
Text -> Poke
Poke.string Text
text
in Int -> Poke -> Json
write Int
size Poke
poke
{-# INLINE scientificString #-}
scientificString :: Scientific -> Json
scientificString :: Scientific -> Json
scientificString =
Write -> Json
Json forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Scientific -> Write
Write.scientificString
{-# INLINE array #-}
array :: Foldable f => f Json -> Json
array :: forall (f :: * -> *). Foldable f => f Json -> Json
array f Json
foldable =
Int -> Poke -> Json
write Int
size Poke
poke
where
size :: Int
size =
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall {t} {t}. Enum t => Json -> (t -> Int -> t) -> t -> Int -> t
step Int -> Int -> Int
finalize f Json
foldable Int
0 Int
0
where
step :: Json -> (t -> Int -> t) -> t -> Int -> t
step (Json (Write.Write Int
writeSize Poke
_)) t -> Int -> t
next !t
count !Int
size =
t -> Int -> t
next (forall a. Enum a => a -> a
succ t
count) (Int
writeSize forall a. Num a => a -> a -> a
+ Int
size)
finalize :: Int -> Int -> Int
finalize Int
count Int
size =
Int -> Int -> Int
Size.array Int
count Int
size
poke :: Poke
poke =
(Ptr Word8 -> IO (Ptr Word8)) -> Poke
Poke.Poke forall a b. (a -> b) -> a -> b
$
Poke -> Ptr Word8 -> IO (Ptr Word8)
Poke.pokePtr Poke
Poke.openingSquareBracket
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall {c}.
Json -> (Bool -> Ptr Word8 -> IO c) -> Bool -> Ptr Word8 -> IO c
step forall {p}. p -> Ptr Word8 -> IO (Ptr Word8)
finalize f Json
foldable Bool
True
where
step :: Json -> (Bool -> Ptr Word8 -> IO c) -> Bool -> Ptr Word8 -> IO c
step (Json (Write.Write Int
_ Poke
poke)) Bool -> Ptr Word8 -> IO c
next Bool
first =
if Bool
first
then
Poke -> Ptr Word8 -> IO (Ptr Word8)
Poke.pokePtr Poke
poke
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Bool -> Ptr Word8 -> IO c
next Bool
False
else
Poke -> Ptr Word8 -> IO (Ptr Word8)
Poke.pokePtr Poke
Poke.comma
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Poke -> Ptr Word8 -> IO (Ptr Word8)
Poke.pokePtr Poke
poke
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Bool -> Ptr Word8 -> IO c
next Bool
False
finalize :: p -> Ptr Word8 -> IO (Ptr Word8)
finalize p
_ =
Poke -> Ptr Word8 -> IO (Ptr Word8)
Poke.pokePtr Poke
Poke.closingSquareBracket
{-# INLINE object #-}
object :: Foldable f => f (Text, Json) -> Json
object :: forall (f :: * -> *). Foldable f => f (Text, Json) -> Json
object f (Text, Json)
f =
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall {t} {t}.
(Num t, Enum t) =>
(Text, Json)
-> (Bool -> t -> Int -> Poke -> t) -> Bool -> t -> Int -> Poke -> t
step forall {p}. p -> Int -> Int -> Poke -> Json
finalize f (Text, Json)
f Bool
True Int
0 Int
0 forall a. Monoid a => a
mempty
where
step :: (Text, Json)
-> (Bool -> t -> Int -> Poke -> t) -> Bool -> t -> Int -> Poke -> t
step (Text
key, Json (Write.Write {Int
Poke
writeSize :: Write -> Int
writePoke :: Write -> Poke
writePoke :: Poke
writeSize :: Int
..})) Bool -> t -> Int -> Poke -> t
next Bool
first !t
count !Int
size !Poke
poke =
if Bool
first
then Bool -> t -> Int -> Poke -> t
next Bool
False t
1 Int
rowSize Poke
rowPoke
else
Bool -> t -> Int -> Poke -> t
next
Bool
False
(forall a. Enum a => a -> a
succ t
count)
(Int
size forall a. Num a => a -> a -> a
+ Int
rowSize)
(Poke
poke forall a. Semigroup a => a -> a -> a
<> Poke
Poke.comma forall a. Semigroup a => a -> a -> a
<> Poke
rowPoke)
where
rowSize :: Int
rowSize =
Text -> Int
Size.stringBody Text
key
forall a. Num a => a -> a -> a
+ Int
writeSize
rowPoke :: Poke
rowPoke =
Text -> Poke -> Poke
Poke.objectRow Text
key Poke
writePoke
finalize :: p -> Int -> Int -> Poke -> Json
finalize p
_ Int
count Int
contentsSize Poke
bodyPoke =
Int -> Poke -> Json
write Int
size Poke
poke
where
size :: Int
size =
Int -> Int -> Int
Size.object Int
count Int
contentsSize
poke :: Poke
poke =
Poke
Poke.openingCurlyBracket forall a. Semigroup a => a -> a -> a
<> Poke
bodyPoke forall a. Semigroup a => a -> a -> a
<> Poke
Poke.closingCurlyBracket
fromByteString :: ByteString.ByteString -> Json
fromByteString :: ByteString -> Json
fromByteString = Write -> Json
Json forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ByteString -> Write
Write.byteString
fromWrite :: Write.Write -> Json
fromWrite :: Write -> Json
fromWrite = Write -> Json
Json