{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

-- | Functionality to Generate Haskell Code out of an OpenAPI definition File
module OpenAPI.Generate where

import Data.Text (Text)
import qualified Data.Text as T
import Data.Yaml
import qualified OpenAPI.Generate.IO as OAI
import qualified OpenAPI.Generate.OptParse as OAO
import qualified OpenAPI.Generate.Types as OAT
import System.Exit

-- | Decodes an OpenAPI File
decodeOpenApi :: Text -> IO OAT.OpenApiSpecification
decodeOpenApi :: Text -> IO OpenApiSpecification
decodeOpenApi Text
fileName = do
  Either ParseException OpenApiSpecification
res <- String -> IO (Either ParseException OpenApiSpecification)
forall a. FromJSON a => String -> IO (Either ParseException a)
decodeFileEither (String -> IO (Either ParseException OpenApiSpecification))
-> String -> IO (Either ParseException OpenApiSpecification)
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
fileName
  case Either ParseException OpenApiSpecification
res of
    Left ParseException
exc -> String -> IO OpenApiSpecification
forall a. String -> IO a
die (String -> IO OpenApiSpecification)
-> String -> IO OpenApiSpecification
forall a b. (a -> b) -> a -> b
$ String
"Could not parse OpenAPI specification '" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
fileName String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"': " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> ParseException -> String
forall a. Show a => a -> String
show ParseException
exc
    Right OpenApiSpecification
o -> OpenApiSpecification -> IO OpenApiSpecification
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure OpenApiSpecification
o

-- | Run the generator as CLI
runGenerator :: IO ()
runGenerator :: IO ()
runGenerator = do
  Settings
settings <- IO Settings
OAO.getSettings
  OpenApiSpecification
spec <- Text -> IO OpenApiSpecification
decodeOpenApi (Text -> IO OpenApiSpecification)
-> Text -> IO OpenApiSpecification
forall a b. (a -> b) -> a -> b
$ Settings -> Text
OAO.settingOpenApiSpecification Settings
settings
  outFiles :: OutputFiles
outFiles@OAI.OutputFiles {FilesWithContent
outputFilesModuleFiles :: FilesWithContent
outputFilesCabalFiles :: FilesWithContent
outputFilesStackFiles :: FilesWithContent
outputFilesNixFiles :: FilesWithContent
outputFilesModuleFiles :: OutputFiles -> FilesWithContent
outputFilesCabalFiles :: OutputFiles -> FilesWithContent
outputFilesStackFiles :: OutputFiles -> FilesWithContent
outputFilesNixFiles :: OutputFiles -> FilesWithContent
..} <- OpenApiSpecification -> Settings -> IO OutputFiles
OAI.generateFilesToCreate OpenApiSpecification
spec Settings
settings
  if Settings -> Bool
OAO.settingDryRun Settings
settings
    then
      ((String, String) -> IO ()) -> FilesWithContent -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_
        ( \(String
file, String
content) -> do
            String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"File: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
file
            String -> IO ()
putStrLn String
"---"
            String -> IO ()
putStrLn String
content
            String -> IO ()
putStrLn String
"---\n\n"
        )
        FilesWithContent
outputFilesModuleFiles
    else do
      Bool
proceed <- Settings -> IO Bool
OAI.permitProceed Settings
settings
      if Bool
proceed
        then do
          Settings -> OutputFiles -> IO ()
OAI.writeFiles Settings
settings OutputFiles
outFiles
          String -> IO ()
putStrLn String
"finished"
        else String -> IO ()
putStrLn String
"aborted"