{-| This library provides utilities for converting Dhall source code into a
    normalized AST
-}

module Dhall.Toml.Utils
    ( fileToDhall
    , inputToDhall
    , textToDhall
    ) where

import Data.Text    (Text)
import Data.Void    (Void)
import Dhall.Import (SemanticCacheMode(..))
import Dhall.Parser (Src)

import qualified Data.Text.IO    as Text.IO
import qualified Dhall.Core      as Core
import qualified Dhall.Import
import qualified Dhall.Parser
import qualified Dhall.TypeCheck
import qualified System.FilePath as FilePath

-- | Read the file fileName and return the normalized Dhall AST
fileToDhall :: String -> IO (Core.Expr Src Void)
fileToDhall :: String -> IO (Expr Src X)
fileToDhall String
fileName = do
    Text
text <- String -> IO Text
Text.IO.readFile String
fileName
    String -> Text -> IO (Expr Src X)
textToDhall String
fileName Text
text

-- | Read from STDIN and return the normalized Dhall AST. The file name
--   is set to "(input)"
inputToDhall :: IO (Core.Expr Src Void)
inputToDhall :: IO (Expr Src X)
inputToDhall = do
    Text
text <- IO Text
Text.IO.getContents
    String -> Text -> IO (Expr Src X)
textToDhall String
"(input)" Text
text

-- | Parse text and return the normalized Dhall AST. A file name is required
--   by the parser for generating error messages.
textToDhall :: String -> Text -> IO (Core.Expr Src Void)
textToDhall :: String -> Text -> IO (Expr Src X)
textToDhall String
fileName Text
text = do
    Expr Src Import
parsedExpression <- do
        Either ParseError (Expr Src Import) -> IO (Expr Src Import)
forall e (io :: * -> *) a.
(Exception e, MonadIO io) =>
Either e a -> io a
Core.throws (String -> Text -> Either ParseError (Expr Src Import)
Dhall.Parser.exprFromText String
fileName Text
text)

    let directory :: String
directory = String -> String
FilePath.takeDirectory String
fileName

    Expr Src X
resolvedExpression <- do
        String -> SemanticCacheMode -> Expr Src Import -> IO (Expr Src X)
Dhall.Import.loadRelativeTo String
directory SemanticCacheMode
UseSemanticCache Expr Src Import
parsedExpression

    Expr Src X
_ <- Either (TypeError Src X) (Expr Src X) -> IO (Expr Src X)
forall e (io :: * -> *) a.
(Exception e, MonadIO io) =>
Either e a -> io a
Core.throws (Expr Src X -> Either (TypeError Src X) (Expr Src X)
forall s. Expr s X -> Either (TypeError s X) (Expr s X)
Dhall.TypeCheck.typeOf Expr Src X
resolvedExpression)

    Expr Src X -> IO (Expr Src X)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Expr Src X
resolvedExpression