envy 0.1.0.1 → 0.2.0.0
raw patch · 3 files changed
+63/−115 lines, 3 filesdep ~envyPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: envy
API changes (from Hackage documentation)
- System.Envy: (.:) :: (Typeable a, Var a) => String -> Env -> Parser a
- System.Envy: (.:?) :: (Typeable a, Var a) => String -> Env -> Parser (Maybe a)
- System.Envy: Env :: Map String String -> Env
- System.Envy: instance FromEnv Env
- System.Envy: instance MonadReader Env Parser
- System.Envy: instance Show Env
- System.Envy: loadEnv :: IO Env
- System.Envy: newtype Env
+ System.Envy: envMaybe :: (Typeable a, Var a) => String -> Parser (Maybe a)
- System.Envy: env :: Env -> Map String String
+ System.Envy: env :: (Typeable a, Var a) => String -> Parser a
- System.Envy: fromEnv :: FromEnv a => Env -> Parser a
+ System.Envy: fromEnv :: FromEnv a => Parser a
- System.Envy: showEnv :: Env -> IO ()
+ System.Envy: showEnv :: IO ()
Files
- envy.cabal +2/−2
- src/System/Envy.hs +46/−67
- tests/Main.hs +15/−46
envy.cabal view
@@ -1,5 +1,5 @@ name: envy-version: 0.1.0.1+version: 0.2.0.0 synopsis: An environmentally friendly way to deal with environment variables license: BSD3 license-file: LICENSE@@ -31,7 +31,7 @@ main-is: Main.hs build-depends: base >= 4.7 && < 5 , bytestring == 0.10.*- , envy == 0.1.*+ , envy == 0.2.* , hspec == 2.1.* , mtl == 2.2.* , quickcheck-instances == 0.3.*
src/System/Envy.hs view
@@ -1,9 +1,9 @@-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE RankNTypes #-} ------------------------------------------------------------------------------ -- | -- Module : System.Envy@@ -14,29 +14,25 @@ -- ------------------------------------------------------------------------------ module System.Envy- ( -- * Types- Env (..)- -- * Classes- , FromEnv (..)+ ( -- * Classes+ FromEnv (..) , ToEnv (..) , Var (..)+ , EnvList -- * Functions- , loadEnv , decodeEnv , decode , showEnv , setEnvironment , unsetEnvironment , makeEnv - , EnvList+ , env+ , envMaybe , (.=)- , (.:)- , (.:?) , (.!=) ) where ------------------------------------------------------------------------------ import Control.Applicative-import Control.Monad.Reader import Control.Monad.Except import Control.Monad.Identity import Control.Exception@@ -45,6 +41,7 @@ import Data.Monoid import Control.Monad import Data.Typeable+import Data.String import System.Environment import Text.Read (readMaybe) import qualified Data.Text as T@@ -58,14 +55,9 @@ ------------------------------------------------------------------------------ --------------------------------------------------------------------------------- | Environment-newtype Env = Env { env :: M.Map String String }- deriving (Show)-------------------------------------------------------------------------------- -- | Parser-newtype Parser a = Parser { runParser :: ReaderT Env (ExceptT String IO) a }- deriving ( Functor, Monad, Applicative, MonadReader Env, MonadError String+newtype Parser a = Parser { runParser :: ExceptT String IO a }+ deriving ( Functor, Monad, Applicative, MonadError String , MonadIO, Alternative, MonadPlus ) ------------------------------------------------------------------------------@@ -76,19 +68,17 @@ ------------------------------------------------------------------------------ -- | Execute Parser evalParser :: FromEnv a => Parser a -> IO (Either String a)-evalParser stack = do- env <- liftIO loadEnv- runExceptT $ runReaderT (runParser stack) env+evalParser = runExceptT . runParser ------------------------------------------------------------------------------ -- | Infix environment variable getter getE :: forall a . (Typeable a, Var a) => String- -> Env -> Parser a-getE k (Env m) = do- case M.lookup k m of+getE k = do+ result <- liftIO (lookupEnv k)+ case result of Nothing -> throwError $ "Variable not found for: " ++ k Just dv -> case fromVar dv :: Maybe a of@@ -97,41 +87,30 @@ Just x -> return x ------------------------------------------------------------------------------+-- | Environment variable getter +env :: forall a. (Typeable a, Var a)+ => String+ -> Parser a+env = getE++------------------------------------------------------------------------------ -- | Infix environment variable getter getEMaybe :: forall a . (Typeable a, Var a) => String- -> Env -> Parser (Maybe a)-getEMaybe k (Env m) = do- return $ do- dv <- M.lookup k m- fromVar dv ----------------------------------------------------------------------------------- | Infix environment variable getter-(.:) :: forall a. (Typeable a, Var a)- => String- -> Env- -> Parser a-(.:) = getE----------------------------------------------------------------------------------- | Infix environment variable setter --- this is a smart constructor for producing types of `EnvVar`-(.=) :: Var a- => String- -> a- -> EnvVar -(.=) x y = EnvVar (x, toVar y)+getEMaybe k = do+ val <- liftIO (lookupEnv k)+ return $ case val of+ Nothing -> Nothing+ Just x -> fromVar x ------------------------------------------------------------------------------ -- | Maybe parser-(.:?) :: forall a. (Typeable a, Var a)+envMaybe :: forall a. (Typeable a, Var a) => String- -> Env -> Parser (Maybe a)-(.:?) = getEMaybe+envMaybe = getEMaybe ------------------------------------------------------------------------------ -- | For use with (.:?) for providing default arguments@@ -142,13 +121,18 @@ (.!=) p x = fmap (fromMaybe x) p --------------------------------------------------------------------------------- | FromEnv Typeclass-class FromEnv a where- fromEnv :: Env -> Parser a+-- | Infix environment variable setter +-- this is a smart constructor for producing types of `EnvVar`+(.=) :: Var a+ => String+ -> a+ -> EnvVar +(.=) x y = EnvVar (x, toVar y) --------------------------------------------------------------------------------- | Identity instance-instance FromEnv Env where fromEnv = return+-- | FromEnv Typeclass+class FromEnv a where+ fromEnv :: Parser a ------------------------------------------------------------------------------ -- | ToEnv Typeclass@@ -247,21 +231,16 @@ fromVar = Just --------------------------------------------------------------------------------- | Environment loading-loadEnv :: IO Env-loadEnv = Env . M.fromList <$> getEnvironment-------------------------------------------------------------------------------- -- | Environment retrieval with failure info decodeEnv :: FromEnv a => IO (Either String a)-decodeEnv = loadEnv >>= evalParser . fromEnv+decodeEnv = evalParser fromEnv ------------------------------------------------------------------------------ -- | Environment retrieval (with no failure info) decode :: FromEnv a => IO (Maybe a)-decode = fmap f $ loadEnv >>= evalParser . fromEnv+decode = fmap f decodeEnv where- f (Left _) = Nothing+ f (Left _) = Nothing f (Right x) = Just x ------------------------------------------------------------------------------@@ -284,5 +263,5 @@ ------------------------------------------------------------------------------ -- | Env helper-showEnv :: Env -> IO ()-showEnv (Env xs) = mapM_ print (M.toList xs)+showEnv :: IO ()+showEnv = mapM_ print =<< getEnvironment
tests/Main.hs view
@@ -9,7 +9,6 @@ import Control.Applicative import Control.Exception import Control.Monad-import Control.Monad.Error import Control.Monad.IO.Class (liftIO) import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy.Char8 as BL8@@ -29,41 +28,12 @@ import Test.QuickCheck import Test.QuickCheck.Instances --------------------------------------------------------------------------------- | Posgtres Port-newtype PGPORT = PGPORT Word16- deriving (Read, Show, Var, Typeable, Num)----------------------------------------------------------------------------------- | Postgres URL-newtype PGURL = PGURL String- deriving (Read, Show, Var, IsString, Typeable)----------------------------------------------------------------------------------- | Postgres Host-newtype PGHOST = PGHOST String- deriving (Read, Show, Var, IsString, Typeable)----------------------------------------------------------------------------------- | Postgres DB-newtype PGDB = PGDB String- deriving (Read, Show, Var, IsString, Typeable)----------------------------------------------------------------------------------- | Postgres User-newtype PGUSER = PGUSER String- deriving (Read, Show, Var, IsString, Typeable)----------------------------------------------------------------------------------- | Postgres Password-newtype PGPASS = PGPASS String- deriving (Read, Show, Var, IsString, Typeable)- data ConnectInfo = ConnectInfo {- pgHost :: PGHOST- , pgDB :: PGDB- , pgPass :: PGPASS- , pgUrl :: PGURL- , pgUser :: PGUSER+ pgHost :: String+ , pgPort :: Word16+ , pgUser :: String+ , pgPass :: String+ , pgDB :: String } deriving (Show) ------------------------------------------------------------------------------@@ -81,22 +51,21 @@ -- | FromEnv Instances, supports popular aeson combinators *and* IO -- for dealing with connection pools instance FromEnv PGConfig where- fromEnv env = do- PGConfig <$> (ConnectInfo <$> "PG_HOST" .:? env .!= ("localhost" :: PGHOST)- <*> "PG_PORT" .: env - <*> "PG_USER" .: env - <*> "PG_PASS" .: env - <*> "PG_DB" .: env)+ fromEnv = PGConfig <$> (ConnectInfo <$> envMaybe "PG_HOST" .!= "localhost"+ <*> env "PG_PORT"+ <*> env "PG_USER" + <*> env "PG_PASS" + <*> env "PG_DB") ------------------------------------------------------------------------------ -- | To Environment Instances instance ToEnv PGConfig where toEnv = makeEnv - [ "PG_HOST" .= PGHOST "localhost"- , "PG_PORT" .= PGPORT 5432- , "PG_USER" .= PGUSER "user"- , "PG_PASS" .= PGPASS "pass"- , "PG_DB" .= PGDB "db"+ [ "PG_HOST" .= ("localhost" :: String)+ , "PG_PORT" .= (5432 :: Word16)+ , "PG_USER" .= ("user" :: String)+ , "PG_PASS" .= ("pass" :: String)+ , "PG_DB" .= ("db" :: String) ] ------------------------------------------------------------------------------