{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE NoImplicitPrelude #-}
module CLI.Config
( Service (..),
Config (..),
readConfig,
ServiceOptions (..),
Source (..),
)
where
import qualified Data.ByteString as L
( readFile,
)
import Data.Yaml
( FromJSON (..),
Value (..),
decodeThrow,
withObject,
(.:),
(.:?),
)
import Relude
import System.FilePath.Posix
( (</>),
)
data ServiceOptions = ServiceOptions
{ optionNamespace :: Bool,
optionImports :: [Text],
optionExternals :: HashMap Text Text
}
deriving (Show)
instance FromJSON ServiceOptions where
parseJSON =
withObject
"ServiceOptions"
( \v -> do
optionNamespace <- fromMaybe False <$> v .:? "namespace"
optionExternals <- collection "externals" v
optionImports <- collection "globals" v
pure ServiceOptions {..}
)
where
collection name v = fromMaybe mempty <$> (v .:? name)
instance Semigroup ServiceOptions where
(ServiceOptions n1 g1 e1) <> (ServiceOptions n2 g2 e2) = ServiceOptions (n1 || n2) (g1 <> g2) (e1 <> e2)
data Source = Source
{ sourcePath :: FilePath,
sourceOptions :: Maybe ServiceOptions
}
deriving (Show)
instance FromJSON Source where
parseJSON (Object o) = do
path <- o .: "path"
ops <- parseJSON (Object o)
pure (Source path ops)
parseJSON x = (`Source` Nothing) <$> parseJSON x
data Service = Service
{ name :: String,
includes :: [Source],
source :: FilePath,
options :: Maybe ServiceOptions,
schema :: Maybe Source
}
deriving
( Generic,
FromJSON,
Show
)
data Config = Config
{ server :: Maybe [Service],
client :: Maybe [Service]
}
deriving
( Generic,
FromJSON,
Show
)
readConfig :: FilePath -> IO Config
readConfig path = do
file <- L.readFile (path </> "code-gen.yaml")
decodeThrow file