packages feed

herms-1.9.0.2: src/ReadConfig.hs

module ReadConfig where

import UnitConversions
import qualified Text.Read as TR
import Control.Exception
import Data.Typeable
import Data.Char (toLower)
import Data.List.Split
import Lang.Pirate
import Lang.French
import Paths_herms

------------------------------
------- Config Types ---------
------------------------------
  
-- TODO Allow record synonyms with that fancy stuff

data ConfigInfo = ConfigInfo
  { defaultUnit           :: Conversion
  , defaultServingSize    :: Int
  , recipesFile           :: String
  , language              :: String
  } deriving (Read, Show)

data Config = Config
  { defaultUnit'        :: Conversion
  , defaultServingSize' :: Int
  , recipesFile'        :: String
  , translator          :: String -> String
  } 

data Language = English
              | Pirate
              | Portuguese
              | French

type Translator = String -> String

------------------------------
---- Exception Handling ------
------------------------------

data ConfigParseError = ConfigParseError 
  deriving Typeable

instance Show ConfigParseError where
  show ConfigParseError = "Error parsing config.hs"

instance Exception ConfigParseError

------------------------------
------ Language Synonyms -----
------------------------------

-- Contributor's note: Make sure that all of these synonyms are lower-case as
-- we handle case-sensitivity by first converting the user's settings input
-- to all lower-case.

englishSyns = [ "english"
              , "en"
              , "en-us"
              , "\'murican"
              ]

pirateSyns = [ "pirate"
             , "pr"
             ]

portugueseSyns = [ "portuguese"
                 , "português"
                 , "portugues"
                 , "pt"
                 ]

frenchSyns = [ "french"
              , "fr"
              , "fr-fr"
              , "français"
              , "francais"
              ]


------------------------------
--------- Functions ----------
------------------------------

getLang :: ConfigInfo -> Language
getLang c
  | isIn englishSyns = English
  -- | isIn portugueseSyns = Portuguese
  | isIn pirateSyns  = Pirate
  -- | isIn frenchSyns = French
  | isIn frenchSyns  = French
  where isIn = elem (map toLower $ language c)

getTranslator :: Language -> Translator
getTranslator lang = case lang of
                       English -> id :: String -> String
                       Pirate  -> pirate
                       French  -> french

dropComments :: String -> String
dropComments = unlines . map (head . splitOn "--") . lines

processConfig :: ConfigInfo -> Config
processConfig raw = Config
  { defaultUnit'        = defaultUnit raw
  , defaultServingSize' = defaultServingSize raw
  , recipesFile'        = recipesFile raw
  , translator          = getTranslator $ getLang raw
  }

getConfig :: IO Config
getConfig = do
  fileName <- getDataFileName "config.hs"
  contents <- readFile fileName
  let result = TR.readEither (dropComments contents) :: Either String ConfigInfo
  case result of
    Left str -> throw ConfigParseError
    Right r  -> return (processConfig r)