Merge branch 'ggonzalez/options2'
This commit is contained in:
commit
ab15df5e32
1 changed files with 44 additions and 42 deletions
|
@ -9,8 +9,8 @@
|
||||||
-- > import Turtle
|
-- > import Turtle
|
||||||
-- >
|
-- >
|
||||||
-- > parser :: Parser (Text, Int)
|
-- > parser :: Parser (Text, Int)
|
||||||
-- > parser = (,) <$> optText "name" "Your first name"
|
-- > parser = (,) <$> optText "name" 'n' "Your first name"
|
||||||
-- > <*> optIntegral "age" "Your current age"
|
-- > <*> optInt "age" 'a' "Your current age"
|
||||||
-- >
|
-- >
|
||||||
-- > main = do
|
-- > main = do
|
||||||
-- > (name, age) <- options "Greeting script" parser
|
-- > (name, age) <- options "Greeting script" parser
|
||||||
|
@ -35,21 +35,24 @@ module Turtle.Options
|
||||||
( -- * Types
|
( -- * Types
|
||||||
Parser
|
Parser
|
||||||
, ArgName
|
, ArgName
|
||||||
|
, ShortName
|
||||||
, Description
|
, Description
|
||||||
, HelpMessage
|
, HelpMessage
|
||||||
|
|
||||||
-- * Flag-based option parsers
|
-- * Flag-based option parsers
|
||||||
, switch
|
, switch
|
||||||
, optText
|
, optText
|
||||||
, optIntegral
|
, optInt
|
||||||
, optFractional
|
, optInteger
|
||||||
|
, optDouble
|
||||||
, optRead
|
, optRead
|
||||||
, opt
|
, opt
|
||||||
|
|
||||||
-- * Positional argument parsers
|
-- * Positional argument parsers
|
||||||
, argText
|
, argText
|
||||||
, argIntegral
|
, argInt
|
||||||
, argFractional
|
, argInteger
|
||||||
|
, argDouble
|
||||||
, argRead
|
, argRead
|
||||||
, arg
|
, arg
|
||||||
|
|
||||||
|
@ -80,13 +83,16 @@ options desc parser = liftIO
|
||||||
|
|
||||||
{-| The name of a command-line argument
|
{-| The name of a command-line argument
|
||||||
|
|
||||||
This is used to infer the long name, short name, and metavariable for the
|
This is used to infer the long name and metavariable for the command line
|
||||||
command line flag. For example, an `ArgName` of @\"name\"@ will create a
|
flag. For example, an `ArgName` of @\"name\"@ will create a @--name@ flag
|
||||||
@--name@ flag with a @NAME@ metavariable and a short name of @-n@
|
with a @NAME@ metavariable
|
||||||
-}
|
-}
|
||||||
newtype ArgName = ArgName { getArgName :: Text }
|
newtype ArgName = ArgName { getArgName :: Text }
|
||||||
deriving (IsString)
|
deriving (IsString)
|
||||||
|
|
||||||
|
-- | The short one-character abbreviation for a flag (i.e. @-n@)
|
||||||
|
type ShortName = Char
|
||||||
|
|
||||||
{-| A brief description of what your program does
|
{-| A brief description of what your program does
|
||||||
|
|
||||||
This description will appear in the header of the @--help@ output
|
This description will appear in the header of the @--help@ output
|
||||||
|
@ -106,12 +112,13 @@ newtype HelpMessage = HelpMessage { getHelpMessage :: Text }
|
||||||
-}
|
-}
|
||||||
switch
|
switch
|
||||||
:: ArgName
|
:: ArgName
|
||||||
|
-> ShortName
|
||||||
-> Optional HelpMessage
|
-> Optional HelpMessage
|
||||||
-> Parser Bool
|
-> Parser Bool
|
||||||
switch argName helpMessage
|
switch argName c helpMessage
|
||||||
= Opts.switch
|
= Opts.switch
|
||||||
$ (Opts.long . Text.unpack . getArgName) argName
|
$ (Opts.long . Text.unpack . getArgName) argName
|
||||||
<> foldMap (Opts.short . fst) (Text.uncons (getArgName argName))
|
<> Opts.short c
|
||||||
<> foldMap (Opts.help . Text.unpack . getHelpMessage) helpMessage
|
<> foldMap (Opts.help . Text.unpack . getHelpMessage) helpMessage
|
||||||
|
|
||||||
{- | Build a flag-based option parser for any type by providing a `Text`-parsing
|
{- | Build a flag-based option parser for any type by providing a `Text`-parsing
|
||||||
|
@ -119,38 +126,36 @@ switch argName helpMessage
|
||||||
-}
|
-}
|
||||||
opt :: (Text -> Maybe a)
|
opt :: (Text -> Maybe a)
|
||||||
-> ArgName
|
-> ArgName
|
||||||
|
-> ShortName
|
||||||
-> Optional HelpMessage
|
-> Optional HelpMessage
|
||||||
-> Parser a
|
-> Parser a
|
||||||
opt argParse argName helpMessage
|
opt argParse argName c helpMessage
|
||||||
= Opts.option (argParseToReadM argParse)
|
= Opts.option (argParseToReadM argParse)
|
||||||
$ Opts.metavar (Text.unpack (Text.toUpper (getArgName argName)))
|
$ Opts.metavar (Text.unpack (Text.toUpper (getArgName argName)))
|
||||||
<> Opts.long (Text.unpack (getArgName argName))
|
<> Opts.long (Text.unpack (getArgName argName))
|
||||||
<> foldMap (Opts.short . fst) (Text.uncons (getArgName argName))
|
<> Opts.short c
|
||||||
<> foldMap (Opts.help . Text.unpack . getHelpMessage) helpMessage
|
<> foldMap (Opts.help . Text.unpack . getHelpMessage) helpMessage
|
||||||
|
|
||||||
-- | Parse any type that implements `Read`
|
-- | Parse any type that implements `Read`
|
||||||
optRead :: Read a => ArgName -> Optional HelpMessage -> Parser a
|
optRead :: Read a => ArgName -> ShortName -> Optional HelpMessage -> Parser a
|
||||||
optRead = opt (readMaybe . Text.unpack)
|
optRead = opt (readMaybe . Text.unpack)
|
||||||
|
|
||||||
{-| Parse any type that implements `Integral` as n flag-based option
|
-- | Parse an `Int` as a flag-based option
|
||||||
|
optInt :: ArgName -> ShortName -> Optional HelpMessage -> Parser Int
|
||||||
|
optInt = optRead
|
||||||
|
|
||||||
This is most commonly used to parse an `Int` or `Integer`
|
-- | Parse an `Integer` as a flag-based option
|
||||||
-}
|
optInteger :: ArgName -> ShortName -> Optional HelpMessage -> Parser Integer
|
||||||
optIntegral :: Integral n => ArgName -> Optional HelpMessage -> Parser n
|
optInteger = optRead
|
||||||
optIntegral argName helpMessage = fmap fromInteger (optRead argName helpMessage)
|
|
||||||
|
-- | Parse a `Double` as a flag-based option
|
||||||
|
optDouble :: ArgName -> ShortName -> Optional HelpMessage -> Parser Double
|
||||||
|
optDouble = optRead
|
||||||
|
|
||||||
-- | Parse a `Text` value as a flag-based option
|
-- | Parse a `Text` value as a flag-based option
|
||||||
optText :: ArgName -> Optional HelpMessage -> Parser Text
|
optText :: ArgName -> ShortName -> Optional HelpMessage -> Parser Text
|
||||||
optText = opt Just
|
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
|
{- | Build a positional argument parser for any type by providing a
|
||||||
`Text`-parsing function
|
`Text`-parsing function
|
||||||
-}
|
-}
|
||||||
|
@ -167,25 +172,22 @@ arg argParse argName helpMessage
|
||||||
argRead :: Read a => ArgName -> Optional HelpMessage -> Parser a
|
argRead :: Read a => ArgName -> Optional HelpMessage -> Parser a
|
||||||
argRead = arg (readMaybe . Text.unpack)
|
argRead = arg (readMaybe . Text.unpack)
|
||||||
|
|
||||||
{-| Parse any type that implements `Integral` as a positional argument
|
-- | Parse an `Int` as a positional argument
|
||||||
|
argInt :: ArgName -> Optional HelpMessage -> Parser Int
|
||||||
|
argInt = argRead
|
||||||
|
|
||||||
This is most commonly used to parse an `Int` or `Integer`
|
-- | Parse an `Integer` as a positional argument
|
||||||
-}
|
argInteger :: ArgName -> Optional HelpMessage -> Parser Integer
|
||||||
argIntegral :: Integral n => ArgName -> Optional HelpMessage -> Parser n
|
argInteger = argRead
|
||||||
argIntegral argName helpMessage = fmap fromInteger (argRead argName helpMessage)
|
|
||||||
|
|
||||||
-- | Parse a `Text` value as a positional argument
|
-- | Parse a `Double` as a positional argument
|
||||||
|
argDouble :: ArgName -> Optional HelpMessage -> Parser Double
|
||||||
|
argDouble = argRead
|
||||||
|
|
||||||
|
-- | Parse a `Text` as a positional argument
|
||||||
argText :: ArgName -> Optional HelpMessage -> Parser Text
|
argText :: ArgName -> Optional HelpMessage -> Parser Text
|
||||||
argText = arg Just
|
argText = arg Just
|
||||||
|
|
||||||
{-| Parse any type that implements `Fractional` as a positional argument
|
|
||||||
|
|
||||||
This is most commonly used to parse a `Double`
|
|
||||||
-}
|
|
||||||
argFractional :: Fractional n => ArgName -> Optional HelpMessage -> Parser n
|
|
||||||
argFractional argName helpMessage =
|
|
||||||
fmap fromRational (argRead argName helpMessage)
|
|
||||||
|
|
||||||
argParseToReadM :: (Text -> Maybe a) -> Opts.ReadM a
|
argParseToReadM :: (Text -> Maybe a) -> Opts.ReadM a
|
||||||
argParseToReadM f = do
|
argParseToReadM f = do
|
||||||
s <- Opts.readerAsk
|
s <- Opts.readerAsk
|
||||||
|
|
Loading…
Reference in a new issue