]> gitweb.michael.orlitzky.com - dead/harbl.git/blobdiff - harbl-cli/src/OptionalConfiguration.hs
Fix hlint suggestions.
[dead/harbl.git] / harbl-cli / src / OptionalConfiguration.hs
index 35ca7d4cb3a7876648f329dbee2e1ff69def59b9..66e47858b227b8cb6112a026c973d90a1d01d8eb 100644 (file)
@@ -1,7 +1,5 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE StandaloneDeriving #-}
 
 -- | An OptionalConfiguration is just like a 'Configuration', except
 --   all of its fields are optional. The user can set options in two
@@ -11,6 +9,8 @@
 --
 module OptionalConfiguration (
   OptionalConfiguration(..),
+  merge_maybe,
+  merge_monoid,
   from_rc )
 where
 
@@ -22,13 +22,17 @@ import qualified Data.Configurator as DC (
 import Data.Data ( Data )
 import Data.Maybe ( fromMaybe )
 import Data.Monoid ( Monoid(..) )
+import Data.Text ( pack )
 import Data.Typeable ( Typeable )
 import Paths_harbl ( getSysconfDir )
 import System.Console.CmdArgs.Default ( Default(..) )
 import System.Directory ( getHomeDirectory )
 import System.FilePath ( (</>) )
 import System.IO.Error ( catchIOError )
-import System.IO ( hPutStrLn, stderr )
+import System.IO ( hPrint, stderr )
+
+-- Harbl library imports.
+import Network.DNS.RBL.Weight ( Weight )
 
 -- Local imports.
 import Hosts ( Hosts(..) )
@@ -43,10 +47,88 @@ import Lists ( Lists(..) )
 data OptionalConfiguration =
   OptionalConfiguration {
     hosts :: Hosts,
-    lists :: Lists }
+    lists :: Lists,
+    threshold :: Maybe Weight }
     deriving (Show, Data, Typeable)
 
 
+-- | Choose a nonempty monoid from our two arguments, preferring the
+--   second. So if the second monoid is non-'mempty', we'll return
+--   that. Otherwise the first.
+--
+--   ==== _Examples_
+--
+--   The second list is preferred if both are nonempty:
+--
+--   >>> merge_monoid [1,2] [3,4]
+--   [3,4]
+--
+--   However, if the second list is empty, the first is returned:
+--
+--   >>> merge_monoid [1,2] []
+--   [1,2]
+--
+--   And if both are empty, we return the first (i.e. empty) list:
+--
+--   >>> merge_monoid [] []
+--   []
+--
+merge_monoid :: (Eq a, Monoid a) => a -> a -> a
+merge_monoid l1 l2 = if l2 == mempty then l1 else l2
+
+
+-- | Like 'merge_monoid', except for optional things. We take two
+--   (potentially 'Nothing') values, and then try to choose a
+--   non-'Nothing' one, preferring the second argument.
+--
+--   ==== _Examples_
+--
+--   The second is preferred if it is non-'Nothing':
+--
+--   >>> merge_maybes (Just 3) (Just 4)
+--   Just 4
+--
+--   >>> merge_maybes Nothing (Just 4)
+--   Just 4
+--
+--   However, if the second argument is 'Nothing', the first is
+--   returned:
+--
+--   >>> merge_maybes (Just 1) Nothing
+--   Just 1
+--
+--   If both are 'Nothing', we return 'Nothing':
+--
+--   >>> merge_maybes Nothing Nothing
+--   Nothing
+--
+merge_maybes :: (Maybe a) -> (Maybe a) -> (Maybe a)
+merge_maybes _ y@(Just _) = y
+merge_maybes x@(Just _) Nothing = x
+merge_maybes Nothing Nothing = Nothing
+
+
+-- | Return the (thing contained in the) second argument if it is
+--   non-'Nothing'. Otherwise return the first argument.
+--
+--   ==== _Examples_
+--
+--   The second is preferred if it is non-'Nothing':
+--
+--   >>> merge_maybe 3 (Just 4)
+--   4
+--
+--   However, if the second argument is 'Nothing', the first is
+--   returned:
+--
+--   >>> merge_maybe 1 Nothing
+--   1
+--
+merge_maybe :: a -> Maybe a -> a
+merge_maybe x Nothing = x
+merge_maybe _ (Just y) = y
+
+
 -- | The Monoid instance for these lets us \"combine\" two
 --   OptionalConfigurations. The \"combine\" operation that we'd like to
 --   perform is, essentially, to mash them together. So if we have two
@@ -57,18 +139,14 @@ data OptionalConfiguration =
 --
 instance Monoid OptionalConfiguration where
   -- | An empty OptionalConfiguration.
-  mempty = OptionalConfiguration (Hosts []) (Lists [])
-
+  mempty = OptionalConfiguration mempty mempty Nothing
 
   -- | Combine @cfg1@ and @cfg2@, giving precedence to @cfg2@.
-  --   XML files can only be specified on the command-line, so we
-  --   just join them together here.
-  cfg1 `mappend` cfg2 =
-    OptionalConfiguration all_hosts all_lists
+  cfg1 `mappend` cfg2 = OptionalConfiguration hs ls t
     where
-      all_hosts = Hosts $ (get_hosts $ hosts cfg1) ++ (get_hosts $ hosts cfg2)
-      all_lists = Lists $ (get_lists $ lists cfg1) ++ (get_lists $ lists cfg2)
-
+      hs = merge_monoid (hosts cfg1) (hosts cfg2)
+      ls = merge_monoid (lists cfg1) (lists cfg2)
+      t  = merge_maybes (threshold cfg1) (threshold cfg2)
 
 
 -- | Obtain an OptionalConfiguration from harblrc in either the global
@@ -83,15 +161,19 @@ instance Monoid OptionalConfiguration where
 from_rc :: IO OptionalConfiguration
 from_rc = do
   etc  <- catchIOError getSysconfDir (\e -> do
-                                        hPutStrLn stderr (show e)
+                                        hPrint stderr e
                                         return "/etc")
   home <- catchIOError getHomeDirectory (\e -> do
-                                           hPutStrLn stderr (show e)
+                                           hPrint stderr e
                                            return "$(HOME)")
   let global_config_path = etc </> "harblrc"
   let user_config_path = home </> ".harblrc"
   cfg <- DC.load [ DC.Optional global_config_path,
                    DC.Optional user_config_path ]
-  cfg_lists <- DC.lookup cfg "lists"
-  let cfg_hosts = Hosts [] -- This won't be in the config file.
-  return $ OptionalConfiguration cfg_hosts (fromMaybe def cfg_lists)
+  cfg_lists <- DC.lookup cfg (pack "lists")
+  cfg_hosts <- DC.lookup cfg (pack "hosts")
+  cfg_threshold <- DC.lookup cfg (pack "threshold")
+  return $ OptionalConfiguration
+             (fromMaybe def cfg_hosts)
+             (fromMaybe def cfg_lists)
+             cfg_threshold