{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}

module WithCli.Parser where

import           Data.Orphans ()
import           Prelude ()
import           Prelude.Compat

import           Control.Arrow
import           Control.Monad
import           System.Console.GetOpt as Base

import           WithCli.Flag
import           WithCli.Modifier.Types
import           WithCli.Normalize
import           WithCli.Result

data NonOptionsParser uninitialized =
  NonOptionsParser {
    NonOptionsParser uninitialized -> String
nonOptionsType :: String,
    NonOptionsParser uninitialized -> Bool
nonOptionsOptional :: Bool,
    NonOptionsParser uninitialized
-> [String] -> Result (uninitialized -> uninitialized, [String])
nonOptionsParser ::
      [String] -> Result (uninitialized -> uninitialized, [String])
  }

combineNonOptionsParser :: [NonOptionsParser u] -> [NonOptionsParser v]
  -> [NonOptionsParser (u, v)]
combineNonOptionsParser :: [NonOptionsParser u]
-> [NonOptionsParser v] -> [NonOptionsParser (u, v)]
combineNonOptionsParser a :: [NonOptionsParser u]
a b :: [NonOptionsParser v]
b =
  (NonOptionsParser u -> NonOptionsParser (u, v))
-> [NonOptionsParser u] -> [NonOptionsParser (u, v)]
forall a b. (a -> b) -> [a] -> [b]
map (((u -> u) -> (u, v) -> (u, v))
-> NonOptionsParser u -> NonOptionsParser (u, v)
forall a b.
((a -> a) -> b -> b) -> NonOptionsParser a -> NonOptionsParser b
modMod (u -> u) -> (u, v) -> (u, v)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first) [NonOptionsParser u]
a [NonOptionsParser (u, v)]
-> [NonOptionsParser (u, v)] -> [NonOptionsParser (u, v)]
forall a. [a] -> [a] -> [a]
++
  (NonOptionsParser v -> NonOptionsParser (u, v))
-> [NonOptionsParser v] -> [NonOptionsParser (u, v)]
forall a b. (a -> b) -> [a] -> [b]
map (((v -> v) -> (u, v) -> (u, v))
-> NonOptionsParser v -> NonOptionsParser (u, v)
forall a b.
((a -> a) -> b -> b) -> NonOptionsParser a -> NonOptionsParser b
modMod (v -> v) -> (u, v) -> (u, v)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second) [NonOptionsParser v]
b
  where
    modMod :: ((a -> a) -> (b -> b)) -> NonOptionsParser a -> NonOptionsParser b
    modMod :: ((a -> a) -> b -> b) -> NonOptionsParser a -> NonOptionsParser b
modMod f :: (a -> a) -> b -> b
f (NonOptionsParser field :: String
field optional :: Bool
optional parser :: [String] -> Result (a -> a, [String])
parser) =
      String
-> Bool
-> ([String] -> Result (b -> b, [String]))
-> NonOptionsParser b
forall uninitialized.
String
-> Bool
-> ([String] -> Result (uninitialized -> uninitialized, [String]))
-> NonOptionsParser uninitialized
NonOptionsParser String
field Bool
optional ((Result (a -> a, [String]) -> Result (b -> b, [String]))
-> ([String] -> Result (a -> a, [String]))
-> [String]
-> Result (b -> b, [String])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((a -> a, [String]) -> (b -> b, [String]))
-> Result (a -> a, [String]) -> Result (b -> b, [String])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((a -> a) -> b -> b) -> (a -> a, [String]) -> (b -> b, [String])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (a -> a) -> b -> b
f)) [String] -> Result (a -> a, [String])
parser)

data Parser phase a where
  Parser :: {
    ()
parserDefault :: uninitialized,
    ()
parserOptions :: [OptDescr (Result (uninitialized -> uninitialized))],
    ()
parserNonOptions :: [NonOptionsParser uninitialized],
    ()
parserConvert :: uninitialized -> Result a
  } -> Parser phase a

instance Functor (Parser phase) where
  fmap :: (a -> b) -> Parser phase a -> Parser phase b
