summaryrefslogtreecommitdiff
path: root/src/Settlr/Config.hs
blob: 1e2ff09f5928322949ded0cc2ed222bce915b653 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
module Settlr.Config
  ( ScriptM
  , Config(..)
  , ConfigException(..)
  , loadConfig
  , withConfig
  ) where

import Data.Text (Text)
import qualified Data.Text as T
import Network.CGI (getVarWithDefault, getVar, scriptName, CGIT, CGI)
import Control.Exception (Exception)
import Control.Monad.Catch (MonadThrow, throwM)
import Control.Monad.Reader (ReaderT(runReaderT))
import Network.CGI.Monad (MonadCGI(..))
import Control.Monad.Trans (lift)

type ScriptM = ReaderT Config (CGIT IO)

instance MonadCGI ScriptM where
  cgiAddHeader x y = lift $ cgiAddHeader x y
  cgiGet x = lift $ cgiGet x

data Config = Config
  { cfgCssPath    :: !Text -- ^ $SETTLR_CSS_PATH, defaults to "/settlr.css"
  , cfgScriptPath :: !Text -- ^ $SETTLR_SCRIPT_PATH, defaults to the CGI variable $SCRIPT_PATH or "/"
  , cfgDataPath   :: !Text -- ^ $SETTLR_DATA_PATH, required
  }

data ConfigException
  = CfgDataPathNotSet

instance Show ConfigException where
  show CfgDataPathNotSet = "Server misconfiguration: Required environment variable SETTLR_DATA_PATH not set."

instance Exception ConfigException

loadConfig :: MonadCGI m => MonadThrow m => m Config
loadConfig = do cssPath     <- getVarWithDefault "SETTLR_CSS_PATH" "/settlr.css"
                scriptPath' <- scriptName
                scriptPath  <- getVarWithDefault "SETTLR_SCRIPT_PATH" scriptPath'
                dataPath    <- getVar "SETTLR_DATA_PATH" >>= \case
                                 Nothing -> throwM CfgDataPathNotSet
                                 Just x  -> pure x
                pure $ Config { cfgCssPath    = T.pack cssPath
                              , cfgScriptPath = T.pack scriptPath
                              , cfgDataPath   = T.pack dataPath
                              }

withConfig :: ScriptM a -> CGI a
withConfig x = loadConfig >>= runReaderT x