hledger/hledger-lib/Hledger/Data/RawOptions.hs
Moritz Kiefer 4141067428 Replace Parsec with Megaparsec (see #289) (#366)
* Replace Parsec with Megaparsec (see #289)

This builds upon PR #289 by @rasendubi

* Revert renaming of parseWithState to parseWithCtx

* Fix doctests

* Update for Megaparsec 5

* Specialize parser to improve performance

* Pretty print errors

* Swap StateT and ParsecT

This is necessary to get the correct backtracking behavior, i.e. discard
state changes if the parsing fails.
2016-07-29 08:57:10 -07:00

70 lines
1.8 KiB
Haskell

{-|
hledger's cmdargs modes parse command-line arguments to an
intermediate format, RawOpts (an association list), rather than a
fixed ADT like CliOpts. This allows the modes and flags to be reused
more easily by hledger commands/scripts in this and other packages.
-}
module Hledger.Data.RawOptions (
RawOpts,
setopt,
setboolopt,
inRawOpts,
boolopt,
stringopt,
maybestringopt,
listofstringopt,
intopt,
maybeintopt,
optserror
)
where
import Data.Maybe
import qualified Data.Text as T
import Safe
import Hledger.Utils
-- | The result of running cmdargs: an association list of option names to string values.
type RawOpts = [(String,String)]
setopt :: String -> String -> RawOpts -> RawOpts
setopt name val = (++ [(name, quoteIfNeeded $ val)])
setboolopt :: String -> RawOpts -> RawOpts
setboolopt name = (++ [(name,"")])
-- | Is the named option present ?
inRawOpts :: String -> RawOpts -> Bool
inRawOpts name = isJust . lookup name
boolopt :: String -> RawOpts -> Bool
boolopt = inRawOpts
maybestringopt :: String -> RawOpts -> Maybe String
maybestringopt name = maybe Nothing (Just . T.unpack . stripquotes . T.pack) . lookup name . reverse
stringopt :: String -> RawOpts -> String
stringopt name = fromMaybe "" . maybestringopt name
listofstringopt :: String -> RawOpts -> [String]
listofstringopt name rawopts = [v | (k,v) <- rawopts, k==name]
maybeintopt :: String -> RawOpts -> Maybe Int
maybeintopt name rawopts =
let ms = maybestringopt name rawopts in
case ms of Nothing -> Nothing
Just s -> Just $ readDef (optserror $ "could not parse "++name++" number: "++s) s
intopt :: String -> RawOpts -> Int
intopt name = fromMaybe 0 . maybeintopt name
-- | Raise an error, showing the specified message plus a hint about --help.
optserror :: String -> a
optserror = error' . (++ " (run with --help for usage)")