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