{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} -- | The program will parse ~/.htsnrc for any available configuration -- directives, resulting in an OptionalConfiguration. The -- command-line arguments will be used to create another -- OptionalConfiguration, and the two will be merged. Finally, a -- def :: Configuration will be updated from the merged -- OptionalConfigurations. -- module OptionalConfiguration ( OptionalConfiguration(..), from_rc ) where import qualified Data.Configurator as DC ( Worth(Optional), load, lookup ) import Data.Data (Data) import Data.Maybe (fromMaybe) import Data.Monoid (Monoid(..)) import Data.Typeable (Typeable) import FeedHosts (FeedHosts(..)) -- | The same as Configuration, except everything is optional. It's easy to -- merge two of these by simply dropping the Nothings in favor of -- the Justs. The 'feed_hosts' are left un-maybed so that cmdargs -- can parse more than one of them. -- data OptionalConfiguration = OptionalConfiguration { feed_hosts :: FeedHosts, password :: Maybe String, output_directory :: Maybe FilePath, username :: Maybe String } deriving (Show, Data, Typeable) instance Monoid OptionalConfiguration where mempty = OptionalConfiguration (FeedHosts []) Nothing Nothing Nothing cfg1 `mappend` cfg2 = OptionalConfiguration all_feed_hosts (merge (password cfg1) (password cfg2)) (merge (output_directory cfg1) (output_directory cfg2)) (merge (username cfg1) (username cfg2)) where merge :: (Maybe a) -> (Maybe a) -> (Maybe a) merge Nothing Nothing = Nothing merge (Just x) Nothing = Just x merge Nothing (Just x) = Just x merge (Just _) (Just y) = Just y -- Use only the latter feed_hosts if there are any. all_feed_hosts = feed_hosts $ if (null (get_feed_hosts (feed_hosts cfg2))) then cfg1 else cfg2 from_rc :: IO OptionalConfiguration from_rc = do cfg <- DC.load [ DC.Optional "$(HOME)/.htsnrc" ] cfg_password <- DC.lookup cfg "password" cfg_output_directory <- DC.lookup cfg "output_directory" cfg_username <- DC.lookup cfg "username" cfg_feed_hosts <- DC.lookup cfg "feed_hosts" return $ OptionalConfiguration (fromMaybe (FeedHosts []) cfg_feed_hosts) cfg_password cfg_output_directory cfg_username