module Game.LambdaHack.Common.ConfigIO
( CP, appDataDir, mkConfig, get, getOption, set, getItems, to_string, dump
) where
import Control.Exception.Assert.Sugar
import qualified Data.Char as Char
import qualified Data.ConfigFile as CF
import System.Directory
import System.Environment
import System.FilePath
import Game.LambdaHack.Server.Config
overrideCP :: CP -> FilePath -> IO CP
overrideCP cp@(CP defCF) cfile = do
cpExists <- doesFileExist cfile
if not cpExists
then return cp
else do
c <- CF.readfile defCF cfile
return $ toCP $ assert `forceEither` c
mkConfig :: String -> FilePath -> IO CP
mkConfig configDefault cfile = do
let delComment = map (drop 2) $ lines configDefault
unConfig = unlines delComment
!defCF = assert `forceEither` CF.readstring CF.emptyCP unConfig
!defCP = toCP defCF
overrideCP defCP cfile
appDataDir :: IO FilePath
appDataDir = do
progName <- getProgName
let name = takeWhile Char.isAlphaNum progName
getAppUserDataDirectory name
dump :: Config -> FilePath -> IO ()
dump Config{configSelfString} fn = do
current <- getCurrentDirectory
let path = current </> fn
writeFile path configSelfString
set :: CP -> CF.SectionSpec -> CF.OptionSpec -> String -> CP
set (CP conf) s o v =
if CF.has_option conf s o
then assert `failure`"overwritten config option" `twith` (s, o)
else CP $ assert `forceEither` CF.set conf s o v
newtype CP = CP CF.ConfigParser
instance Show CP where
show (CP conf) = show $ CF.to_string conf
toCP :: CF.ConfigParser -> CP
toCP cf = CP $ cf {CF.optionxform = id}
getOption :: CF.Get_C a => CP -> CF.SectionSpec -> CF.OptionSpec -> Maybe a
getOption (CP conf) s o =
if CF.has_option conf s o
then Just $ assert `forceEither` CF.get conf s o
else Nothing
get :: CF.Get_C a => CP -> CF.SectionSpec -> CF.OptionSpec -> a
get (CP conf) s o =
if CF.has_option conf s o
then assert `forceEither` CF.get conf s o
else assert `failure` "unknown CF option" `twith` (s, o, CF.to_string conf)
getItems :: CP -> CF.SectionSpec -> [(String, String)]
getItems (CP conf) s =
if CF.has_section conf s
then assert `forceEither` CF.items conf s
else assert `failure` "unknown CF section" `twith` (s, CF.to_string conf)
to_string :: CP -> String
to_string (CP conf) = CF.to_string conf