{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Dhall.JSON.Yaml
( Options(..)
, parseDocuments
, parseQuoted
, defaultOptions
, dhallToYaml
, jsonToYaml
, generatedCodeNotice
) where
import Data.ByteString (ByteString)
import Data.Text (Text)
import Dhall.JSON (Conversion (..), SpecialDoubleMode (..))
import Options.Applicative (Parser)
import qualified Data.Aeson
import qualified Data.Aeson.Yaml
import qualified Data.ByteString.Lazy
import qualified Data.Vector
import qualified Dhall
import qualified Dhall.JSON
import qualified Options.Applicative
data Options = Options
{ explain :: Bool
, omission :: Data.Aeson.Value -> Data.Aeson.Value
, documents :: Bool
, quoted :: Bool
, conversion :: Conversion
, file :: Maybe FilePath
, output :: Maybe FilePath
, noEdit :: Bool
}
defaultOptions :: Options
defaultOptions =
Options { explain = False
, omission = id
, documents = False
, quoted = False
, conversion = Dhall.JSON.defaultConversion
, file = Nothing
, output = Nothing
, noEdit = False
}
parseDocuments :: Parser Bool
parseDocuments =
Options.Applicative.switch
( Options.Applicative.long "documents"
<> Options.Applicative.help "If given a Dhall list, output a document for every element. Each document, including the first one, will be preceded by \"---\", even if there is only one document. If not given a list, output a single document (as if it were a list of one element)"
)
parseQuoted :: Parser Bool
parseQuoted =
Options.Applicative.switch
( Options.Applicative.long "quoted"
<> Options.Applicative.help "Prevent from generating not quoted scalars"
)
generatedCodeNotice :: ByteString
generatedCodeNotice = "# Code generated by dhall-to-yaml. DO NOT EDIT.\n"
dhallToYaml
:: Options
-> Maybe FilePath
-> Text
-> IO ByteString
dhallToYaml Options{..} mFilePath code = do
let explaining = if explain then Dhall.detailed else id
json <- omission <$> explaining (Dhall.JSON.codeToValue conversion UseYAMLEncoding mFilePath code)
let header =
if noEdit
then generatedCodeNotice
else mempty
return $ header <> jsonToYaml json documents quoted
jsonToYaml
:: Data.Aeson.Value
-> Bool
-> Bool
-> ByteString
jsonToYaml json documents quoted =
Data.ByteString.Lazy.toStrict $ case (documents, json) of
(True, Data.Aeson.Array elems)
-> (if quoted
then Data.Aeson.Yaml.encodeQuotedDocuments
else Data.Aeson.Yaml.encodeDocuments
) (Data.Vector.toList elems)
(True, value)
-> (if quoted
then Data.Aeson.Yaml.encodeQuotedDocuments
else Data.Aeson.Yaml.encodeDocuments
) [ value ]
_ -> (if quoted
then Data.Aeson.Yaml.encodeQuoted
else Data.Aeson.Yaml.encode
) json