fmap f :: a -> b
f (Parser def :: uninitialized
def options :: [OptDescr (Result (uninitialized -> uninitialized))]
options nonOptions :: [NonOptionsParser uninitialized]
nonOptions convert :: uninitialized -> Result a
convert) =
    uninitialized
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [NonOptionsParser uninitialized]
-> (uninitialized -> Result b)
-> Parser phase b
forall uninitialized a phase.
uninitialized
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [NonOptionsParser uninitialized]
-> (uninitialized -> Result a)
-> Parser phase a
Parser uninitialized
def [OptDescr (Result (uninitialized -> uninitialized))]
options [NonOptionsParser uninitialized]
nonOptions ((a -> b) -> Result a -> Result b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (Result a -> Result b)
-> (uninitialized -> Result a) -> uninitialized -> Result b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. uninitialized -> Result a
convert)

-- phases:
data Unnormalized
data Normalized

emptyParser :: a -> Parser phase a
emptyParser :: a -> Parser phase a
emptyParser a :: a
a = $WParser :: forall uninitialized a phase.
uninitialized
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [NonOptionsParser uninitialized]
-> (uninitialized -> Result a)
-> Parser phase a
Parser {
  parserDefault :: a
parserDefault = a
a,
  parserOptions :: [OptDescr (Result (a -> a))]
parserOptions = [],
  parserNonOptions :: [NonOptionsParser a]
parserNonOptions = [],
  parserConvert :: a -> Result a
parserConvert = a -> Result a
forall (m :: * -> *) a. Monad m => a -> m a
return
}

normalizeParser :: Parser Unnormalized a -> Parser Normalized a
normalizeParser :: Parser Unnormalized a -> Parser Normalized a
normalizeParser (Parser d :: uninitialized
d options :: [OptDescr (Result (uninitialized -> uninitialized))]
options nonOptions :: [NonOptionsParser uninitialized]
nonOptions convert :: uninitialized -> Result a
convert) =
  uninitialized
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [NonOptionsParser uninitialized]
-> (uninitialized -> Result a)
-> Parser Normalized a
forall uninitialized a phase.
uninitialized
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [NonOptionsParser uninitialized]
-> (uninitialized -> Result a)
-> Parser phase a
Parser uninitialized
d ((OptDescr (Result (uninitialized -> uninitialized))
 -> OptDescr (Result (uninitialized -> uninitialized)))
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [OptDescr (Result (uninitialized -> uninitialized))]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> String)
-> OptDescr (Result (uninitialized -> uninitialized))
-> OptDescr (Result (uninitialized -> uninitialized))
forall a. (String -> String) -> OptDescr a -> OptDescr a
mapLongOptions String -> String
normalize) [OptDescr (Result (uninitialized -> uninitialized))]
options) [NonOptionsParser uninitialized]
nonOptions uninitialized -> Result a
convert
  where
    mapLongOptions :: (String -> String) -> OptDescr a -> OptDescr a
    mapLongOptions :: (String -> String) -> OptDescr a -> OptDescr a
mapLongOptions f :: String -> String
f (Option shorts :: String
shorts longs :: [String]
longs argDescr :: ArgDescr a
argDescr help :: String
help) =
      String -> [String] -> ArgDescr a -> String -> OptDescr a
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
shorts ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
f [String]
longs) ArgDescr a
argDescr String
help

modParserOptions :: (forall x . [OptDescr (Result x)] -> [OptDescr (Result x)])
  -> Parser Unnormalized a -> Parser Unnormalized a
