aboutsummaryrefslogtreecommitdiff
path: root/structopt/examples
diff options
context:
space:
mode:
Diffstat (limited to 'structopt/examples')
-rw-r--r--structopt/examples/README.md82
-rw-r--r--structopt/examples/after_help.rs19
-rw-r--r--structopt/examples/at_least_two.rs15
-rw-r--r--structopt/examples/basic.rs48
-rw-r--r--structopt/examples/deny_missing_docs.rs51
-rw-r--r--structopt/examples/doc_comments.rs74
-rw-r--r--structopt/examples/enum_in_args.rs25
-rw-r--r--structopt/examples/enum_tuple.rs26
-rw-r--r--structopt/examples/env.rs26
-rw-r--r--structopt/examples/example.rs54
-rw-r--r--structopt/examples/flatten.rs29
-rw-r--r--structopt/examples/gen_completions.rs26
-rw-r--r--structopt/examples/git.rs35
-rw-r--r--structopt/examples/group.rs31
-rw-r--r--structopt/examples/keyvalue.rs36
-rw-r--r--structopt/examples/negative_flag.rs15
-rw-r--r--structopt/examples/no_version.rs17
-rw-r--r--structopt/examples/rename_all.rs74
-rw-r--r--structopt/examples/skip.rs47
-rw-r--r--structopt/examples/subcommand_aliases.rs21
-rw-r--r--structopt/examples/true_or_false.rs41
21 files changed, 792 insertions, 0 deletions
diff --git a/structopt/examples/README.md b/structopt/examples/README.md
new file mode 100644
index 0000000..f0db20b
--- /dev/null
+++ b/structopt/examples/README.md
@@ -0,0 +1,82 @@
+# Collection of examples "how to use `structopt`"
+
+### [Help on the bottom](after_help.rs)
+
+How to append a postscript to the help message generated.
+
+### [At least N](at_least_two.rs)
+
+How to require presence of at least N values, like `val1 val2 ... valN ... valM`.
+
+### [Basic](basic.rs)
+
+A basic example how to use `structopt`.
+
+### [Deny missing docs](deny_missing_docs.rs)
+
+**This is not an example but a test**, it should be moved to `tests` folder
+as soon as [this](https://github.com/rust-lang/rust/issues/24584) is fixed (if ever).
+
+### [Doc comments](doc_comments.rs)
+
+How to use doc comments in place of `help/long_help`.
+
+### [Enums as arguments](enum_in_args.rs)
+
+How to use `arg_enum!` with `StructOpt`.
+
+### [Arguments of subcommands in separate `struct`](enum_tuple.rs)
+
+How to extract subcommands' args into external structs.
+
+### [Environment variables](env.rs)
+
+How to use environment variable fallback an how it interacts with `default_value`.
+
+### [Advanced](example.rs)
+
+Somewhat complex example of usage of `structopt`.
+
+### [Flatten](flatten.rs)
+
+How to use `#[structopt(flatten)]`
+
+### [`bash` completions](gen_completions.rs)
+
+Generating `bash` completions with `structopt`.
+
+### [Git](git.rs)
+
+Pseudo-`git` example, shows how to use subcommands and how to document them.
+
+### [Groups](group.rs)
+
+Using `clap::Arg::group` with `structopt`.
+
+### [`key=value` pairs](keyvalue.rs)
+
+How to parse `key=value` pairs.
+
+### [`--no-*` flags](negative_flag.rs)
+
+How to add `no-thing` flag which is `true` by default and `false` if passed.
+
+### [No version](no_version.rs)
+
+How to completely remove version.
+
+### [Rename all](rename_all.rs)
+
+How `#[structopt(rename_all)]` works.
+
+### [Skip](skip.rs)
+
+How to use `#[structopt(skip)]`.
+
+### [Aliases](subcommand_aliases.rs)
+
+How to use aliases
+
+### [`true` or `false`](true_or_false.rs)
+
+How to express "`"true"` or `"false"` argument.
diff --git a/structopt/examples/after_help.rs b/structopt/examples/after_help.rs
new file mode 100644
index 0000000..db2845f
--- /dev/null
+++ b/structopt/examples/after_help.rs
@@ -0,0 +1,19 @@
+//! How to append a postscript to the help message generated.
+
+use structopt::StructOpt;
+
+/// I am a program and I do things.
+///
+/// Sometimes they even work.
+#[derive(StructOpt, Debug)]
+#[structopt(after_help = "Beware `-d`, dragons be here")]
+struct Opt {
+ /// Release the dragon.
+ #[structopt(short)]
+ dragon: bool,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/at_least_two.rs b/structopt/examples/at_least_two.rs
new file mode 100644
index 0000000..683db50
--- /dev/null
+++ b/structopt/examples/at_least_two.rs
@@ -0,0 +1,15 @@
+//! How to require presence of at least N values,
+//! like `val1 val2 ... valN ... valM`.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+struct Opt {
+ #[structopt(required = true, min_values = 2)]
+ foos: Vec<String>,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/basic.rs b/structopt/examples/basic.rs
new file mode 100644
index 0000000..510e0e0
--- /dev/null
+++ b/structopt/examples/basic.rs
@@ -0,0 +1,48 @@
+//! A somewhat comprehensive example of a typical `StructOpt` usage.use
+
+use std::path::PathBuf;
+use structopt::StructOpt;
+
+/// A basic example
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+ // A flag, true if used in the command line. Note doc comment will
+ // be used for the help message of the flag. The name of the
+ // argument will be, by default, based on the name of the field.
+ /// Activate debug mode
+ #[structopt(short, long)]
+ debug: bool,
+
+ // The number of occurrences of the `v/verbose` flag
+ /// Verbose mode (-v, -vv, -vvv, etc.)
+ #[structopt(short, long, parse(from_occurrences))]
+ verbose: u8,
+
+ /// Set speed
+ #[structopt(short, long, default_value = "42")]
+ speed: f64,
+
+ /// Output file
+ #[structopt(short, long, parse(from_os_str))]
+ output: PathBuf,
+
+ // the long option will be translated by default to kebab case,
+ // i.e. `--nb-cars`.
+ /// Number of cars
+ #[structopt(short = "c", long)]
+ nb_cars: Option<i32>,
+
+ /// admin_level to consider
+ #[structopt(short, long)]
+ level: Vec<String>,
+
+ /// Files to process
+ #[structopt(name = "FILE", parse(from_os_str))]
+ files: Vec<PathBuf>,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:#?}", opt);
+}
diff --git a/structopt/examples/deny_missing_docs.rs b/structopt/examples/deny_missing_docs.rs
new file mode 100644
index 0000000..82b1e63
--- /dev/null
+++ b/structopt/examples/deny_missing_docs.rs
@@ -0,0 +1,51 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This should be in tests but it will not work until
+// https://github.com/rust-lang/rust/issues/24584 is fixed
+
+//! A test to check that structopt compiles with deny(missing_docs)
+
+#![deny(missing_docs)]
+
+use structopt::StructOpt;
+
+/// The options
+#[derive(StructOpt, Debug, PartialEq)]
+pub struct Opt {
+ #[structopt(short)]
+ verbose: bool,
+ #[structopt(subcommand)]
+ cmd: Option<Cmd>,
+}
+
+/// Some subcommands
+#[derive(StructOpt, Debug, PartialEq)]
+pub enum Cmd {
+ /// command A
+ A,
+ /// command B
+ B {
+ /// Alice?
+ #[structopt(short)]
+ alice: bool,
+ },
+ /// command C
+ C(COpt),
+}
+
+/// The options for C
+#[derive(StructOpt, Debug, PartialEq)]
+pub struct COpt {
+ #[structopt(short)]
+ bob: bool,
+}
+
+fn main() {
+ println!("{:?}", Opt::from_args());
+}
diff --git a/structopt/examples/doc_comments.rs b/structopt/examples/doc_comments.rs
new file mode 100644
index 0000000..810101f
--- /dev/null
+++ b/structopt/examples/doc_comments.rs
@@ -0,0 +1,74 @@
+//! How to use doc comments in place of `help/long_help`.
+
+use structopt::StructOpt;
+
+/// A basic example for the usage of doc comments as replacement
+/// of the arguments `help`, `long_help`, `about` and `long_about`.
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+ /// Just use doc comments to replace `help`, `long_help`,
+ /// `about` or `long_about` input.
+ #[structopt(short, long)]
+ first_flag: bool,
+
+ /// Split between `help` and `long_help`.
+ ///
+ /// In the previous case structopt is going to present
+ /// the whole comment both as text for the `help` and the
+ /// `long_help` argument.
+ ///
+ /// But if the doc comment is formatted like this example
+ /// -- with an empty second line splitting the heading and
+ /// the rest of the comment -- only the first line is used
+ /// as `help` argument. The `long_help` argument will still
+ /// contain the whole comment.
+ ///
+ /// ## Attention
+ ///
+ /// Any formatting next to empty lines that could be used
+ /// inside a doc comment is currently not preserved. If
+ /// lists or other well formatted content is required it is
+ /// necessary to use the related structopt argument with a
+ /// raw string as shown on the `third_flag` description.
+ #[structopt(short, long)]
+ second_flag: bool,
+
+ #[structopt(
+ short,
+ long,
+ long_help = r"This is a raw string.
+
+It can be used to pass well formatted content (e.g. lists or source
+code) in the description:
+
+ - first example list entry
+ - second example list entry
+ "
+ )]
+ third_flag: bool,
+
+ #[structopt(subcommand)]
+ sub_command: SubCommand,
+}
+
+#[derive(StructOpt, Debug)]
+#[structopt()]
+enum SubCommand {
+ /// The same rules described previously for flags. Are
+ /// also true for in regards of sub-commands.
+ First,
+
+ /// Applicable for both `about` an `help`.
+ ///
+ /// The formatting rules described in the comment of the
+ /// `second_flag` also apply to the description of
+ /// sub-commands which is normally given through the `about`
+ /// and `long_about` arguments.
+ Second,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/enum_in_args.rs b/structopt/examples/enum_in_args.rs
new file mode 100644
index 0000000..70347da
--- /dev/null
+++ b/structopt/examples/enum_in_args.rs
@@ -0,0 +1,25 @@
+//! How to use `arg_enum!` with `StructOpt`.
+
+use clap::arg_enum;
+use structopt::StructOpt;
+
+arg_enum! {
+ #[derive(Debug)]
+ enum Baz {
+ Foo,
+ Bar,
+ FooBar
+ }
+}
+
+#[derive(StructOpt, Debug)]
+struct Opt {
+ /// Important argument.
+ #[structopt(possible_values = &Baz::variants(), case_insensitive = true)]
+ i: Baz,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/enum_tuple.rs b/structopt/examples/enum_tuple.rs
new file mode 100644
index 0000000..0bad2e6
--- /dev/null
+++ b/structopt/examples/enum_tuple.rs
@@ -0,0 +1,26 @@
+//! How to extract subcommands' args into external structs.
+
+use structopt::StructOpt;
+
+#[derive(Debug, StructOpt)]
+pub struct Foo {
+ pub bar: Option<String>,
+}
+
+#[derive(Debug, StructOpt)]
+pub enum Command {
+ #[structopt(name = "foo")]
+ Foo(Foo),
+}
+
+#[derive(Debug, StructOpt)]
+#[structopt(name = "classify")]
+pub struct ApplicationArguments {
+ #[structopt(subcommand)]
+ pub command: Command,
+}
+
+fn main() {
+ let opt = ApplicationArguments::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/env.rs b/structopt/examples/env.rs
new file mode 100644
index 0000000..0477089
--- /dev/null
+++ b/structopt/examples/env.rs
@@ -0,0 +1,26 @@
+//! How to use environment variable fallback an how it
+//! interacts with `default_value`.
+
+use structopt::StructOpt;
+
+/// Example for allowing to specify options via environment variables.
+#[derive(StructOpt, Debug)]
+#[structopt(name = "env")]
+struct Opt {
+ // Use `env` to enable specifying the option with an environment
+ // variable. Command line arguments take precedence over env.
+ /// URL for the API server
+ #[structopt(long, env = "API_URL")]
+ api_url: String,
+
+ // The default value is used if neither argument nor environment
+ // variable is specified.
+ /// Number of retries
+ #[structopt(long, env = "RETRIES", default_value = "5")]
+ retries: u32,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:#?}", opt);
+}
diff --git a/structopt/examples/example.rs b/structopt/examples/example.rs
new file mode 100644
index 0000000..7a9a514
--- /dev/null
+++ b/structopt/examples/example.rs
@@ -0,0 +1,54 @@
+//! Somewhat complex example of usage of structopt.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "example")]
+/// An example of StructOpt usage.
+struct Opt {
+ // A flag, true if used in the command line.
+ #[structopt(short, long)]
+ /// Activate debug mode
+ debug: bool,
+
+ // An argument of type float, with a default value.
+ #[structopt(short, long, default_value = "42")]
+ /// Set speed
+ speed: f64,
+
+ // Needed parameter, the first on the command line.
+ /// Input file
+ input: String,
+
+ // An optional parameter, will be `None` if not present on the
+ // command line.
+ /// Output file, stdout if not present
+ output: Option<String>,
+
+ // An optional parameter with optional value, will be `None` if
+ // not present on the command line, will be `Some(None)` if no
+ // argument is provided (i.e. `--log`) and will be
+ // `Some(Some(String))` if argument is provided (e.g. `--log
+ // log.txt`).
+ #[structopt(long)]
+ #[allow(clippy::option_option)]
+ /// Log file, stdout if no file, no logging if not present
+ log: Option<Option<String>>,
+
+ // An optional list of values, will be `None` if not present on
+ // the command line, will be `Some(vec![])` if no argument is
+ // provided (i.e. `--optv`) and will be `Some(Some(String))` if
+ // argument list is provided (e.g. `--optv a b c`).
+ #[structopt(long)]
+ optv: Option<Vec<String>>,
+
+ // Skipped option: it won't be parsed and will be filled with the
+ // default value for its type (in this case it'll be an empty string).
+ #[structopt(skip)]
+ skipped: String,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/flatten.rs b/structopt/examples/flatten.rs
new file mode 100644
index 0000000..d51647f
--- /dev/null
+++ b/structopt/examples/flatten.rs
@@ -0,0 +1,29 @@
+//! How to use flattening.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+struct Cmdline {
+ /// switch verbosity on
+ #[structopt(short)]
+ verbose: bool,
+
+ #[structopt(flatten)]
+ daemon_opts: DaemonOpts,
+}
+
+#[derive(StructOpt, Debug)]
+struct DaemonOpts {
+ /// daemon user
+ #[structopt(short)]
+ user: String,
+
+ /// daemon group
+ #[structopt(short)]
+ group: String,
+}
+
+fn main() {
+ let opt = Cmdline::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/gen_completions.rs b/structopt/examples/gen_completions.rs
new file mode 100644
index 0000000..4f35b07
--- /dev/null
+++ b/structopt/examples/gen_completions.rs
@@ -0,0 +1,26 @@
+// Copyright 2019-present structopt developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use structopt::clap::Shell;
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+/// An example of how to generate bash completions with structopt.
+struct Opt {
+ #[structopt(short, long)]
+ /// Activate debug mode
+ debug: bool,
+}
+
+fn main() {
+ // generate `bash` completions in "target" directory
+ Opt::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Bash, "target");
+
+ let opt = Opt::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/git.rs b/structopt/examples/git.rs
new file mode 100644
index 0000000..494e9d1
--- /dev/null
+++ b/structopt/examples/git.rs
@@ -0,0 +1,35 @@
+//! `git.rs` serves as a demonstration of how to use subcommands,
+//! as well as a demonstration of adding documentation to subcommands.
+//! Documentation can be added either through doc comments or
+//! `help`/`about` attributes.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "git")]
+/// the stupid content tracker
+enum Opt {
+ /// fetch branches from remote repository
+ Fetch {
+ #[structopt(long)]
+ dry_run: bool,
+ #[structopt(long)]
+ all: bool,
+ #[structopt(default_value = "origin")]
+ repository: String,
+ },
+ #[structopt(help = "add files to the staging area")]
+ Add {
+ #[structopt(short)]
+ interactive: bool,
+ #[structopt(short)]
+ all: bool,
+ files: Vec<String>,
+ },
+}
+
+fn main() {
+ let matches = Opt::from_args();
+
+ println!("{:?}", matches);
+}
diff --git a/structopt/examples/group.rs b/structopt/examples/group.rs
new file mode 100644
index 0000000..d53de6a
--- /dev/null
+++ b/structopt/examples/group.rs
@@ -0,0 +1,31 @@
+//! How to use `clap::Arg::group`
+
+use structopt::{clap::ArgGroup, StructOpt};
+
+#[derive(StructOpt, Debug)]
+#[structopt(group = ArgGroup::with_name("verb").required(true))]
+struct Opt {
+ /// Set a custom HTTP verb
+ #[structopt(long, group = "verb")]
+ method: Option<String>,
+ /// HTTP GET
+ #[structopt(long, group = "verb")]
+ get: bool,
+ /// HTTP HEAD
+ #[structopt(long, group = "verb")]
+ head: bool,
+ /// HTTP POST
+ #[structopt(long, group = "verb")]
+ post: bool,
+ /// HTTP PUT
+ #[structopt(long, group = "verb")]
+ put: bool,
+ /// HTTP DELETE
+ #[structopt(long, group = "verb")]
+ delete: bool,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/keyvalue.rs b/structopt/examples/keyvalue.rs
new file mode 100644
index 0000000..12ce6fc
--- /dev/null
+++ b/structopt/examples/keyvalue.rs
@@ -0,0 +1,36 @@
+//! How to parse "key=value" pairs with structopt.
+
+use std::error::Error;
+use structopt::StructOpt;
+
+/// Parse a single key-value pair
+fn parse_key_val<T, U>(s: &str) -> Result<(T, U), Box<dyn Error>>
+where
+ T: std::str::FromStr,
+ T::Err: Error + 'static,
+ U: std::str::FromStr,
+ U::Err: Error + 'static,
+{
+ let pos = s
+ .find('=')
+ .ok_or_else(|| format!("invalid KEY=value: no `=` found in `{}`", s))?;
+ Ok((s[..pos].parse()?, s[pos + 1..].parse()?))
+}
+
+#[derive(StructOpt, Debug)]
+struct Opt {
+ // number_of_values = 1 forces the user to repeat the -D option for each key-value pair:
+ // my_program -D a=1 -D b=2
+ // Without number_of_values = 1 you can do:
+ // my_program -D a=1 b=2
+ // but this makes adding an argument after the values impossible:
+ // my_program -D a=1 -D b=2 my_input_file
+ // becomes invalid.
+ #[structopt(short = "D", parse(try_from_str = parse_key_val), number_of_values = 1)]
+ defines: Vec<(String, i32)>,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/negative_flag.rs b/structopt/examples/negative_flag.rs
new file mode 100644
index 0000000..b178bf5
--- /dev/null
+++ b/structopt/examples/negative_flag.rs
@@ -0,0 +1,15 @@
+//! How to add `no-thing` flag which is `true` by default and
+//! `false` if passed.
+
+use structopt::StructOpt;
+
+#[derive(Debug, StructOpt)]
+struct Opt {
+ #[structopt(long = "no-verbose", parse(from_flag = std::ops::Not::not))]
+ verbose: bool,
+}
+
+fn main() {
+ let cmd = Opt::from_args();
+ println!("{:#?}", cmd);
+}
diff --git a/structopt/examples/no_version.rs b/structopt/examples/no_version.rs
new file mode 100644
index 0000000..a542ec1
--- /dev/null
+++ b/structopt/examples/no_version.rs
@@ -0,0 +1,17 @@
+//! How to completely remove version.
+
+use structopt::clap::AppSettings;
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(
+ name = "no_version",
+ no_version,
+ global_settings = &[AppSettings::DisableVersion]
+)]
+struct Opt {}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/rename_all.rs b/structopt/examples/rename_all.rs
new file mode 100644
index 0000000..35f3c4f
--- /dev/null
+++ b/structopt/examples/rename_all.rs
@@ -0,0 +1,74 @@
+//! Example on how the `rename_all` parameter works.
+//!
+//! `rename_all` can be used to override the casing style used during argument
+//! generation. By default the `kebab-case` style will be used but there are a wide
+//! variety of other styles available.
+//!
+//! ## Supported styles overview:
+//!
+//! - **Camel Case**: Indicate word boundaries with uppercase letter, excluding
+//! the first word.
+//! - **Kebab Case**: Keep all letters lowercase and indicate word boundaries
+//! with hyphens.
+//! - **Pascal Case**: Indicate word boundaries with uppercase letter,
+//! including the first word.
+//! - **Screaming Snake Case**: Keep all letters uppercase and indicate word
+//! boundaries with underscores.
+//! - **Snake Case**: Keep all letters lowercase and indicate word boundaries
+//! with underscores.
+//! - **Verbatim**: Use the original attribute name defined in the code.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "rename_all", rename_all = "screaming_snake_case")]
+enum Opt {
+ // This subcommand will be named `FIRST_COMMAND`. As the command doesn't
+ // override the initial casing style, ...
+ /// A screaming loud first command. Only use if necessary.
+ FirstCommand {
+ // this flag will be available as `--FOO` and `-F`.
+ /// This flag will even scream louder.
+ #[structopt(long, short)]
+ foo: bool,
+ },
+
+ // As we override the casing style for this variant the related subcommand
+ // will be named `SecondCommand`.
+ /// Not nearly as loud as the first command.
+ #[structopt(rename_all = "pascal_case")]
+ SecondCommand {
+ // We can also override it again on a single field.
+ /// Nice quiet flag. No one is annoyed.
+ #[structopt(rename_all = "snake_case", long)]
+ bar_option: bool,
+
+ // Renaming will not be propagated into subcommand flagged enums. If
+ // a non default casing style is required it must be defined on the
+ // enum itself.
+ #[structopt(subcommand)]
+ cmds: Subcommands,
+
+ // or flattened structs.
+ #[structopt(flatten)]
+ options: BonusOptions,
+ },
+}
+
+#[derive(StructOpt, Debug)]
+enum Subcommands {
+ // This one will be available as `first-subcommand`.
+ FirstSubcommand,
+}
+
+#[derive(StructOpt, Debug)]
+struct BonusOptions {
+ // And this one will be available as `baz-option`.
+ #[structopt(long)]
+ baz_option: bool,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/skip.rs b/structopt/examples/skip.rs
new file mode 100644
index 0000000..1f44769
--- /dev/null
+++ b/structopt/examples/skip.rs
@@ -0,0 +1,47 @@
+//! How to use `#[structopt(skip)]`
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug, PartialEq)]
+pub struct Opt {
+ #[structopt(long, short)]
+ number: u32,
+ #[structopt(skip)]
+ k: Kind,
+ #[structopt(skip)]
+ v: Vec<u32>,
+
+ #[structopt(skip = Kind::A)]
+ k2: Kind,
+ #[structopt(skip = vec![1, 2, 3])]
+ v2: Vec<u32>,
+ #[structopt(skip = "cake")] // &str implements Into<String>
+ s: String,
+}
+
+#[derive(Debug, PartialEq)]
+enum Kind {
+ A,
+ B,
+}
+
+impl Default for Kind {
+ fn default() -> Self {
+ return Kind::B;
+ }
+}
+
+fn main() {
+ assert_eq!(
+ Opt::from_iter(&["test", "-n", "10"]),
+ Opt {
+ number: 10,
+ k: Kind::B,
+ v: vec![],
+
+ k2: Kind::A,
+ v2: vec![1, 2, 3],
+ s: String::from("cake")
+ }
+ );
+}
diff --git a/structopt/examples/subcommand_aliases.rs b/structopt/examples/subcommand_aliases.rs
new file mode 100644
index 0000000..30b8cc3
--- /dev/null
+++ b/structopt/examples/subcommand_aliases.rs
@@ -0,0 +1,21 @@
+//! How to assign some aliases to subcommands
+
+use structopt::clap::AppSettings;
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+// https://docs.rs/clap/2/clap/enum.AppSettings.html#variant.InferSubcommands
+#[structopt(setting = AppSettings::InferSubcommands)]
+enum Opt {
+ // https://docs.rs/clap/2/clap/struct.App.html#method.alias
+ #[structopt(alias = "foobar")]
+ Foo,
+ // https://docs.rs/clap/2/clap/struct.App.html#method.aliases
+ #[structopt(aliases = &["baz", "fizz"])]
+ Bar,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ println!("{:?}", opt);
+}
diff --git a/structopt/examples/true_or_false.rs b/structopt/examples/true_or_false.rs
new file mode 100644
index 0000000..31a543e
--- /dev/null
+++ b/structopt/examples/true_or_false.rs
@@ -0,0 +1,41 @@
+//! How to parse `--foo=true --bar=false` and turn them into bool.
+
+use structopt::StructOpt;
+
+fn true_or_false(s: &str) -> Result<bool, &'static str> {
+ match s {
+ "true" => Ok(true),
+ "false" => Ok(false),
+ _ => Err("expected `true` or `false`"),
+ }
+}
+
+#[derive(StructOpt, Debug, PartialEq)]
+struct Opt {
+ // Default parser for `try_from_str` is FromStr::from_str.
+ // `impl FromStr for bool` parses `true` or `false` so this
+ // works as expected.
+ #[structopt(long, parse(try_from_str))]
+ foo: bool,
+
+ // Of course, this could be done with an explicit parser function.
+ #[structopt(long, parse(try_from_str = true_or_false))]
+ bar: bool,
+
+ // `bool` can be positional only with explicit `parse(...)` annotation
+ #[structopt(long, parse(try_from_str))]
+ boom: bool,
+}
+
+fn main() {
+ assert_eq!(
+ Opt::from_iter(&["test", "--foo=true", "--bar=false", "true"]),
+ Opt {
+ foo: true,
+ bar: false,
+ boom: true
+ }
+ );
+ // no beauty, only truth and falseness
+ assert!(Opt::from_iter_safe(&["test", "--foo=beauty"]).is_err());
+}