=== Typed options and arguments

The described `link:../dataobjects.html#Option[Option]` and `link:../dataobjects.html#Argument[Argument]` classes are _untyped_,
meaning that the only get String values.
`link:unavailable[TypedOption]` and `link:unavailable[TypedArgument]` let you specify a _type_, so the
(String) raw value is converted to the specified type.

Instead of
`link:../dataobjects.html#Option[Option]` and `link:../dataobjects.html#Argument[Argument]`, use `link:unavailable[TypedOption]`
and `link:unavailable[TypedArgument]` in the `link:../../yardoc/Vertx/CLI.html[CLI]` definition:

[source,java]
----
CLI cli = CLI.create("copy")
    .setSummary("A command line interface to copy files.")
    .addOption(new TypedOption<Boolean>()
        .setType(Boolean.class)
        .setLongName("directory")
        .setShortName("R")
        .setDescription("enables directory support")
        .setFlag(true))
    .addArgument(new TypedArgument<File>()
        .setType(File.class)
        .setIndex(0)
        .setDescription("The source")
        .setArgName("source"))
    .addArgument(new TypedArgument<File>()
        .setType(File.class)
        .setIndex(0)
        .setDescription("The destination")
        .setArgName("target"));
----

Then you can retrieve the converted values as follows:

[source,java]
----
CommandLine commandLine = cli.parse(userCommandLineArguments);
boolean flag = commandLine.getOptionValue("R");
File source = commandLine.getArgumentValue("source");
File target = commandLine.getArgumentValue("target");
----

The vert.x CLI is able to convert to classes:

* having a constructor with a single
`link:unavailable[String]` argument, such as `link:unavailable[File]` or `link:unavailable[JsonObject]`
* with a static `from` or `fromString` method
* with a static `valueOf` method, such as primitive types and enumeration

In addition, you can implement your own `link:unavailable[Converter]` and instruct the CLI to use
this converter:

[source,java]
----
CLI cli = CLI.create("some-name")
    .addOption(new TypedOption<Person>()
        .setType(Person.class)
        .setConverter(new PersonConverter())
        .setLongName("person"));
----

For booleans, the boolean values are evaluated to `true`: `on`, `yes`, `1`, `true`.

If one of your option has an `enum` as type, it computes the set of choices automatically.

=== Using annotations

You can also define your CLI using annotations. Definition is done using annotation on the class and on _setter_
methods:

[source, java]
----
&#64;Name("some-name")
&#64;Summary("some short summary.")
&#64;Description("some long description")
public class AnnotatedCli {

 private boolean flag;
 private String name;
 private String arg;

&#64;Option(shortName = "f", flag = true)
public void setFlag(boolean flag) {
  this.flag = flag;
}

&#64;Option(longName = "name")
public void setName(String name) {
  this.name = name;
}

&#64;Argument(index = 0)
public void setArg(String arg) {
 this.arg = arg;
}
}
----

Once annotated, you can define the `link:../../yardoc/Vertx/CLI.html[CLI]` and inject the values using:

[source,java]
----
CLI cli = CLI.create(AnnotatedCli.class);
CommandLine commandLine = cli.parse(userCommandLineArguments);
AnnotatedCli instance = new AnnotatedCli();
CLIConfigurator.inject(commandLine, instance);
----