module Configuration.Dotenv.ParsedVariable (ParsedVariable(..),
VarName,
VarValue(..),
VarContents,
VarFragment(..),
interpolateParsedVariables) where
import Configuration.Dotenv.Environment (lookupEnv)
import Control.Applicative ((<|>))
import Control.Monad (foldM)
import System.Process (proc, readCreateProcess)
data ParsedVariable
= ParsedVariable VarName VarValue deriving (Int -> ParsedVariable -> ShowS
[ParsedVariable] -> ShowS
ParsedVariable -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ParsedVariable] -> ShowS
$cshowList :: [ParsedVariable] -> ShowS
show :: ParsedVariable -> String
$cshow :: ParsedVariable -> String
showsPrec :: Int -> ParsedVariable -> ShowS
$cshowsPrec :: Int -> ParsedVariable -> ShowS
Show, ParsedVariable -> ParsedVariable -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ParsedVariable -> ParsedVariable -> Bool
$c/= :: ParsedVariable -> ParsedVariable -> Bool
== :: ParsedVariable -> ParsedVariable -> Bool
$c== :: ParsedVariable -> ParsedVariable -> Bool
Eq)
type VarName = String
data VarValue
= Unquoted VarContents
| SingleQuoted VarContents
| DoubleQuoted VarContents deriving (Int -> VarValue -> ShowS
[VarValue] -> ShowS
VarValue -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VarValue] -> ShowS
$cshowList :: [VarValue] -> ShowS
show :: VarValue -> String
$cshow :: VarValue -> String
showsPrec :: Int -> VarValue -> ShowS
$cshowsPrec :: Int -> VarValue -> ShowS
Show, VarValue -> VarValue -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VarValue -> VarValue -> Bool
$c/= :: VarValue -> VarValue -> Bool
== :: VarValue -> VarValue -> Bool
$c== :: VarValue -> VarValue -> Bool
Eq)
type VarContents = [VarFragment]
data VarFragment
= VarInterpolation String
| VarLiteral String
| CommandInterpolation String [String] deriving (Int -> VarFragment -> ShowS
VarContents -> ShowS
VarFragment -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: VarContents -> ShowS
$cshowList :: VarContents -> ShowS
show :: VarFragment -> String
$cshow :: VarFragment -> String
showsPrec :: Int -> VarFragment -> ShowS
$cshowsPrec :: Int -> VarFragment -> ShowS
Show, VarFragment -> VarFragment -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VarFragment -> VarFragment -> Bool
$c/= :: VarFragment -> VarFragment -> Bool
== :: VarFragment -> VarFragment -> Bool
$c== :: VarFragment -> VarFragment -> Bool
Eq)
interpolateParsedVariables :: [ParsedVariable] -> IO [(String, String)]
interpolateParsedVariables :: [ParsedVariable] -> IO [(String, String)]
interpolateParsedVariables = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM [(String, String)] -> ParsedVariable -> IO [(String, String)]
addInterpolated []
addInterpolated :: [(String, String)] -> ParsedVariable -> IO [(String, String)]
addInterpolated :: [(String, String)] -> ParsedVariable -> IO [(String, String)]
addInterpolated [(String, String)]
previous (ParsedVariable String
name VarValue
value) = (forall a. a -> [a] -> [a]
: [(String, String)]
previous) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((,) String
name forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(String, String)] -> VarValue -> IO String
interpolate [(String, String)]
previous VarValue
value)
interpolate :: [(String, String)] -> VarValue -> IO String
interpolate :: [(String, String)] -> VarValue -> IO String
interpolate [(String, String)]
_ (SingleQuoted VarContents
contents) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ VarContents -> String
joinContents VarContents
contents
interpolate [(String, String)]
previous (DoubleQuoted VarContents
contents) = [(String, String)] -> VarContents -> IO String
interpolateContents [(String, String)]
previous VarContents
contents
interpolate [(String, String)]
previous (Unquoted VarContents
contents) = [(String, String)] -> VarContents -> IO String
interpolateContents [(String, String)]
previous VarContents
contents
interpolateContents :: [(String, String)] -> VarContents -> IO String
interpolateContents :: [(String, String)] -> VarContents -> IO String
interpolateContents [(String, String)]
previous VarContents
contents = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ([(String, String)] -> VarFragment -> IO String
interpolateFragment [(String, String)]
previous) VarContents
contents
interpolateFragment :: [(String, String)] -> VarFragment -> IO String
interpolateFragment :: [(String, String)] -> VarFragment -> IO String
interpolateFragment [(String, String)]
_ (VarLiteral String
value ) = forall (m :: * -> *) a. Monad m => a -> m a
return String
value
interpolateFragment [(String, String)]
previous (VarInterpolation String
varname) = IO (Maybe String)
fromPreviousOrEnv forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. Monad m => a -> m a
return String
"") forall (m :: * -> *) a. Monad m => a -> m a
return
where
fromPreviousOrEnv :: IO (Maybe String)
fromPreviousOrEnv = (forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
varname [(String, String)]
previous forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO (Maybe String)
lookupEnv String
varname
interpolateFragment [(String, String)]
_ (CommandInterpolation String
commandName [String]
args) = forall a. [a] -> [a]
init forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CreateProcess -> String -> IO String
readCreateProcess (String -> [String] -> CreateProcess
proc String
commandName [String]
args) String
""
joinContents :: VarContents -> String
joinContents :: VarContents -> String
joinContents = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap VarFragment -> String
fragmentToString
where
fragmentToString :: VarFragment -> String
fragmentToString (CommandInterpolation String
commandName [String]
args) = [String] -> String
unwords forall a b. (a -> b) -> a -> b
$ String
commandName forall a. a -> [a] -> [a]
: [String]
args
fragmentToString (VarInterpolation String
value) = String
value
fragmentToString (VarLiteral String
value) = String
value