gameServer/Data/TConfig.hs
changeset 4989 4771fed9272e
child 4992 408301a9d2d6
equal deleted inserted replaced
4988:bd540ba66599 4989:4771fed9272e
       
     1 -- Module      : Data.TConfig
       
     2 -- Copyright   : (c) Anthony Simpson 2009
       
     3 -- License     : BSD3
       
     4 --
       
     5 -- Maintainer  : DiscipleRayne@gmail.com
       
     6 -- Stability   : relatively stable
       
     7 -- Portability : portable
       
     8 ---------------------------------------------------
       
     9 {-|
       
    10   A small and simple text file configuration
       
    11   library written in Haskell. It is similar
       
    12   to the INI file format, but lacks a few of
       
    13   it's features, such as sections. It is
       
    14   suitable for simple games that need to
       
    15   keep track of certain information between
       
    16   plays.
       
    17 -}
       
    18 module Data.TConfig
       
    19     (
       
    20      getValue
       
    21    , repConfig
       
    22    , readConfig
       
    23    , writeConfig
       
    24    , remKey
       
    25    , addKey
       
    26    , Conf ()
       
    27    ) where
       
    28 
       
    29 import Data.Char
       
    30 import qualified Data.Map as M
       
    31 
       
    32 type Key   = String
       
    33 type Value = String
       
    34 type Conf  = M.Map Key Value
       
    35 
       
    36 -- |Adds a key and value to the end of the configuration.
       
    37 addKey :: Key -> Value -> Conf -> Conf
       
    38 addKey k v conf = M.insert k (addQuotes v) conf
       
    39 
       
    40 -- |Utility Function. Checks for the existence
       
    41 -- of a key.
       
    42 checkKey :: Key -> Conf -> Bool
       
    43 checkKey k conf = M.member k conf
       
    44 
       
    45 -- |Utility function.
       
    46 -- Removes a key and it's value from the configuration.
       
    47 remKey :: Key -> Conf -> Conf
       
    48 remKey k conf = M.delete k conf
       
    49 
       
    50 -- |Utility function. Searches a configuration for a
       
    51 -- key, and returns it's value.
       
    52 getValue :: Key -> Conf -> Maybe Value
       
    53 getValue k conf = case M.lookup k conf of
       
    54                     Just val -> Just $ stripQuotes val
       
    55                     Nothing  -> Nothing
       
    56 
       
    57 stripQuotes :: String -> String
       
    58 stripQuotes x | any isSpace x = filter (/= '\"') x
       
    59               | otherwise     = x
       
    60 
       
    61 -- |Returns a String wrapped in quotes if it
       
    62 -- contains spaces, otherwise returns the string
       
    63 -- untouched.
       
    64 addQuotes :: String -> String
       
    65 addQuotes x | any isSpace x = "\"" ++ x ++ "\""
       
    66             | otherwise     = x
       
    67 
       
    68 -- |Utility function. Replaces the value
       
    69 -- associated with a key in a configuration.
       
    70 repConfig :: Key -> Value -> Conf -> Conf
       
    71 repConfig k rv conf = let f _ = Just rv
       
    72                       in M.alter f k conf
       
    73 
       
    74 -- |Reads a file and parses to a Map String String.
       
    75 readConfig :: FilePath -> IO Conf
       
    76 readConfig path = readFile path >>= return . parseConfig
       
    77 
       
    78 -- |Parses a parsed configuration back to a file.
       
    79 writeConfig :: FilePath -> Conf -> IO ()
       
    80 writeConfig path con = writeFile path $ putTogether con
       
    81 
       
    82 -- |Turns a list of configuration types back into a String
       
    83 -- to write to a file.
       
    84 putTogether :: Conf -> String
       
    85 putTogether = concat . putTogether' . backToString
       
    86     where putTogether' (x:y:xs) = x : " = " : y : "\n" : putTogether' xs
       
    87           putTogether' _        = []
       
    88 
       
    89 -- |Turns a list of configuration types into a list of Strings
       
    90 backToString :: Conf -> [String]
       
    91 backToString conf = backToString' $ M.toList conf
       
    92     where backToString' ((x,y):xs) = x : y : backToString' xs
       
    93           backToString' _          = []
       
    94 
       
    95 -- |Parses a string into a list of Configuration types.
       
    96 parseConfig :: String -> Conf
       
    97 parseConfig = listConfig . popString . parse
       
    98 
       
    99 parse :: String -> [String]
       
   100 parse = words . filter (/= '=')
       
   101 
       
   102 -- |Turns a list of key value key value etc... pairs into
       
   103 -- A list of Configuration types.
       
   104 listConfig :: [String] -> Conf
       
   105 listConfig = M.fromList . helper
       
   106     where helper (x:y:xs) = (x,y) : helper xs
       
   107           helper _        = []
       
   108 
       
   109 -- |Parses strings from the parseConfig'd file.
       
   110 popString :: [String] -> [String]
       
   111 popString []     = []
       
   112 popString (x:xs)
       
   113     | head x == '\"' = findClose $ break (('\"' ==) . last) xs
       
   114     | otherwise      = x : popString xs
       
   115     where findClose (y,ys) =
       
   116               [unwords $ x : y ++ [head ys]] ++ popString (tail ys)