module Argo.Encode where

import qualified Argo.Class.ToValue as ToValue
import qualified Argo.Encoder as Encoder
import qualified Argo.Json.Value as Value
import qualified Argo.Literal as Literal
import qualified Argo.Vendor.Builder as Builder
import qualified Argo.Vendor.Transformers as Trans
import qualified Control.Monad as Monad
import qualified Data.Functor.Identity as Identity

encode :: ToValue.ToValue a => a -> Builder.Builder
encode :: a -> Builder
encode = Indent -> a -> Builder
forall a. ToValue a => Indent -> a -> Builder
encodeWith (Indent -> a -> Builder) -> Indent -> a -> Builder
forall a b. (a -> b) -> a -> b
$ Int -> Indent
Encoder.Spaces Int
0

encodeWith :: ToValue.ToValue a => Encoder.Indent -> a -> Builder.Builder
encodeWith :: Indent -> a -> Builder
encodeWith Indent
i a
x =
    let c :: Config
c = Config :: Indent -> Int -> Config
Encoder.Config { indent :: Indent
Encoder.indent = Indent
i, level :: Int
Encoder.level = Int
0 }
    in ((), Builder) -> Builder
forall a b. (a, b) -> b
snd
    (((), Builder) -> Builder)
-> (ReaderT Config (WriterT Builder Identity) () -> ((), Builder))
-> ReaderT Config (WriterT Builder Identity) ()
-> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identity ((), Builder) -> ((), Builder)
forall a. Identity a -> a
Identity.runIdentity
    (Identity ((), Builder) -> ((), Builder))
-> (ReaderT Config (WriterT Builder Identity) ()
    -> Identity ((), Builder))
-> ReaderT Config (WriterT Builder Identity) ()
-> ((), Builder)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WriterT Builder Identity () -> Identity ((), Builder)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
Trans.runWriterT
    (WriterT Builder Identity () -> Identity ((), Builder))
-> (ReaderT Config (WriterT Builder Identity) ()
    -> WriterT Builder Identity ())
-> ReaderT Config (WriterT Builder Identity) ()
-> Identity ((), Builder)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ReaderT Config (WriterT Builder Identity) ()
 -> Config -> WriterT Builder Identity ())
-> Config
-> ReaderT Config (WriterT Builder Identity) ()
-> WriterT Builder Identity ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT Config (WriterT Builder Identity) ()
-> Config -> WriterT Builder Identity ()
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
Trans.runReaderT Config
c
    (ReaderT Config (WriterT Builder Identity) () -> Builder)
-> ReaderT Config (WriterT Builder Identity) () -> Builder
forall a b. (a -> b) -> a -> b
$ do
        Value -> ReaderT Config (WriterT Builder Identity) ()
Value.encode (Value -> ReaderT Config (WriterT Builder Identity) ())
-> Value -> ReaderT Config (WriterT Builder Identity) ()
forall a b. (a -> b) -> a -> b
$ a -> Value
forall a. ToValue a => a -> Value
ToValue.toValue a
x
        Bool
-> ReaderT Config (WriterT Builder Identity) ()
-> ReaderT Config (WriterT Builder Identity) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
Monad.when (Config -> Bool
Encoder.hasIndent Config
c)
            (ReaderT Config (WriterT Builder Identity) ()
 -> ReaderT Config (WriterT Builder Identity) ())
-> (Builder -> ReaderT Config (WriterT Builder Identity) ())
-> Builder
-> ReaderT Config (WriterT Builder Identity) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WriterT Builder Identity ()
-> ReaderT Config (WriterT Builder Identity) ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
Trans.lift
            (WriterT Builder Identity ()
 -> ReaderT Config (WriterT Builder Identity) ())
-> (Builder -> WriterT Builder Identity ())
-> Builder
-> ReaderT Config (WriterT Builder Identity) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> WriterT Builder Identity ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
Trans.tell
            (Builder -> ReaderT Config (WriterT Builder Identity) ())
-> Builder -> ReaderT Config (WriterT Builder Identity) ()
forall a b. (a -> b) -> a -> b
$ Word8 -> Builder
Builder.word8 Word8
Literal.newLine