{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}

{-|
Module      : Options.Applicative.Args
Description : Accepting arguments to be passed through to a sub-process.
License     : BSD-3-Clause

Accepting arguments to be passed through to a sub-process.
-}

module Options.Applicative.Args
  ( argsArgument
  , argsOption
  , cmdOption
  ) where

import           Data.Attoparsec.Args ( EscapingMode (..), parseArgsFromString )
import qualified Options.Applicative as O
import           Stack.Prelude

-- | An argument which accepts a list of arguments

-- e.g. @--ghc-options="-X P.hs \"this\""@.

argsArgument :: O.Mod O.ArgumentFields [String] -> O.Parser [String]
argsArgument :: Mod ArgumentFields [String] -> Parser [String]
argsArgument =
  ReadM [String] -> Mod ArgumentFields [String] -> Parser [String]
forall a. ReadM a -> Mod ArgumentFields a -> Parser a
O.argument
    ( do s <- ReadM String
forall s. IsString s => ReadM s
O.str
         either O.readerError pure (parseArgsFromString Escaping s)
    )

-- | An option which accepts a list of arguments

-- e.g. @--ghc-options="-X P.hs \"this\""@.

argsOption :: O.Mod O.OptionFields [String] -> O.Parser [String]
argsOption :: Mod OptionFields [String] -> Parser [String]
argsOption =
  ReadM [String] -> Mod OptionFields [String] -> Parser [String]
forall a. ReadM a -> Mod OptionFields a -> Parser a
O.option
    ( do s <- ReadM String
forall s. IsString s => ReadM s
O.str
         either O.readerError pure (parseArgsFromString Escaping s)
    )

-- | An option which accepts a command and a list of arguments

-- e.g. @--exec "echo hello world"@

cmdOption ::
     O.Mod O.OptionFields (String, [String])
  -> O.Parser (String, [String])
cmdOption :: Mod OptionFields (String, [String]) -> Parser (String, [String])
cmdOption =
  ReadM (String, [String])
-> Mod OptionFields (String, [String]) -> Parser (String, [String])
forall a. ReadM a -> Mod OptionFields a -> Parser a
O.option
    ( do s <- ReadM String
forall s. IsString s => ReadM s
O.str
         either O.readerError pure (parseArgsFromString Escaping s) >>= \case
           [] -> String -> ReadM (String, [String])
forall a. String -> ReadM a
O.readerError String
"Must provide a command"
           String
x:[String]
xs' -> (String, [String]) -> ReadM (String, [String])
forall a. a -> ReadM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String
x, [String]
xs')
    )