packages feed

global-config (empty) → 0.1.0

raw patch · 5 files changed

+196/−0 lines, 5 filesdep +HUnitdep +QuickCheckdep +basesetup-changed

Dependencies added: HUnit, QuickCheck, base, bytestring, data-default, global-config, global-variables, test-framework, test-framework-hunit, test-framework-quickcheck2, transformers

Files

+ LICENSE view
@@ -0,0 +1,25 @@+The following license covers this documentation, and the source code, except+where otherwise indicated.++Copyright 2011, John Lenz. All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+  list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright notice,+  this list of conditions and the following disclaimer in the documentation+  and/or other materials provided with the distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO+EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple
+main = defaultMain
+ global-config.cabal view
@@ -0,0 +1,49 @@+name:           global-config
+version:        0.1.0
+cabal-version:  >= 1.8
+build-type:     Simple
+author:         Alexander Dorofeev <aka.spin@gmail.com>spin
+maintainer:     Alexander Dorofeev <aka.spin@gmail.com>
+stability:      Experimental
+synopsis:       Global mutable configuration
+homepage:       https://github.com/akaspin/global-config
+bug-reports:    https://github.com/akaspin/global-config/issues
+category:       Configuration
+license-file:   LICENSE
+license:        BSD3
+description:    
+    @Data.Global.Config@ provides brain-free pattern to work with global 
+    configurations. Use wisely.
+
+source-repository head
+  type:         git
+  location:     git://github.com/akaspin/global-config.git
+
+library
+  hs-source-dirs:   src
+  build-depends:    base >= 4 && < 5,
+                   global-variables,
+                   data-default
+  ghc-options:      -Wall
+  exposed-modules:  Data.Global.Config
+
+test-suite test
+  type:            exitcode-stdio-1.0
+  x-uses-tf:       true
+  build-depends:   
+                   base >= 4 && < 5,
+                   HUnit >= 1.2 && < 2,
+                   QuickCheck >= 2.4,
+                   test-framework >= 0.4.1,
+                   test-framework-quickcheck2,
+                   test-framework-hunit,
+
+                   global-config,
+
+                   transformers,
+                   bytestring,
+                   data-default
+  ghc-options:     -Wall -rtsopts
+  hs-source-dirs:  test
+  main-is:         Main.hs
+
+ src/Data/Global/Config.hs view
@@ -0,0 +1,59 @@+
+-- | Main problem in haskell is \"creepy\" enviroment variables passed to all 
+--   functions. It's safe but tedious.
+--   
+--   'GlobalConfig' trying to solve this problem and propose common pattern 
+--   to work with configurations. It has been tested and proved to be very 
+--   useful in production.
+--   
+-- > {-# LANGUAGE DeriveDataTypeable #-}
+-- > 
+-- > module Main (main) where
+-- > 
+-- > import Data.Typeable (Typeable)
+-- > import Data.Default
+-- > import Data.Global.Config
+-- > 
+-- > data Config = Config { configInt :: Int, configBool :: Bool }
+-- >    deriving (Show, Typeable)
+-- > 
+-- > instance Default Config
+-- >    def = Config 0 False
+-- > 
+-- > instance GlobalConfig Config
+-- > 
+-- > main :: IO ()
+-- > main = do
+-- >    -- try to read unitialized config
+-- >    c1 <- getConfig 
+-- >    print (c1 :: Config)
+-- >    -- Config {configInt=0, configBool=False}
+-- >    
+-- >    -- set config and read it
+-- >    setConfig $ Config 1 True
+-- >    c2 <- getConfig
+-- >    print (c1 :: Config)
+-- >    -- Config {configInt=1, configBool=True}
+
+module Data.Global.Config (
+    GlobalConfig (setConfig, getConfig)
+) where
+
+import Data.Typeable (Typeable)
+import Data.Global (declareIORef)
+import Data.IORef (IORef, writeIORef, readIORef)
+import Data.Default (Default(def))
+
+-- | Global configuration class
+class (Default a, Typeable a) => GlobalConfig a where
+    -- | Init global config
+    setConfig :: a -> IO ()
+    setConfig e = stubConfig `writeIORef` e 
+    
+    -- | Get global config
+    getConfig :: IO a
+    getConfig = readIORef stubConfig
+    
+    -- | Stub enviroment
+    stubConfig :: IORef a
+    stubConfig = declareIORef "" def
+ test/Main.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+
+module Main where
+
+import Test.Framework (defaultMain)
+import Test.Framework.Providers.HUnit (testCase)
+import Test.HUnit (Assertion, (@=?))
+
+import Control.Monad.IO.Class (liftIO)
+
+import Data.Typeable (Typeable)
+import Data.Default
+import Data.ByteString (ByteString)
+import Data.ByteString.Char8 () -- Just for an orphan instance
+
+import Data.Global.Config
+
+main :: IO ()
+main = defaultMain [
+        testCase "Basic" caseBasic
+    ]
+
+---------------------------------------------------------------------------
+-- Test cases
+---------------------------------------------------------------------------
+
+caseBasic :: Assertion
+caseBasic = do
+    let c1 = Config 1 "first"
+    let c2 = Config 2 "second"
+
+    -- try to read unitialised config
+    c1f <- getConfig :: IO Config
+    liftIO $ c1f @=? def
+    
+    setConfig c1
+    c1' <- getConfig :: IO Config
+    liftIO $ c1' @=? c1
+
+    setConfig c2
+    c2' <- getConfig :: IO Config
+    liftIO $ c2' @=? c2
+
+---------------------------------------------------------------------------
+-- Test data types
+---------------------------------------------------------------------------
+
+-- First config
+data Config = Config {
+    tc1p1 :: Int,
+    tc1p2 :: ByteString
+  } deriving (Show, Eq, Typeable)
+  
+instance Default Config where
+    def = Config 0 ""
+    
+instance GlobalConfig Config
+
+    
+