-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Create command line interfaces with ease -- -- Create command line interfaces with ease @package getopt-generics @version 0.12 module WithCli -- | withCli converts an IO operation into a program with a proper -- CLI. Retrieves command line arguments through withArgs. -- main (the given IO operation) can have arbitrarily many -- parameters provided all parameters have instances for -- HasArguments. -- -- May throw the following exceptions: -- --
-- import WithCli -- -- main :: IO () -- main = withCli run -- -- run :: String -> Int -> Bool -> IO () -- run s i b = print (s, i, b) ---- -- Using the above program in a shell: -- --
-- $ program foo 42 true
-- ("foo",42,True)
-- $ program --help
-- program [OPTIONS] STRING INTEGER BOOL
-- -h --help show help and exit
-- $ program foo 42 bar
-- cannot parse as BOOL: bar
-- # exit-code 1
-- $ program
-- missing argument of type STRING
-- missing argument of type INTEGER
-- missing argument of type BOOL
-- # exit-code 1
-- $ program foo 42 yes bar
-- unknown argument: bar
-- # exit-code 1
--
withCli :: WithCli main => main -> IO ()
-- | Everything that can be used as a main function with
-- withCli needs to have an instance of WithCli. You
-- shouldn't need to implement your own instances.
class WithCli main
-- | Everything that can be used as an argument to your main
-- function (see withCli) needs to have a HasArguments
-- instance.
--
-- HasArguments also allows to conjure up instances for record
-- types to create more complex command line interfaces. Here's an
-- example:
--
--
-- {-# LANGUAGE DeriveAnyClass #-}
-- {-# LANGUAGE DeriveGeneric #-}
--
-- import WithCli
--
-- data Options
-- = Options {
-- port :: Int,
-- daemonize :: Bool,
-- config :: Maybe FilePath
-- }
-- deriving (Show, Generic, HasArguments)
--
-- main :: IO ()
-- main = withCli run
--
-- run :: Options -> IO ()
-- run = print
--
--
-- In a shell this program behaves like this:
--
--
-- $ program --port 8080 --config some/path
-- Options {port = 8080, daemonize = False, config = Just "some/path"}
-- $ program --port 8080 --daemonize
-- Options {port = 8080, daemonize = True, config = Nothing}
-- $ program --port foo
-- cannot parse as INTEGER: foo
-- # exit-code 1
-- $ program
-- missing option: --port=INTEGER
-- # exit-code 1
-- $ program --help
-- program [OPTIONS]
-- --port=INTEGER
-- --daemonize
-- --config=STRING (optional)
-- -h --help show help and exit
--
class HasArguments a where argumentsParser = const . genericParser
argumentsParser :: HasArguments a => Modifiers -> Maybe String -> Result (Parser Unnormalized a)
-- | Useful for implementing your own instances of HasArguments on
-- top of a custom Argument instance.
atomicArgumentsParser :: Argument a => Modifiers -> Maybe String -> Result (Parser Unnormalized a)
-- | Argument is a typeclass for things that can be parsed as atomic
-- values from single command line arguments, e.g. strings (and
-- filenames) and numbers.
--
-- Occasionally you might want to declare your own instance for
-- additional type safety and for providing a more informative command
-- argument type. Here's an example:
--
--
-- {-# LANGUAGE DeriveDataTypeable #-}
--
-- import WithCli
--
-- data File = File FilePath
-- deriving (Show, Typeable)
--
-- instance Argument File where
-- argumentType Proxy = "custom-file-type"
-- parseArgument f = Just (File f)
--
-- instance HasArguments File where
-- argumentsParser = atomicArgumentsParser
--
-- main :: IO ()
-- main = withCli run
--
-- run :: File -> IO ()
-- run = print
--
--
-- And this is how the above program behaves:
--
-- -- $ program --help -- program [OPTIONS] custom-file-type -- -h --help show help and exit -- $ program some/file -- File "some/file" --class Argument a argumentType :: Argument a => Proxy a -> String parseArgument :: Argument a => String -> Maybe a -- | This is a variant of withCli that allows to tweak the generated -- command line interface by providing a list of Modifiers. withCliModified :: WithCli main => [Modifier] -> main -> IO () -- | Modifiers can be used to customize the command line parser. data Modifier -- | AddShortOption fieldName c adds the Char c as -- a short option for the field addressed by fieldName. AddShortOption :: String -> Char -> Modifier -- | RenameOption fieldName customName renames the option -- generated through the fieldName by customName. RenameOption :: String -> String -> Modifier -- | RenameOptions f renames all options with the given functions. -- In case the function returns Nothing the original field name -- is used. -- -- Can be used together with stripPrefix. RenameOptions :: (String -> Maybe String) -> Modifier -- | UseForPositionalArguments fieldName argumentType fills the -- field addressed by fieldName with the positional arguments -- (i.e. arguments that don't correspond to a flag). The field has to -- have type [String]. -- -- argumentType is used as the type of the positional arguments -- in the help output. UseForPositionalArguments :: String -> String -> Modifier -- | AddOptionHelp fieldName helpText adds a help text for the -- option fieldName. AddOptionHelp :: String -> String -> Modifier -- | AddVersionFlag version adds a --version flag. AddVersionFlag :: String -> Modifier -- | Representable types of kind *. This class is derivable in GHC with the -- DeriveGeneric flag on. class Generic a -- | The class Typeable allows a concrete representation of a type -- to be calculated. class Typeable (a :: k) -- | A concrete, poly-kinded proxy type data Proxy (t :: k) :: k -> * Proxy :: Proxy instance WithCli.WithCli (GHC.Types.IO ()) instance (WithCli.HasArguments.HasArguments a, WithCli.WithCli rest) => WithCli.WithCli (a -> rest) module System.Console.GetOpt.Generics -- | withCli converts an IO operation into a program with a proper -- CLI. Retrieves command line arguments through withArgs. -- main (the given IO operation) can have arbitrarily many -- parameters provided all parameters have instances for -- HasArguments. -- -- May throw the following exceptions: -- --
-- import WithCli -- -- main :: IO () -- main = withCli run -- -- run :: String -> Int -> Bool -> IO () -- run s i b = print (s, i, b) ---- -- Using the above program in a shell: -- --
-- $ program foo 42 true
-- ("foo",42,True)
-- $ program --help
-- program [OPTIONS] STRING INTEGER BOOL
-- -h --help show help and exit
-- $ program foo 42 bar
-- cannot parse as BOOL: bar
-- # exit-code 1
-- $ program
-- missing argument of type STRING
-- missing argument of type INTEGER
-- missing argument of type BOOL
-- # exit-code 1
-- $ program foo 42 yes bar
-- unknown argument: bar
-- # exit-code 1
--
withCli :: WithCli main => main -> IO ()
-- | Everything that can be used as a main function with
-- withCli needs to have an instance of WithCli. You
-- shouldn't need to implement your own instances.
class WithCli main
-- | Everything that can be used as an argument to your main
-- function (see withCli) needs to have a HasArguments
-- instance.
--
-- HasArguments also allows to conjure up instances for record
-- types to create more complex command line interfaces. Here's an
-- example:
--
--
-- {-# LANGUAGE DeriveAnyClass #-}
-- {-# LANGUAGE DeriveGeneric #-}
--
-- import WithCli
--
-- data Options
-- = Options {
-- port :: Int,
-- daemonize :: Bool,
-- config :: Maybe FilePath
-- }
-- deriving (Show, Generic, HasArguments)
--
-- main :: IO ()
-- main = withCli run
--
-- run :: Options -> IO ()
-- run = print
--
--
-- In a shell this program behaves like this:
--
--
-- $ program --port 8080 --config some/path
-- Options {port = 8080, daemonize = False, config = Just "some/path"}
-- $ program --port 8080 --daemonize
-- Options {port = 8080, daemonize = True, config = Nothing}
-- $ program --port foo
-- cannot parse as INTEGER: foo
-- # exit-code 1
-- $ program
-- missing option: --port=INTEGER
-- # exit-code 1
-- $ program --help
-- program [OPTIONS]
-- --port=INTEGER
-- --daemonize
-- --config=STRING (optional)
-- -h --help show help and exit
--
class HasArguments a where argumentsParser = const . genericParser
-- | Argument is a typeclass for things that can be parsed as atomic
-- values from single command line arguments, e.g. strings (and
-- filenames) and numbers.
--
-- Occasionally you might want to declare your own instance for
-- additional type safety and for providing a more informative command
-- argument type. Here's an example:
--
--
-- {-# LANGUAGE DeriveDataTypeable #-}
--
-- import WithCli
--
-- data File = File FilePath
-- deriving (Show, Typeable)
--
-- instance Argument File where
-- argumentType Proxy = "custom-file-type"
-- parseArgument f = Just (File f)
--
-- instance HasArguments File where
-- argumentsParser = atomicArgumentsParser
--
-- main :: IO ()
-- main = withCli run
--
-- run :: File -> IO ()
-- run = print
--
--
-- And this is how the above program behaves:
--
-- -- $ program --help -- program [OPTIONS] custom-file-type -- -h --help show help and exit -- $ program some/file -- File "some/file" --class Argument a argumentType :: Argument a => Proxy a -> String parseArgument :: Argument a => String -> Maybe a -- | This is a variant of withCli that allows to tweak the generated -- command line interface by providing a list of Modifiers. withCliModified :: WithCli main => [Modifier] -> main -> IO () -- | Modifiers can be used to customize the command line parser. data Modifier -- | AddShortOption fieldName c adds the Char c as -- a short option for the field addressed by fieldName. AddShortOption :: String -> Char -> Modifier -- | RenameOption fieldName customName renames the option -- generated through the fieldName by customName. RenameOption :: String -> String -> Modifier -- | RenameOptions f renames all options with the given functions. -- In case the function returns Nothing the original field name -- is used. -- -- Can be used together with stripPrefix. RenameOptions :: (String -> Maybe String) -> Modifier -- | UseForPositionalArguments fieldName argumentType fills the -- field addressed by fieldName with the positional arguments -- (i.e. arguments that don't correspond to a flag). The field has to -- have type [String]. -- -- argumentType is used as the type of the positional arguments -- in the help output. UseForPositionalArguments :: String -> String -> Modifier -- | AddOptionHelp fieldName helpText adds a help text for the -- option fieldName. AddOptionHelp :: String -> String -> Modifier -- | AddVersionFlag version adds a --version flag. AddVersionFlag :: String -> Modifier -- | Parses command line arguments (gotten from withArgs) and -- returns the parsed value. This function should be enough for simple -- use-cases. -- -- Throws the same exceptions as withCli. -- -- Here's an example: -- --
-- {-# LANGUAGE DeriveGeneric #-}
--
-- module RecordType where
--
-- import System.Console.GetOpt.Generics
--
-- -- All you have to do is to define a type and derive an instance for Generic:
--
-- data Options
-- = Options {
-- port :: Int,
-- daemonize :: Bool,
-- config :: Maybe FilePath
-- }
-- deriving (Show, Generic)
--
-- -- Then you can use `getArguments` to create a command-line argument parser:
--
-- main :: IO ()
-- main = do
-- options <- getArguments
-- print (options :: Options)
--
--
-- And this is how the above program behaves:
--
--
-- $ program --port 8080 --config some/path
-- Options {port = 8080, daemonize = False, config = Just "some/path"}
-- $ program --port 8080 --daemonize
-- Options {port = 8080, daemonize = True, config = Nothing}
-- $ program --port foo
-- cannot parse as INTEGER: foo
-- # exit-code 1
-- $ program
-- missing option: --port=INTEGER
-- # exit-code 1
-- $ program --help
-- program [OPTIONS]
-- --port=INTEGER
-- --daemonize
-- --config=STRING (optional)
-- -h --help show help and exit
--
getArguments :: (Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => IO a
-- | Like getArguments but allows you to pass in Modifiers.
modifiedGetArguments :: (Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => [Modifier] -> IO a
-- | Pure variant of modifiedGetArguments.
--
-- Does not throw any exceptions.
parseArguments :: (Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => String -> [Modifier] -> [String] -> Result a
-- | Type to wrap results from the pure parsing functions.
data Result a
-- | The CLI was used correctly and a value of type a was
-- successfully constructed.
Success :: a -> Result a
-- | The CLI was used incorrectly. The Result contains a list of
-- error messages.
--
-- It can also happen that the data type you're trying to use isn't
-- supported. See the README for details.
Errors :: [String] -> Result a
-- | The CLI was used with --help. The Result contains the
-- help message.
OutputAndExit :: String -> Result a
-- | Representable types of kind *. This class is derivable in GHC with the
-- DeriveGeneric flag on.
class Generic a
-- | Constraint for the class that computes gdatatypeInfo.
type GDatatypeInfo a = GDatatypeInfo' (Rep a)
-- | Compute the SOP code of a datatype.
--
-- This requires that Rep is defined, which in turn requires that
-- the type has a Generic (from module GHC.Generics)
-- instance.
--
-- This is the default definition for Code. For more info, see
-- Generic.
type GCode a = ToSumCode (Rep a) ([] [*])
-- | Require a constraint for every element of a list of lists.
--
-- If you have a datatype that is indexed over a type-level list of
-- lists, then you can use All2 to indicate that all elements of
-- the innert lists must satisfy a given constraint.
--
-- Example: The constraint
--
-- -- All2 Eq '[ '[ Int ], '[ Bool, Char ] ] ---- -- is equivalent to the constraint -- --
-- (Eq Int, Eq Bool, Eq Char) ---- -- Example: A type signature such as -- --
-- f :: All2 Eq xss => SOP I xs -> ... ---- -- means that f can assume that all elements of the sum of -- product satisfy Eq. class (AllF [k] (All k f) xss, SListI [k] xss) => All2 (f :: k -> Constraint) (xss :: [[k]])