packages feed

optparse-declarative-0.1.0: README.md

# optparse-declarative

`optparse-declarative` is a declarative and easy to use command-line option parser.

# Install

```bash
$ cabal install optparse-declarative
```

# Usage

## Writing a simple command

First, you need to enable `DataKinds` extension and import `Options.Declarative` module.

```hs
{-# LANGUAGE DataKinds #-}
import           Options.Declarative
```

Then, define the command line option as a **type of the function**.
For example, this is a simple greeting program:

```hs
greet :: Flag "g" '["greet"] "STRING" "greeting message" (Def "Hello" String)
      -> Arg "NAME" String
      -> Cmd "greet"
greet msg name = Cmd $ do
    putStrLn $ get msg ++ ", " ++ get name ++ "!"
```

There are two type of options, `Flag` and `Arg`.
`Flag` is named argument and `Arg` is unnamed argument.
Last argument of both options is value type.
If you need to specify default value, use the modifiers such as `Def`.

In above, variable `msg` has a very complex type (`Flag "g" '["greet"] "STRING" "greeting message" (Def "Hello" String)`).
In order to get the value of usual type (in this case, that is `String`),
you can use `get` function.

The whole type of command is `Cmd`.
`Cmd <description>` is basically newtype of `IO ()`,
except this contains extra information.

When you define the command, there remains only invoking the command.

```hs
main :: IO ()
main = run_ greet
```

You can execute this program like this:

```bash
$ ghc simple.hs

$ ./simple
simple: not enough arguments
Try 'simple --help' for more information.

$ ./simple --help
Usage: simple [OPTION...] NAME
Options:
  -g STRING  --greet=STRING  greeting message
  -?         --help          display this help and exit

$ ./simple World
Hello, World!

$ ./simple --greet=Goodbye World
Goodbye, World!
```

## Writing multiple sum-commands

You can write (nested) sub-commands.

Just groupe subcommands by `Group`, you got sub-command parser.

This is the example:

```hs
{-# LANGUAGE DataKinds #-}

import           Options.Declarative

main :: IO ()
main = run_ $
    Group "Test program for library"
    [ subCmd "greet"   greet
    , subCmd "connect" connect
    ]

greet :: Flag "g" '["greet"] "STRING" "greeting message" (Def "Hello" String)
      -> Flag "" '["decolate"] "" "decolate message" Bool
      -> Arg "NAME" String
      -> Cmd "Greeting command"
greet msg deco name = Cmd $ do
    let f x | get deco = "*** " ++ x ++ " ***"
            | otherwise = x
    putStrLn $ f $ get msg ++ ", " ++ get name ++ "!"

connect :: Flag "h" '["host"] "HOST" "host name"   (Def "localhost" String)
        -> Flag "p" '["port"] "PORT" "port number" (Def "8080"      Int   )
    -> Cmd "Connect command"
connect host port = Cmd $ do
    let addr = get host ++ ":" ++ show (get port)
    putStrLn $ "connect to " ++ addr
```

And this is the output:

```bash
$ ./subcmd --help
Usage: subcmd [OPTION...] <COMMAND> [ARGS...]
Options:
  -?  --help  display this help and exit

Commands:
  greet       Greeting command
  port        Server command

$ ./subcmd connect --port=1234
connect to localhost:1234
```

For more examples, please see `example` directory.