module Hedgehog.Extras.Internal.Cli
  ( argQuote
  ) where

import           Data.Bool
import           Data.Semigroup
import           Data.String

import qualified Data.List as L

-- | Format argument for a shell CLI command.
--
-- This includes automatically embedding string in double quotes if necessary, including any necessary escaping.
--
-- Note, this function does not cover all the edge cases for shell processing, so avoid use in production code.
argQuote :: String -> String
argQuote :: String -> String
argQuote String
arg = if Char
' ' Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`L.elem` String
arg Bool -> Bool -> Bool
|| Char
'"' Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`L.elem` String
arg Bool -> Bool -> Bool
|| Char
'$' Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`L.elem` String
arg
  then String
"\"" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String -> String
escape String
arg String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"\""
  else String
arg
  where escape :: String -> String
        escape :: String -> String
escape (Char
'"':String
xs) = Char
'\\'Char -> String -> String
forall a. a -> [a] -> [a]
:Char
'"'Char -> String -> String
forall a. a -> [a] -> [a]
:String -> String
escape String
xs
        escape (Char
'\\':String
xs) = Char
'\\'Char -> String -> String
forall a. a -> [a] -> [a]
:Char
'\\'Char -> String -> String
forall a. a -> [a] -> [a]
:String -> String
escape String
xs
        escape (Char
'\n':String
xs) = Char
'\\'Char -> String -> String
forall a. a -> [a] -> [a]
:Char
'n'Char -> String -> String
forall a. a -> [a] -> [a]
:String -> String
escape String
xs
        escape (Char
'\r':String
xs) = Char
'\\'Char -> String -> String
forall a. a -> [a] -> [a]
:Char
'r'Char -> String -> String
forall a. a -> [a] -> [a]
:String -> String
escape String
xs
        escape (Char
'\t':String
xs) = Char
'\\'Char -> String -> String
forall a. a -> [a] -> [a]
:Char
't'Char -> String -> String
forall a. a -> [a] -> [a]
:String -> String
escape String
xs
        escape (Char
'$':String
xs) = Char
'\\'Char -> String -> String
forall a. a -> [a] -> [a]
:Char
'$'Char -> String -> String
forall a. a -> [a] -> [a]
:String -> String
escape String
xs
        escape (Char
x:String
xs) = Char
xChar -> String -> String
forall a. a -> [a] -> [a]
:String -> String
escape String
xs
        escape String
"" = String
""