Add back positional argument parsers and short names

This commit is contained in:
Gabriel Gonzalez 2015-06-28 17:54:13 -07:00
parent 8169c4086f
commit 8848646a98

View file

@ -9,8 +9,8 @@
-- > import Turtle
-- >
-- > parser :: Parser (Text, Int)
-- > parser = (,) <$> argText "name" "Your first name"
-- > <*> argIntegral "age" "Your current age"
-- > parser = (,) <$> optText "name" "Your first name"
-- > <*> optIntegral "age" "Your current age"
-- >
-- > main = do
-- > (name, age) <- options "Greeting script" parser
@ -24,7 +24,7 @@
-- > $ ./options --help
-- > Greeting script
-- >
-- > Usage: options --name NAME --age AGE
-- > Usage: options (-n|--name NAME) (-a|--age AGE)
-- >
-- > Available options:
-- > -h,--help Show this help text
@ -38,8 +38,15 @@ module Turtle.Options
, Description
, HelpMessage
-- * Build parsers
-- * Flag-based option parsers
, switch
, optText
, optIntegral
, optFractional
, optRead
, opt
-- * Positional argument parsers
, argText
, argIntegral
, argFractional
@ -73,9 +80,9 @@ options desc parser = liftIO
{-| The name of a command-line argument
This is used to infer the long name and metavariable for the command line
flag. For example, an `ArgName` of @\"name\"@ will create a @--name@ flag
with a @NAME@ metavariable
This is used to infer the long name, short name, and metavariable for the
command line flag. For example, an `ArgName` of @\"name\"@ will create a
@--name@ flag with a @NAME@ metavariable and a short name of @-n@
-}
newtype ArgName = ArgName { getArgName :: Text }
deriving (IsString)
@ -104,37 +111,74 @@ switch
switch argName helpMessage
= Opts.switch
$ (Opts.long . Text.unpack . getArgName) argName
<> foldMap (Opts.short . fst) (Text.uncons (getArgName argName))
<> foldMap (Opts.help . Text.unpack . getHelpMessage) helpMessage
{- | Build an argument parser for any type by providing a `Text`-parsing
{- | Build a flag-based option parser for any type by providing a `Text`-parsing
function
-}
opt :: (Text -> Maybe a)
-> ArgName
-> Optional HelpMessage
-> Parser a
opt argParse argName helpMessage
= Opts.option (argParseToReadM argParse)
$ Opts.metavar (Text.unpack (Text.toUpper (getArgName argName)))
<> Opts.long (Text.unpack (getArgName argName))
<> foldMap (Opts.short . fst) (Text.uncons (getArgName argName))
<> foldMap (Opts.help . Text.unpack . getHelpMessage) helpMessage
-- | Parse any type that implements `Read`
optRead :: Read a => ArgName -> Optional HelpMessage -> Parser a
optRead = opt (readMaybe . Text.unpack)
{-| Parse any type that implements `Integral` as n flag-based option
This is most commonly used to parse an `Int` or `Integer`
-}
optIntegral :: Integral n => ArgName -> Optional HelpMessage -> Parser n
optIntegral argName helpMessage = fmap fromInteger (optRead argName helpMessage)
-- | Parse a `Text` value as a flag-based option
optText :: ArgName -> Optional HelpMessage -> Parser Text
optText = opt Just
{-| Parse any type that implements `Fractional` as a flag-based option
This is most commonly used to parse a `Double`
-}
optFractional :: Fractional n => ArgName -> Optional HelpMessage -> Parser n
optFractional argName helpMessage =
fmap fromRational (optRead argName helpMessage)
{- | Build a positional argument parser for any type by providing a
`Text`-parsing function
-}
arg :: (Text -> Maybe a)
-> ArgName
-> Optional HelpMessage
-> Parser a
arg argParse argName helpMessage
= Opts.option (argParseToReadM argParse)
= Opts.argument (argParseToReadM argParse)
$ Opts.metavar (Text.unpack (Text.toUpper (getArgName argName)))
<> Opts.long (Text.unpack (getArgName argName))
<> foldMap (Opts.help . Text.unpack . getHelpMessage) helpMessage
-- | Parse any type that implements `Read`
-- | Parse any type that implements `Read` as a positional argument
argRead :: Read a => ArgName -> Optional HelpMessage -> Parser a
argRead = arg (readMaybe . Text.unpack)
{-| Parse any type that implements `Integral`
{-| Parse any type that implements `Integral` as a positional argument
This is most commonly used to parse an `Int` or `Integer`
-}
argIntegral :: Integral n => ArgName -> Optional HelpMessage -> Parser n
argIntegral argName helpMessage = fmap fromInteger (argRead argName helpMessage)
-- | Parse a `Text` value
-- | Parse a `Text` value as a positional argument
argText :: ArgName -> Optional HelpMessage -> Parser Text
argText = arg Just
{-| Parse any type that implements `Fractional`
{-| Parse any type that implements `Fractional` as a positional argument
This is most commonly used to parse a `Double`
-}