modParserOptions :: (forall x. [OptDescr (Result x)] -> [OptDescr (Result x)])
-> Parser Unnormalized a -> Parser Unnormalized a
modParserOptions f :: forall x. [OptDescr (Result x)] -> [OptDescr (Result x)]
f (Parser def :: uninitialized
def options :: [OptDescr (Result (uninitialized -> uninitialized))]
options nonOptions :: [NonOptionsParser uninitialized]
nonOptions convert :: uninitialized -> Result a
convert) =
  uninitialized
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [NonOptionsParser uninitialized]
-> (uninitialized -> Result a)
-> Parser Unnormalized a
forall uninitialized a phase.
uninitialized
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [NonOptionsParser uninitialized]
-> (uninitialized -> Result a)
-> Parser phase a
Parser uninitialized
def ([OptDescr (Result (uninitialized -> uninitialized))]
-> [OptDescr (Result (uninitialized -> uninitialized))]
forall x. [OptDescr (Result x)] -> [OptDescr (Result x)]
f [OptDescr (Result (uninitialized -> uninitialized))]
options) [NonOptionsParser uninitialized]
nonOptions uninitialized -> Result a
convert

combine :: forall a b phase .
  Result (Parser phase a) -> Result (Parser phase b)
  -> Result (Parser phase (a, b))
