# `CliMate.CLI.Option`
[🔗](https://github.com/lud/cli_mate/blob/v0.10.2/lib/cli_mate/cli/option.ex#L1)

Describes an option.

When declaring a command, the `:options` entry is a keyword list that accepts
these settings, all optional:

* `:type` - Uses the `OptionParser` module under the hood, so the following
  types are accepted:
  * `:boolean` - If the default value is `true`, `OptionParser` supports the
    `--no-` prefix to the options.
  * `:count` - Counts the number of times the flag is given.
  * `:integer` - Value is parsed or an error is returned.
  * `:float` - Same as `:integer`.
  * `:string` - Value is used as-is.
* `:doc` - A string describing the role of the option. It is displayed in the
  usage block shown with `--help` or `mix help`.
* `:short` - A single letter atom like `:a`, `:b`, etc. For instance with
  these options:

      @command options: [
        name: [short: :n]
      ]

* `:default` - The default value to set if the option is not given. See the
  "Default values" section below.

  The command line will accept both `--name` and `-n` switches.

* `:keep` - A boolean. This flag is used with `OptionParser`. When `true`
  duplicate options will not override each other but will rather be
  accumulated in a list. The option value will always be a list even when
  provided a single time in the command line arguments. The option will also
  be present, as an empty list, if the option is not given in command line
  arguments.
* `:doc_arg` - A string to display in the usage block. Defaults the type of
  the option, as in:

  ```text
  Options

    -n --some-int <integer>  This option does not define :doc_arg.
    -o --other-int <other>   Here "other" was provided as :doc_arg.
  ```
* `:default_doc` - The string to output when CliMate does not know how to
  display the default value. That is, when the default value is defined by a
  function. Not used when `:default` is not defined.
* `:cast` - A fun accepting the value, or a `{module, function, arguments}`,
  returning a result tuple. See the "Casting" section below for more
  information.

### Casting

When the `:cast` option is a fun, it will be called with the parsed value
(after `OptionParser` has converted it to the appropriate type). When it is an
"MFA" tuple, the parsed value will be prepended to the given arguments.

Cast functions must return `{:ok, value}` or `{:error, reason}`. The `reason`
can be anything, but at the moment CliMate doesn't do any special formatting
on it to display errors (besides calling `to_string/1` with a safe fallback to
`inspect/1`). It is advised to return a meaningful error message as the
reason.

When the `:keep` option is enabled, the cast function is called on each value
individually, not on the entire list.

Note that cast functions are NOT applied to default values.

### Default values

Default values can be omitted, in that case, the option will not be present at
all when parsing the command line arguments. This is especially important for
booleans, where one would expect that they automatically default to false. It
is not the case.

When defined, a default value can be:

* A raw value, that is anything that is not a function. This value will be
  used as the default value.
* A function of arity zero. This function will be called when the option is
  not provided in the command line and the result value will be used as the
  default value. For instance `fn -> 123 end` or `&default_for_some_opt/0`.
* A function of arity one. This function will be called with the option key as
  its argument. For instance, passing `&default_opt/1` as the `:default` for
  an option definition allow to define the following function:

      defp default_opt(:port), do: 4000
      defp default_opt(:scheme), do: "http"

When the command is defined in a module attribute, you need to pass the module
prefix or the compilation will fail:

    defmodule MyCommand do
      use Mix.Task

      @command name: "my command",
               options: [
                 some_arg: [
                   default: &__MODULE__.cast_some/1
                 ]
               ]
    end

# `caster`

```elixir
@type caster() ::
  (term() -&gt; {:ok, term()} | {:error, term()}) | {module(), atom(), [term()]}
```

# `t`

```elixir
@type t() :: %CliMate.CLI.Option{
  cast: nil | caster(),
  default: term(),
  default_doc: String.t(),
  doc: String.t(),
  doc_arg: String.t(),
  keep: boolean(),
  key: atom(),
  short: atom(),
  type: vtype()
}
```

# `vtype`

```elixir
@type vtype() :: :integer | :float | :string | :count | :boolean
```

# `new`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
