{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}

-- |
module Language.Jsonnet.Manifest where

import Control.Monad.Except
import Data.Aeson (FromJSON (..))
import qualified Data.Aeson as JSON
import Data.HashMap.Lazy (HashMap)
import qualified Data.HashMap.Lazy as H
import Data.Text (Text)
import Data.Vector (Vector)
import Debug.Trace
import Language.Jsonnet.Common
import Language.Jsonnet.Error
import Language.Jsonnet.Eval.Monad
import Language.Jsonnet.Value

manifest :: Value -> Eval JSON.Value
manifest :: Value -> Eval Value
manifest =
  \case
    Value
VNull -> Value -> Eval Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value
JSON.Null
    VBool Bool
b -> Value -> Eval Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Value -> Eval Value) -> Value -> Eval Value
forall a b. (a -> b) -> a -> b
$ Bool -> Value
JSON.Bool Bool
b
    VNum Scientific
n -> Value -> Eval Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Value -> Eval Value) -> Value -> Eval Value
forall a b. (a -> b) -> a -> b
$ Scientific -> Value
JSON.Number Scientific
n
    VStr Text
s -> Value -> Eval Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Value -> Eval Value) -> Value -> Eval Value
forall a b. (a -> b) -> a -> b
$ Text -> Value
JSON.String Text
s
    VArr Array
a -> Array -> Value
JSON.Array (Array -> Value) -> Eval Array -> Eval Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Array -> Eval Array
forceArray Array
a
    VObj HashMap Text (Hideable Thunk)
o -> Object -> Value
JSON.Object (Object -> Value) -> Eval Object -> Eval Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HashMap Text (Hideable Thunk) -> Eval Object
forceObject HashMap Text (Hideable Thunk)
o
    VClos {} -> EvalError -> Eval Value
forall a. EvalError -> Eval a
throwE (Doc -> EvalError
ManifestError Doc
"function")
    VFun Thunk -> Eval Value
_ -> EvalError -> Eval Value
forall a. EvalError -> Eval a
throwE (Doc -> EvalError
ManifestError Doc
"function")

forceArray :: Vector Thunk -> Eval (Vector JSON.Value)
forceArray :: Array -> Eval Array
forceArray = (Thunk -> Eval Value) -> Array -> Eval Array
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (Thunk -> Eval Value
force (Thunk -> Eval Value)
-> (Value -> Eval Value) -> Thunk -> Eval Value
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Value -> Eval Value
manifest)

forceObject :: Object -> Eval (HashMap Text JSON.Value)
forceObject :: HashMap Text (Hideable Thunk) -> Eval Object
forceObject = (Thunk -> Eval Value) -> HashMap Text Thunk -> Eval Object
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (Thunk -> Eval Value
force (Thunk -> Eval Value)
-> (Value -> Eval Value) -> Thunk -> Eval Value
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Value -> Eval Value
manifest) (HashMap Text Thunk -> Eval Object)
-> (HashMap Text (Hideable Thunk) -> HashMap Text Thunk)
-> HashMap Text (Hideable Thunk)
-> Eval Object
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap Text (Hideable Thunk) -> HashMap Text Thunk
visibleKeys

visibleKeys :: Object -> HashMap Text Thunk
visibleKeys :: HashMap Text (Hideable Thunk) -> HashMap Text Thunk
visibleKeys HashMap Text (Hideable Thunk)
o =
  [(Text, Thunk)] -> HashMap Text Thunk
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
H.fromList [(Text
k, Thunk
v) | (Text
k, vv :: Hideable Thunk
vv@(Hideable Thunk
v Visibility
_)) <- [(Text, Hideable Thunk)]
xs, Bool -> Bool
not (Hideable Thunk -> Bool
forall a. HasVisibility a => a -> Bool
hidden Hideable Thunk
vv)]
  where
    xs :: [(Text, Hideable Thunk)]
xs = HashMap Text (Hideable Thunk) -> [(Text, Hideable Thunk)]
forall k v. HashMap k v -> [(k, v)]
H.toList HashMap Text (Hideable Thunk)
o