{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
module DotEnv (DotEnv, EnvPath(..), loadEnv, getEnv) where
import Data.ByteString (ByteString)
import Data.HashMap.Strict (HashMap)
import qualified Data.ByteString.Char8 as BS
import qualified Data.HashMap.Strict as HashMap
type DotEnv = HashMap ByteString ByteString
data EnvPath = EnvPath FilePath | DefaultEnv
fromEnvPath :: EnvPath -> FilePath
fromEnvPath :: EnvPath -> FilePath
fromEnvPath (EnvPath FilePath
path) = FilePath
path
fromEnvPath EnvPath
DefaultEnv = FilePath
".env"
loadEnv :: EnvPath -> IO DotEnv
loadEnv :: EnvPath -> IO DotEnv
loadEnv EnvPath
path = [(ByteString, ByteString)] -> DotEnv
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList ([(ByteString, ByteString)] -> DotEnv)
-> (ByteString -> [(ByteString, ByteString)])
-> ByteString
-> DotEnv
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> (ByteString, ByteString))
-> [ByteString] -> [(ByteString, ByteString)]
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> (ByteString, ByteString)
parseEnvLine ([ByteString] -> [(ByteString, ByteString)])
-> (ByteString -> [ByteString])
-> ByteString
-> [(ByteString, ByteString)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
BS.lines (ByteString -> DotEnv) -> IO ByteString -> IO DotEnv
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO ByteString
BS.readFile (EnvPath -> FilePath
fromEnvPath EnvPath
path)
getEnv :: DotEnv -> ByteString -> Maybe ByteString
getEnv :: DotEnv -> ByteString -> Maybe ByteString
getEnv = (ByteString -> DotEnv -> Maybe ByteString)
-> DotEnv -> ByteString -> Maybe ByteString
forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString -> DotEnv -> Maybe ByteString
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup
parseEnvLine :: ByteString -> (ByteString, ByteString)
parseEnvLine :: ByteString -> (ByteString, ByteString)
parseEnvLine ByteString
x = let (ByteString
key, HasCallStack => ByteString -> ByteString
ByteString -> ByteString
BS.tail -> ByteString
value) = (Char -> Bool) -> ByteString -> (ByteString, ByteString)
BS.break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'=') ByteString
x in (ByteString
key, ByteString
value)