combine :: Result (Parser phase a)
-> Result (Parser phase b) -> Result (Parser phase (a, b))
combine a :: Result (Parser phase a)
a b :: Result (Parser phase b)
b = Parser phase a -> Parser phase b -> Parser phase (a, b)
inner (Parser phase a -> Parser phase b -> Parser phase (a, b))
-> Result (Parser phase a)
-> Result (Parser phase b -> Parser phase (a, b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Result (Parser phase a)
a Result (Parser phase b -> Parser phase (a, b))
-> Result (Parser phase b) -> Result (Parser phase (a, b))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Result (Parser phase b)
b
  where
    inner :: Parser phase a -> Parser phase b -> Parser phase (a, b)
    inner :: Parser phase a -> Parser phase b -> Parser phase (a, b)
inner (Parser defaultA :: uninitialized
defaultA optionsA :: [OptDescr (Result (uninitialized -> uninitialized))]
optionsA nonOptionsA :: [NonOptionsParser uninitialized]
nonOptionsA convertA :: uninitialized -> Result a
convertA) (Parser defaultB :: uninitialized
defaultB optionsB :: [OptDescr (Result (uninitialized -> uninitialized))]
optionsB nonOptionsB :: [NonOptionsParser uninitialized]
nonOptionsB convertB :: uninitialized -> Result b
convertB) =
      $WParser :: forall uninitialized a phase.
uninitialized
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [NonOptionsParser uninitialized]
-> (uninitialized -> Result a)
-> Parser phase a
Parser {
        parserDefault :: (uninitialized, uninitialized)
parserDefault = (uninitialized
defaultA, uninitialized
defaultB),
        parserOptions :: [OptDescr
   (Result
      ((uninitialized, uninitialized)
       -> (uninitialized, uninitialized)))]
parserOptions =
          (OptDescr (Result (uninitialized -> uninitialized))
 -> OptDescr
      (Result
         ((uninitialized, uninitialized)
          -> (uninitialized, uninitialized))))
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [OptDescr
      (Result
         ((uninitialized, uninitialized)
          -> (uninitialized, uninitialized)))]
forall a b. (a -> b) -> [a] -> [b]
map ((Result (uninitialized -> uninitialized)
 -> Result
      ((uninitialized, uninitialized) -> (uninitialized, uninitialized)))
-> OptDescr (Result (uninitialized -> uninitialized))
-> OptDescr
     (Result
        ((uninitialized, uninitialized) -> (uninitialized, uninitialized)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((uninitialized -> uninitialized)
 -> (uninitialized, uninitialized)
 -> (uninitialized, uninitialized))
-> Result (uninitialized -> uninitialized)
-> Result
     ((uninitialized, uninitialized) -> (uninitialized, uninitialized))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (uninitialized -> uninitialized)
-> (uninitialized, uninitialized) -> (uninitialized, uninitialized)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first)) [OptDescr (Result (uninitialized -> uninitialized))]
optionsA [OptDescr
   (Result
      ((uninitialized, uninitialized)
       -> (uninitialized, uninitialized)))]
-> [OptDescr
      (Result
         ((uninitialized, uninitialized)
          -> (uninitialized, uninitialized)))]
-> [OptDescr
      (Result
         ((uninitialized, uninitialized)
          -> (uninitialized, uninitialized)))]
forall a. [a] -> [a] -> [a]
++ (OptDescr (Result (uninitialized -> uninitialized))
 -> OptDescr
      (Result
         ((uninitialized, uninitialized)
          -> (uninitialized, uninitialized))))
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [OptDescr
      (Result
         ((uninitialized, uninitialized)
          -> (uninitialized, uninitialized)))]
forall a b. (a -> b) -> [a] -> [b]
map ((Result (uninitialized -> uninitialized)
 -> Result
      ((uninitialized, uninitialized) -> (uninitialized, uninitialized)))
-> OptDescr (Result (uninitialized -> uninitialized))
-> OptDescr
     (Result
        ((uninitialized, uninitialized) -> (uninitialized, uninitialized)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((uninitialized -> uninitialized)
 -> (uninitialized, uninitialized)
 -> (uninitialized, uninitialized))
-> Result (uninitialized -> uninitialized)
-> Result
     ((uninitialized, uninitialized) -> (uninitialized, uninitialized))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (uninitialized -> uninitialized)
-> (uninitialized, uninitialized) -> (uninitialized, uninitialized)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second)) [OptDescr (Result (uninitialized -> uninitialized))]
optionsB,
        parserNonOptions :: [NonOptionsParser (uninitialized, uninitialized)]
parserNonOptions = [NonOptionsParser uninitialized]
-> [NonOptionsParser uninitialized]
-> [NonOptionsParser (uninitialized, uninitialized)]
forall u v.
[NonOptionsParser u]
-> [NonOptionsParser v] -> [NonOptionsParser (u, v)]
combineNonOptionsParser [NonOptionsParser uninitialized]
nonOptionsA [NonOptionsParser uninitialized]
nonOptionsB,
        parserConvert :: (uninitialized, uninitialized) -> Result (a, b)
parserConvert =
          \ (u :: uninitialized
u, v :: uninitialized
v) -> (,) (a -> b -> (a, b)) -> Result a -> Result (b -> (a, b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (uninitialized -> Result a
convertA uninitialized
u) Result (b -> (a, b)) -> Result b -> Result (a, b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (uninitialized -> Result b
convertB uninitialized
v)
      }

fillInOptions :: [Result (u -> u)] -> u -> Result u
fillInOptions :: [Result (u -> u)] -> u -> Result u
fillInOptions [] u :: u
u = u -> Result u
forall (m :: * -> *) a. Monad m => a -> m a
return u
u
fillInOptions (option :: Result (u -> u)
option : options :: [Result (u -> u)]
options) u :: u
u = do
  u -> u
f <- Result (u -> u)
option
  [Result (u -> u)] -> u -> Result u
forall u. [Result (u -> u)] -> u -> Result u
fillInOptions [Result (u -> u)]
options (u -> u
f u
u)

fillInNonOptions :: [[String] -> Result (u -> u, [String])] -> [String] -> u
  -> Result u
fillInNonOptions :: [[String] -> Result (u -> u, [String])]
-> [String] -> u -> Result u
fillInNonOptions (parser :: [String] -> Result (u -> u, [String])
parser : parsers :: [[String] -> Result (u -> u, [String])]
parsers) nonOptions :: [String]
nonOptions@(_ : _) u :: u
u = do
  (p :: u -> u
p, rest :: [String]
rest) <- [String] -> Result (u -> u, [String])
parser [String]
nonOptions
  [[String] -> Result (u -> u, [String])]
-> [String] -> u -> Result u
forall u.
[[String] -> Result (u -> u, [String])]
-> [String] -> u -> Result u
fillInNonOptions [[String] -> Result (u -> u, [String])]
parsers [String]
rest (u -> u
p u
u)
fillInNonOptions [] [] u :: u
u =
  u -> Result u
forall (m :: * -> *) a. Monad m => a -> m a
return u
u
fillInNonOptions [] nonOptions :: [String]
nonOptions _ =
  String -> Result u
forall a. String -> Result a
Errors (String -> Result u) -> String -> Result u
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ("unknown argument: " String -> String -> String
forall a. [a] -> [a] -> [a]
++) [String]
nonOptions)
fillInNonOptions _ [] u :: u
u = u -> Result u
forall (m :: * -> *) a. Monad m => a -> m a
return u
u

runParser :: String -> Modifiers -> Parser Normalized a -> [String] -> Result a
runParser :: String -> Modifiers -> Parser Normalized a -> [String] -> Result a
runParser progName :: String
progName modifiers :: Modifiers
modifiers Parser{..} args :: [String]
args =
  [NonOptionsParser uninitialized] -> Result ()
forall a. [NonOptionsParser a] -> Result ()
checkNonOptionParsers [NonOptionsParser uninitialized]
parserNonOptions Result () -> Result a -> Result a
forall a b. Result a -> Result b -> Result b
|>
  let versionOptions :: [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
versionOptions = [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
-> (String
    -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))])
-> Maybe String
-> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe []
        (\ v :: String
v -> OptDescr (Flag (Result (uninitialized -> uninitialized)))
-> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (OptDescr (Flag (Result (uninitialized -> uninitialized)))
 -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))])
-> OptDescr (Flag (Result (uninitialized -> uninitialized)))
-> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
forall a b. (a -> b) -> a -> b
$ String -> OptDescr (Flag (Result (uninitialized -> uninitialized)))
forall a. String -> OptDescr (Flag a)
versionOption (String
progName String -> String -> String
forall a. [a] -> [a] -> [a]
++ " version " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
v))
        (Modifiers -> Maybe String
getVersion Modifiers
modifiers)
      options :: [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
options = (OptDescr (Result (uninitialized -> uninitialized))
 -> OptDescr (Flag (Result (uninitialized -> uninitialized))))
-> [OptDescr (Result (uninitialized -> uninitialized))]
-> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
forall a b. (a -> b) -> [a] -> [b]
map ((Result (uninitialized -> uninitialized)
 -> Flag (Result (uninitialized -> uninitialized)))
-> OptDescr (Result (uninitialized -> uninitialized))
-> OptDescr (Flag (Result (uninitialized -> uninitialized)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Result (uninitialized -> uninitialized)
-> Flag (Result (uninitialized -> uninitialized))
forall a. a -> Flag a
NoHelp) [OptDescr (Result (uninitialized -> uninitialized))]
parserOptions [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
-> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
-> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
forall a. [a] -> [a] -> [a]
++ [OptDescr (Flag (Result (uninitialized -> uninitialized)))
forall a. OptDescr (Flag a)
helpOption] [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
-> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
-> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
forall a. [a] -> [a] -> [a]
++ [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
versionOptions
      (flags :: [Flag (Result (uninitialized -> uninitialized))]
flags, nonOptions :: [String]
nonOptions, errs :: [String]
errs) =
        ArgOrder (Flag (Result (uninitialized -> uninitialized)))
-> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
-> [String]
-> ([Flag (Result (uninitialized -> uninitialized))], [String],
    [String])
forall a.
ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String])
Base.getOpt ArgOrder (Flag (Result (uninitialized -> uninitialized)))
forall a. ArgOrder a
Base.Permute [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
options [String]
args
  in case [Flag (Result (uninitialized -> uninitialized))]
-> Flag [Result (uninitialized -> uninitialized)]
forall a. [Flag a] -> Flag [a]
foldFlags [Flag (Result (uninitialized -> uninitialized))]
flags of
    Help -> String -> Result a
forall a. String -> Result a
OutputAndExit (String -> Result a) -> String -> Result a
forall a b. (a -> b) -> a -> b
$
      let fields :: [(Bool, String)]
fields = case Modifiers -> Maybe String
getPositionalArgumentType Modifiers
modifiers of
            Nothing -> (NonOptionsParser uninitialized -> (Bool, String))
-> [NonOptionsParser uninitialized] -> [(Bool, String)]
forall a b. (a -> b) -> [a] -> [b]
map (\ p :: NonOptionsParser uninitialized
p -> (NonOptionsParser uninitialized -> Bool
forall uninitialized. NonOptionsParser uninitialized -> Bool
nonOptionsOptional NonOptionsParser uninitialized
p, NonOptionsParser uninitialized -> String
forall uninitialized. NonOptionsParser uninitialized -> String
nonOptionsType NonOptionsParser uninitialized
p)) [NonOptionsParser uninitialized]
parserNonOptions
            Just typ :: String
typ -> [(Bool
True, String
typ)]
      in String -> [(Bool, String)] -> [OptDescr ()] -> String
usage String
progName [(Bool, String)]
fields ((OptDescr (Flag (Result (uninitialized -> uninitialized)))
 -> OptDescr ())
-> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
-> [OptDescr ()]
forall a b. (a -> b) -> [a] -> [b]
map OptDescr (Flag (Result (uninitialized -> uninitialized)))
-> OptDescr ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
options)
    Version msg :: String
msg -> String -> Result a
forall a. String -> Result a
OutputAndExit String
msg
    NoHelp innerFlags :: [Result (uninitialized -> uninitialized)]
innerFlags ->
      [String] -> Result ()
reportErrors [String]
errs Result () -> Result a -> Result a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
      ([Result (uninitialized -> uninitialized)]
-> uninitialized -> Result uninitialized
forall u. [Result (u -> u)] -> u -> Result u
fillInOptions [Result (uninitialized -> uninitialized)]
innerFlags uninitialized
parserDefault Result uninitialized
-> (uninitialized -> Result uninitialized) -> Result uninitialized
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
       [[String] -> Result (uninitialized -> uninitialized, [String])]
-> [String] -> uninitialized -> Result uninitialized
forall u.
[[String] -> Result (u -> u, [String])]
-> [String] -> u -> Result u
fillInNonOptions ((NonOptionsParser uninitialized
 -> [String] -> Result (uninitialized -> uninitialized, [String]))
-> [NonOptionsParser uninitialized]
-> [[String] -> Result (uninitialized -> uninitialized, [String])]
forall a b. (a -> b) -> [a] -> [b]
map NonOptionsParser uninitialized
-> [String] -> Result (uninitialized -> uninitialized, [String])
forall uninitialized.
NonOptionsParser uninitialized
-> [String] -> Result (uninitialized -> uninitialized, [String])
nonOptionsParser [NonOptionsParser uninitialized]
parserNonOptions) [String]
nonOptions Result uninitialized -> (uninitialized -> Result a) -> Result a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
       uninitialized -> Result a
parserConvert)
  where
    reportErrors :: [String] -> Result ()
    reportErrors :: [String] -> Result ()
reportErrors = \ case
      [] -> () -> Result ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      errs :: [String]
errs -> String -> Result ()
forall a. String -> Result a
Errors (String -> Result ()) -> String -> Result ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines [String]
errs

    checkNonOptionParsers :: [NonOptionsParser a] -> Result ()
    checkNonOptionParsers :: [NonOptionsParser a] -> Result ()
checkNonOptionParsers parsers :: [NonOptionsParser a]
parsers =
      case (NonOptionsParser a -> Bool)
-> [NonOptionsParser a] -> [NonOptionsParser a]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile NonOptionsParser a -> Bool
forall uninitialized. NonOptionsParser uninitialized -> Bool
nonOptionsOptional ([NonOptionsParser a] -> [NonOptionsParser a])
-> [NonOptionsParser a] -> [NonOptionsParser a]
forall a b. (a -> b) -> a -> b
$ (NonOptionsParser a -> Bool)
-> [NonOptionsParser a] -> [NonOptionsParser a]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Bool -> Bool
not (Bool -> Bool)
-> (NonOptionsParser a -> Bool) -> NonOptionsParser a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonOptionsParser a -> Bool
forall uninitialized. NonOptionsParser uninitialized -> Bool
nonOptionsOptional) [NonOptionsParser a]
parsers of
        [] -> () -> Result ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
        (_ : _) -> String -> Result ()
forall a. String -> Result a
Errors "cannot use Maybes for optional arguments before any non-optional arguments"