module System.Console.Docopt.NoTH
  (
    -- * Usage parsers
      parseUsage
    , parseUsageOrExit

    , module System.Console.Docopt.Public
  )
  where

import Data.Map as M hiding (null)
import System.Exit

import System.Console.Docopt.Types
import System.Console.Docopt.Public
import System.Console.Docopt.ParseUtils
import System.Console.Docopt.UsageParse (pDocopt, trimEmptyLines)


-- | Parse docopt-formatted usage patterns.
--
--   For help with the docopt usage format, see
--   <https://github.com/docopt/docopt.hs/blob/master/README.md#help-text-format the readme on github>.
parseUsage :: String -> Either ParseError Docopt
parseUsage :: String -> Either ParseError Docopt
parseUsage String
rawUsg =
  let usg :: String
usg = String -> String
trimEmptyLines String
rawUsg
  in case GenParser Char OptInfoMap OptFormat
-> OptInfoMap -> String -> String -> Either ParseError OptFormat
forall tok st a.
GenParser tok st a -> st -> String -> [tok] -> Either ParseError a
runParser GenParser Char OptInfoMap OptFormat
pDocopt OptInfoMap
forall k a. Map k a
M.empty String
"Usage" String
usg of
    Left ParseError
e       -> ParseError -> Either ParseError Docopt
forall a b. a -> Either a b
Left ParseError
e
    Right OptFormat
optfmt -> Docopt -> Either ParseError Docopt
forall a b. b -> Either a b
Right (OptFormat -> String -> Docopt
Docopt OptFormat
optfmt String
usg)

-- | Same as 'parseUsage', but 'exitWithUsage' on parse failure. E.g.
--
-- > let usageStr = "Usage:\n  prog [--option]\n"
-- > patterns <- parseUsageOrExit usageStr
parseUsageOrExit :: String -> IO Docopt
parseUsageOrExit :: String -> IO Docopt
parseUsageOrExit String
rawUsg = Either ParseError Docopt -> IO Docopt
forall {a} {b}. Either a b -> IO b
exitUnless (Either ParseError Docopt -> IO Docopt)
-> Either ParseError Docopt -> IO Docopt
forall a b. (a -> b) -> a -> b
$ String -> Either ParseError Docopt
parseUsage String
usg
  where
    usg :: String
usg = String -> String
trimEmptyLines String
rawUsg
    exit :: String -> IO b
exit String
message = String -> IO ()
putStrLn String
message IO () -> IO b -> IO b
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO b
forall a. IO a
exitFailure
    exitUnless :: Either a b -> IO b
exitUnless = (a -> IO b) -> (b -> IO b) -> Either a b -> IO b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (IO b -> a -> IO b
forall a b. a -> b -> a
const (IO b -> a -> IO b) -> IO b -> a -> IO b
forall a b. (a -> b) -> a -> b
$ String -> IO b
forall {b}. String -> IO b
exit String
usg) b -> IO b
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return