-- |
-- Module      :  Configuration.Dotenv.Types
-- Copyright   :  © 2015–2020 Stack Builders Inc.
-- License     :  MIT
--
-- Maintainer  :  Stack Builders <hackage@stackbuilders.com>
-- Stability   :  experimental
-- Portability :  portable
--
-- Provides the types with extra options for loading a dotenv file.

module Configuration.Dotenv.Types
  ( Config(..)
  , defaultConfig
  , ask
  , runReaderT
  , liftReaderT
  , ReaderT
  )
  where

-- | Configuration Data Types with extra options for executing dotenv.
data Config = Config
  { Config -> [FilePath]
configPath        :: [FilePath] -- ^ The paths for the .env files
  , Config -> [FilePath]
configExamplePath :: [FilePath] -- ^ The paths for the .env.example files
  , Config -> Bool
configOverride    :: Bool     -- ^ Flag to allow override env variables
  , Config -> Bool
configVerbose     :: Bool     -- ^ Flag to log the loaded variables and other useful information
  , Config -> Bool
allowDuplicates   :: Bool     -- ^ Flag to allow duplicate variables
  } deriving (Config -> Config -> Bool
(Config -> Config -> Bool)
-> (Config -> Config -> Bool) -> Eq Config
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Config -> Config -> Bool
$c/= :: Config -> Config -> Bool
== :: Config -> Config -> Bool
$c== :: Config -> Config -> Bool
Eq, Int -> Config -> ShowS
[Config] -> ShowS
Config -> FilePath
(Int -> Config -> ShowS)
-> (Config -> FilePath) -> ([Config] -> ShowS) -> Show Config
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [Config] -> ShowS
$cshowList :: [Config] -> ShowS
show :: Config -> FilePath
$cshow :: Config -> FilePath
showsPrec :: Int -> Config -> ShowS
$cshowsPrec :: Int -> Config -> ShowS
Show)

-- | Default configuration. Use .env file without .env.example strict envs and
-- without overriding.
defaultConfig :: Config
defaultConfig :: Config
defaultConfig =
  Config :: [FilePath] -> [FilePath] -> Bool -> Bool -> Bool -> Config
Config
    { configExamplePath :: [FilePath]
configExamplePath = []
    , configOverride :: Bool
configOverride = Bool
False
    , configPath :: [FilePath]
configPath = [ FilePath
".env" ]
    , configVerbose :: Bool
configVerbose = Bool
False
    , allowDuplicates :: Bool
allowDuplicates = Bool
True
    }


newtype ReaderT r m a = ReaderT { ReaderT r m a -> r -> m a
runReaderT :: r -> m a }
mapReaderT :: (m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT :: (m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT m a -> n b
f ReaderT r m a
m = (r -> n b) -> ReaderT r n b
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((r -> n b) -> ReaderT r n b) -> (r -> n b) -> ReaderT r n b
forall a b. (a -> b) -> a -> b
$ m a -> n b
f (m a -> n b) -> (r -> m a) -> r -> n b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT r m a -> r -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT r m a
m
instance (Functor m) => Functor (ReaderT r m) where
    fmap :: (a -> b) -> ReaderT r m a -> ReaderT r m b
fmap a -> b
f  = (m a -> m b) -> ReaderT r m a -> ReaderT r m b
forall (m :: * -> *) a (n :: * -> *) b r.
(m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT ((a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f)
instance (Applicative m) => Applicative (ReaderT r m) where
    pure :: a -> ReaderT r m a
pure    = m a -> ReaderT r m a
forall (m :: * -> *) a r. m a -> ReaderT r m a
liftReaderT (m a -> ReaderT r m a) -> (a -> m a) -> a -> ReaderT r m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    ReaderT r m (a -> b)
f <*> :: ReaderT r m (a -> b) -> ReaderT r m a -> ReaderT r m b
<*> ReaderT r m a
v = (r -> m b) -> ReaderT r m b
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((r -> m b) -> ReaderT r m b) -> (r -> m b) -> ReaderT r m b
forall a b. (a -> b) -> a -> b
$ \ r
r -> ReaderT r m (a -> b) -> r -> m (a -> b)
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT r m (a -> b)
f r
r m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReaderT r m a -> r -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT r m a
v r
r

instance (Monad m) => Monad (ReaderT r m) where
    return :: a -> ReaderT r m a
return   = m a -> ReaderT r m a
forall (m :: * -> *) a r. m a -> ReaderT r m a
liftReaderT (m a -> ReaderT r m a) -> (a -> m a) -> a -> ReaderT r m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return
    ReaderT r m a
m >>= :: ReaderT r m a -> (a -> ReaderT r m b) -> ReaderT r m b
>>= a -> ReaderT r m b
k  = (r -> m b) -> ReaderT r m b
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((r -> m b) -> ReaderT r m b) -> (r -> m b) -> ReaderT r m b
forall a b. (a -> b) -> a -> b
$ \ r
r -> do
      a
a <- ReaderT r m a -> r -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT r m a
m r
r
      ReaderT r m b -> r -> m b
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (a -> ReaderT r m b
k a
a) r
r
    ReaderT r m a
m >> :: ReaderT r m a -> ReaderT r m b -> ReaderT r m b
>> ReaderT r m b
k = (r -> m b) -> ReaderT r m b
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((r -> m b) -> ReaderT r m b) -> (r -> m b) -> ReaderT r m b
forall a b. (a -> b) -> a -> b
$ \ r
r -> ReaderT r m a -> r -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT r m a
m r
r m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ReaderT r m b -> r -> m b
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT r m b
k r
r

liftReaderT :: m a -> ReaderT r m a
liftReaderT :: m a -> ReaderT r m a
liftReaderT m a
m = (r -> m a) -> ReaderT r m a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT (m a -> r -> m a
forall a b. a -> b -> a
const m a
m)

ask :: (Monad m) => ReaderT r m r
ask :: ReaderT r m r
ask = (r -> m r) -> ReaderT r m r
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT r -> m r
forall (m :: * -> *) a. Monad m => a -> m a
return