-- | Defines types and functions for generating Makefiles.
module Build.Drasil.Make.MakeString where

-- * Types

-- | Type synonym for variable names.
type VarName = String
-- | Type synonym for variable values.
type VarVal = String

data MakeString = Mr String -- ^ A string for Makefiles.
                | Mv MVar -- ^ Holds a Makefile variable.
                | Mc MakeString MakeString -- ^ Concatenates two 'MakeString's.

instance Semigroup MakeString where
  <> :: MakeString -> MakeString -> MakeString
(<>) = MakeString -> MakeString -> MakeString
Mc

instance Monoid MakeString where
  mempty :: MakeString
mempty = String -> MakeString
Mr String
""

-- | For creating Makefile variables.
data MVar = Os VarName VarVal VarVal VarVal -- ^ Operating System specific variable. Holds information for Windows, Mac, and Linux systems.
          | Implicit VarName -- ^ Implicit OS.
          | Free VarName -- ^ Independent of OS.
          deriving MVar -> MVar -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MVar -> MVar -> Bool
$c/= :: MVar -> MVar -> Bool
== :: MVar -> MVar -> Bool
$c== :: MVar -> MVar -> Bool
Eq

-- * Functions

-- | Concatenates two 'MakeString's with a space in between.
(+:+) :: MakeString -> MakeString -> MakeString
MakeString
a +:+ :: MakeString -> MakeString -> MakeString
+:+ (Mr String
"") = MakeString
a
(Mr String
"") +:+ MakeString
b = MakeString
b
MakeString
a +:+ MakeString
b = MakeString
a forall a. Semigroup a => a -> a -> a
<> String -> MakeString
Mr String
" " forall a. Semigroup a => a -> a -> a
<> MakeString
b

-- | Renders a 'MakeString'. Variables have the form \"$(@var@)\".
renderMS :: MakeString -> String
renderMS :: MakeString -> String
renderMS (Mr String
s) = String
s
renderMS (Mv MVar
v) = (String -> String) -> MVar -> String
renderVar (\String
x -> String
"$(" forall a. [a] -> [a] -> [a]
++ String
x forall a. [a] -> [a] -> [a]
++ String
")") MVar
v
renderMS (Mc MakeString
a MakeString
b) = MakeString -> String
renderMS MakeString
a forall a. [a] -> [a] -> [a]
++ MakeString -> String
renderMS MakeString
b

-- | Renders variables. Takes in a function for the variable, and the type of variable.
renderVar :: (String -> String) -> MVar -> String
renderVar :: (String -> String) -> MVar -> String
renderVar String -> String
f (Os String
nm String
_ String
_ String
_) = String -> String
f String
nm
renderVar String -> String
f (Implicit String
nm) = String
"\"" forall a. [a] -> [a] -> [a]
++ String -> String
f String
nm forall a. [a] -> [a] -> [a]
++ String
"\""
renderVar String -> String
f (Free String
nm) = String -> String
f String
nm

-- | Constructor for converting a 'String' into a 'MakeString'.
makeS :: String -> MakeString
makeS :: String -> MakeString
makeS = String -> MakeString
Mr

-- | Constructor for Windows OS variables.
mkWindowsVar :: VarName -> VarVal -> VarVal -> MakeString
mkWindowsVar :: String -> String -> String -> MakeString
mkWindowsVar String
n String
w String
e = MVar -> MakeString
Mv forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String -> MVar
Os String
n String
w String
e String
e

-- | Constructor for OS variables.
mkOSVar :: VarName -> VarVal -> VarVal -> VarVal -> MakeString
mkOSVar :: String -> String -> String -> String -> MakeString
mkOSVar String
n String
w String
m String
l = MVar -> MakeString
Mv forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String -> MVar
Os String
n String
w String
m String
l

-- | Constructor for 'Implicit' variables.
mkImplicitVar :: VarName -> MakeString
mkImplicitVar :: String -> MakeString
mkImplicitVar = MVar -> MakeString
Mv forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> MVar
Implicit

-- | Constructor for 'Free' variables.
mkFreeVar :: VarName -> MakeString
mkFreeVar :: String -> MakeString
mkFreeVar = MVar -> MakeString
Mv forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> MVar
Free