module Argo.Encode where

import qualified Argo.Class.HasCodec as HasCodec
import qualified Argo.Codec.Value as Codec
import qualified Argo.Json.Value as Value
import qualified Argo.Literal as Literal
import qualified Argo.Pointer.Pointer as Pointer
import qualified Argo.Type.Config as Config
import qualified Argo.Type.Encoder as Encoder
import qualified Argo.Type.Indent as Indent
import qualified Argo.Vendor.Builder as Builder
import qualified Argo.Vendor.Transformers as Trans
import qualified Control.Monad as Monad

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

encodeWith :: HasCodec.HasCodec a => Indent.Indent -> a -> Builder.Builder
encodeWith :: Indent -> a -> Builder
encodeWith Indent
i a
x =
    let c :: Config
c = Config
Config.initial { indent :: Indent
Config.indent = Indent
i }
    in
        Config -> Encoder () -> Builder
forall a. Config -> Encoder a -> Builder
Encoder.run Config
c (Encoder () -> Builder) -> Encoder () -> Builder
forall a b. (a -> b) -> a -> b
$ do
            Value -> Encoder ()
Value.encode (Value -> Encoder ()) -> Value -> Encoder ()
forall a b. (a -> b) -> a -> b
$ Value a -> a -> Value
forall a. Value a -> a -> Value
Codec.encodeWith Value a
forall a. HasCodec a => Value a
HasCodec.codec a
x
            Bool -> Encoder () -> Encoder ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
Monad.when (Config -> Bool
Config.hasIndent Config
c)
                (Encoder () -> Encoder ())
-> (Builder -> Encoder ()) -> Builder -> Encoder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WriterT Builder Identity () -> Encoder ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
Trans.lift
                (WriterT Builder Identity () -> Encoder ())
-> (Builder -> WriterT Builder Identity ())
-> Builder
-> Encoder ()
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 -> Encoder ()) -> Builder -> Encoder ()
forall a b. (a -> b) -> a -> b
$ Word8 -> Builder
Builder.word8 Word8
Literal.newLine

encodePointer :: Pointer.Pointer -> Builder.Builder
encodePointer :: Pointer -> Builder
encodePointer = Config -> Encoder () -> Builder
forall a. Config -> Encoder a -> Builder
Encoder.run Config
Config.initial (Encoder () -> Builder)
-> (Pointer -> Encoder ()) -> Pointer -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pointer -> Encoder ()
Pointer.encode