-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A library to manage application settings (INI file-like) -- -- A library to deal with application settings. -- -- This library deals with read-write application settings. You will have -- to specify the settings that your application uses, their name, types -- and default values. -- -- Setting types must implement the Read and Show -- typeclasses. -- -- The settings are saved in a file in an INI-like key-value format -- (without sections). -- -- Reading and updating settings is done in pure code, the IO monad is -- only used to load settings and save them to disk. It is advised for -- the user to create a module in your project holding settings handling. -- -- You can then declare settings: -- --
--   fontSize :: Setting Double
--   fontSize = Setting "fontSize" 14
--   
--   dateFormat :: Setting String
--   dateFormat = Setting "dateFormat" "%x"
--   
--   backgroundColor :: Setting (Int, Int, Int)
--   backgroundColor = Setting "backcolor" (255, 0, 0)
--   
-- -- Optionally you can declare the list of all your settings, in that case -- the application will also save the default values in the configuration -- file, but commented out: -- --
--   fontSize=16
--   # dateFormat="%x"
--   # backcolor=(255,0,0)
--   
-- -- If you do not specify the list of settings, only the first line would -- be present in the configuration file. -- -- With an ordinary setting, one row in the configuration file means one -- setting. That setting may of course be a list for instance. This setup -- works very well for shorter lists like [1,2,3], however if you have a -- list of more complex items, you will get very long lines and a -- configuration file very difficult to edit by hand. -- -- For these special cases there is also the ListSetting -- constructor: -- --
--   testList :: Setting [String]
--   testList = ListSetting "testList" ["list1", "list2", "list3"]
--   
-- -- Now the configuration file looks like that: -- --
--   testList_1="list1"
--   testList_2="list2"
--   testList_3="list3"
--   
-- -- Which is much more handy for big lists. An empty list is represented -- like so: -- --
--   testList=
--   
-- -- Once we declared the settings, we can read the configuration from disk -- (and your settings module should export your wrapper around the -- function offered by this library): -- --
--   readResult <- try $ readSettings (AutoFromAppName "test")
--   case readResult of
--   	Right (conf, GetSetting getSetting) -> do
--   		let textSize = getSetting textSizeFromWidth
--   		saveSettings getDefaultConfig (AutoFromAppName "test") conf
--   	Left (x :: SomeException) -> error "Error reading the config file!"
--   
-- -- AutoFromAppName specifies where to save the configuration file. -- And we've already covered the getSetting in this snippet, see the -- readSettings documentation for further information. @package app-settings @version 0.2.0.2 module Data.AppSettings -- | The in-memory configuration data. type Conf = Map String SettingInfo -- | Information about the default configuration. Contains all the settings -- (that you declare using getDefaultConfig) and their default -- values. It is useful when you save a configuration file, if you give -- this information to saveSettings, it will save default options -- in the configuration file in a commented form, as a form of -- documentation to a user who would edit the configuration file. However -- this is completely optional, you can give emptyDefaultConfig if -- you don't want this behaviour. newtype DefaultConfig DefaultConfig :: Conf -> DefaultConfig -- | The type of a setting. It contains the setting name (key in the -- configuration file) and its default value. -- -- It is advised to have a module in your project handling settings. In -- this module, you'd have all the settings declared at the toplevel, and -- exported. The rest of the application can then do -- --
--   getSetting <setting>
--   setSetting <conf> <setting> <value>
--   
-- -- and so on. -- -- Setting declares a simple setting. A value for that setting -- will be stored in the configuration file in a single line. -- -- ListSetting however declares a list setting. While it is -- perfectly fine to store lists using the usual Setting constructor, if -- you have a list of more complex items, you will get very long lines -- and a configuration file very difficult to edit or review by hand. -- -- The ListSetting will store settings using one line per item in the -- list: -- --
--   testList :: Setting [String]
--   testList = ListSetting "testList" ["list1", "list2", "list3"]
--   
-- -- Now the configuration file looks like that: -- --
--   testList_1="list1"
--   testList_2="list2"
--   testList_3="list3"
--   
-- -- Also note that an empty ListSetting is stored like so: -- --
--   testList=
--   
data Setting a Setting :: String -> a -> Setting a ListSetting :: String -> [a] -> Setting [a] newtype GetSetting GetSetting :: (forall a. Read a => Setting a -> a) -> GetSetting -- | see the getDefaultConfig documentation. setting :: Show a => Setting a -> State Conf () -- | Used in combination with setting to register settings. -- Registering settings is optional, see DefaultConfig. -- --
--   defaultSettings :: DefaultConfig
--   defaultSettings = getDefaultConfig $ do
--       setting <setting1>
--       setting <setting2>
--   
getDefaultConfig :: State Conf () -> DefaultConfig -- | Default configuration containing no options. It's fine to give that to -- saveSettings if you don't want default settings being written -- to the configuration file in commented form (see DefaultConfig) emptyDefaultConfig :: DefaultConfig -- | Where to look for or store the configuration file. data FileLocation -- | Automatically build the location based on the application name. It -- will be ~/.<app name>/config.ini. AutoFromAppName :: String -> FileLocation -- | Absolute path to a location on disk. Path :: FilePath -> FileLocation -- | Read settings from disk. Because it is doing file I/O it is smart to -- wrap the call with a try, as I/O exceptions can be thrown. -- Also, the function will throw a ParseException if the file is -- not properly formatted. NOTE that if the file is properly formatted in -- general, but a value is stored in an invalid format (for instance -- "hello" for a Double), you will get no error and get the default value -- for that setting when you attempt to read it. -- -- This function returns a pair. The first element is the configuration -- itself, which you can use to save back or modify the configuration. -- The second element is a function wrapped in the GetSetting -- newtype. This function allows you to read a configuration option -- simply by giving that option (without that callback you'd have to call -- getSetting settings <setting>, so the callback lets you save a -- parameter). There is no such shortcut for setSetting though, as -- it's normally used less often and in other contexts, it is probably OK -- to have that extra parameter for the setSetting. -- -- Example of use: -- --
--   readResult <- try $ readSettings (Path "my.config")
--   case readResult of
--   	Right (conf, GetSetting getSetting) -> do
--   		let textSize = getSetting textSizeFromWidth
--   		saveSettings getDefaultConfig (Path "my.config") conf
--   	Left (x :: SomeException) -> error "Error reading the config file!"
--   
readSettings :: FileLocation -> IO (Conf, GetSetting) -- | The configuration file is in an invalid format. data ParseException -- | It is advised to run the save within a try call because it does disk -- I/O, otherwise the call is straightforward. saveSettings :: DefaultConfig -> FileLocation -> Conf -> IO () -- | Change the value of a setting. You'll have to call saveSettings -- so that the change is written to disk. setSetting :: Show a => Conf -> Setting a -> a -> Conf -- | Most of the time you can use the second function you get from -- readSettings, wrapped in a GetSetting newtype, -- however sometimes it's nicer to just pass a single Conf to -- other functions if you're going to read or write to the configuration. -- The GetSetting lets you only read. getSetting' :: Read a => Conf -> Setting a -> a instance Show GetSetting