macro_rules!
macro.macro_rules!
macro.StructOpt::from_iter_safe(std::env::args_os())
.cargo geiger
list structopt as “safe”. Maybe it will help somebody trying to locate a bug in their dependency tree.quote_spanned
misuse.#[structopt(flatten)]
fields to have doc comments. The comments are ignored.paw
crate is now being reexported when paw
feature is enabled, see #407
.proc-macro-error
to 1.0
.external_subcommand
.syn
‘s “full” feature is now explicitly enabled. It must have been, but hasn’t.syn
feature was not enabled.clippy
warnings triggered by generated code shall not annoy you anymore! Except for those from clippy::correctness
, these lints are useful even for auto generated code.#[no_version]
to every enum
variant anymore. Just annotate the enum
and the setting will be propagated down (#242).Nothing's new. Just re-release of v0.3.6
due to the mess with versioning.
You may notice that structopt-derive
was bumped to v0.4.0
, that‘s OK, it’s not a breaking change. structopt
will pull the right version in on its on.
This is unusually big patch release. It contains a number of bugfixes and new features, some of them may theoretically be considered breaking. We did our best to avoid any problems on user‘s side but, if it wasn’t good enough, please file an issue ASAP.
structopt
used to treat ::path::to::type::Vec<T>
as Vec<T>
special type. This was considered erroneous. (same for Option<T>
and bool
). Now only exact Vec<T>
match is a special type.
#[structopt(version = expr)]
where expr
is not a string literal used to get overridden by auto generated .version()
call, incorrectly. Now it doesn't.
Fixed bug with top-level App::*
calls on multiple struct
s, see #289.
Positional bool
args with no explicit #[structopt(parse(...))]
annotation are now prohibited. This couldn't work well anyway, see this example for details.
Now we've instituted strict priority between doc comments, about, help, and the like. See the documentation.
HUGE THANKS to @ssokolow
for tidying up our documentation, teaching me English and explaining why our doc used to suck. I promise I'll make the rest of the doc up to your standards... sometime later!
Implement StructOpt
for Box<impl StructOpt>
so from now on you can use Box<T>
with flatten
and subcommand
(#304).
enum Command { #[structopt(name = "version")] PrintVersion, #[structopt(name = "second")] DoSomething { #[structopt(flatten)] config: Box<DoSomethingConfig>, }, #[structopt(name = "first")] DoSomethingElse { #[structopt(flatten)] config: Box<DoSomethingElseConfig>, } }
Introduced #[structopt(verbatim_doc_comment)]
attribute that keeps line breaks in doc comments, see the documentation.
Introduced #[structopt(rename_all_env)]
and #[structopt(env)]
magical methods so you can derive env var‘s name from field’s name. See the documentation.
Now we have nice README for our examples, check it out!
Some error messages were improved and clarified, thanks for all people involved!
try_from_str
functions are now called with a &str
instead of a &String
(#282)rename_all
does not apply to fields that were annotated with explicit short/long/name = "..."
anymore (#265)from_flag
custom parser to create flags from non-bool types. Fixes #185structopt
does not replace :
with ,
inside “author” strings while inside <...>
. Fixes #156#[structopt(skip = expr)]
syntax.skip
plus long doc comment” bug (#245)structopt
emits dummy StructOpt
implementation along with an error. It suppresses meaningless errors like from_args method is not found for Opt
.version()
not get generated if CARGO_PKG_VERSION
is not set anymore.Now rustc
1.36 is the minimum compiler version supported by structopt
, it likely won't work with older compilers.
Once upon a time this feature had been used to enable some of improvements in proc-macro2
crate that were available only on nightly. Nowadays this feature doesn‘t mean anything so it’s now removed.
-o 1 2
, -o
and no option provided at all by @sphynx (#180).#[derive(StructOpt)] struct Opt { #[structopt(long)] fruit: Option<Vec<String>>, } fn main() { assert_eq!(Opt::from_args(&["test"]), None); assert_eq!(Opt::from_args(&["test", "--fruit"]), Some(vec![])); assert_eq!(Opt::from_args(&["test", "--fruit=apple orange"]), Some(vec!["apple", "orange"])); }
If you need to fall back to the old behavior you can use a type alias:
type Something = Vec<String>; #[derive(StructOpt)] struct Opt { #[structopt(long)] fruit: Option<Something>, }
structopt
0.3 uses field renaming to deduce a name for long options and subcommands.
#[derive(StructOpt)] struct Opt { #[structopt(long)] http_addr: String, // will be renamed to `--http-addr` #[structopt(subcommand)] addr_type: AddrType // this adds `addr-type` subcommand }
structopt
0.2 used to leave things “as is”, not renaming anything. If you want to keep old behavior add #[structopt(rename_all = "verbatim")]
on top of a struct
/enum
.
version
, author
and about
attributes behavior.Proposed by @TeXitoi (#217), implemented by @CreepySkeleton (#229).
structopt
have been deducing version
, author
, and about
properties from Cargo.toml
for a long time (more accurately, from CARGO_PKG_...
environment variables). But many users found this behavior somewhat confusing, and a hack was added to cancel out this behavior: #[structopt(author = "")]
.
In structopt
0.3 this has changed.
author
and about
are no longer deduced by default. You should use #[structopt(author, about)]
to explicitly request structopt
to deduce them.version
is still deduced by default. You can use #[structopt(no_version)]
to cancel it out.#[structopt(author = "", about = "", version = "")]
is no longer a valid syntax and will trigger an error.#[structopt(version = "version", author = "author", about = "about")]
syntax stays unaffected by this changes.In structopt
0.2 you were able to use any method from clap::App
and clap::Arg
via raw attribute: #[structopt(raw(method_name = "arg"))]
. This syntax was kind of awkward.
#[derive(StructOpt, Debug)] #[structopt(raw( global_settings = "&[AppSettings::ColoredHelp, AppSettings::VersionlessSubcommands]" ))] struct Opt { #[structopt(short = "l", long = "level", raw(aliases = r#"&["set-level", "lvl"]"#))] level: Vec<String>, }
Raw attributes were removed in 0.3. Now you can use any method from App
and Arg
directly:
#[derive(StructOpt)] #[structopt(global_settings(&[AppSettings::ColoredHelp, AppSettings::VersionlessSubcommands]))] struct Opt { #[structopt(short = "l", long = "level", aliases(&["set-level", "lvl"]))] level: Vec<String>, }
Proposed by @Morganamilo in (#174) implemented by @sphynx in (#213).
Sometimes you want to include some fields in your StructOpt
struct
that are not options and clap
should know nothing about them. In structopt
0.3 it's possible via the #[structopt(skip)]
attribute. The field in question will be assigned with Default::default()
value.
#[derive(StructOpt)] struct Opt { #[structopt(short, long)] speed: f32, car: String, // this field should not generate any arguments #[structopt(skip)] meta: Vec<u64> }
paw
by @gameldar (#187)Now (almost) every error message points to the location it originates from:
error: default_value is meaningless for bool --> $DIR/bool_default_value.rs:14:24 | 14 | #[structopt(short, default_value = true)] | ^^^^^^^^^^^^^
cmd [--opt[=value]]
by @sphynx (#188)Sometimes you want to represent an optional option that optionally takes an argument, i.e [--opt[=value]]
. This is represented by Option<Option<T>>
#[derive(StructOpt)] struct Opt { #[structopt(long)] fruit: Option<Option<String>>, } fn main() { assert_eq!(Opt::from_args(&["test"]), None); assert_eq!(Opt::from_args(&["test", "--fruit"]), Some(None)); assert_eq!(Opt::from_args(&["test", "--fruit=apple"]), Some("apple")); }
flatten
by @fbenksteinStructOpt::from_iter_safe()
, which returns an Error
instead of killing the program when it fails to parse, or parses one of the short-circuiting flags. (#98 by @quodlibetor)clap
features independently by @Kerollmopsdefault_value
or required
with Option
(#88) by @Kerollmopsdefault_value
or required
with bool
(#80) by @TeXitoi#[deny(warnings)]
with the !
type (https://github.com/rust-lang/rust/pull/49039#issuecomment-376398999) by @TeXitoiproc-macro2
's nightly feature is enabled. (#77 and proc-macro2#67) by @fitzgen#![deny(missig_docs]
(#74) by @TeXitoiu64
by @SergioBenitezIf you are using a u64
in your struct to get the number of occurence of a flag, you should now add parse(from_occurrences)
on the flag.
For example
#[structopt(short = "v", long = "verbose")] verbose: u64,
must be changed by
#[structopt(short = "v", long = "verbose", parse(from_occurrences))] verbose: u64,
This feature was surprising as shown in #30. Using the parse
feature seems much more natural.
Structopt::from_clap
to take its argument by reference by @TeXitoiThere was no reason to take the argument by value. Most of the StructOpt users will not be impacted by this change. If you are using StructOpt::from_clap
, just add a &
before the argument.
StructOpt was quite fuzzy in its attribute parsing: it was only searching for interresting things, e. g. something like #[structopt(foo(bar))]
was accepted but not used. It now fails the compilation.
You should have nothing to do here. This breaking change may highlight some missuse that can be bugs.
In future versions, if there is cases that are not highlighed, they will be considerated as bugs, not breaking changes.
raw()
wrapping instead of _raw
suffixing by @TeXitoiThe syntax of raw attributes is changed to improve the syntax.
You have to change foo_raw = "bar", baz_raw = "foo"
by raw(foo = "bar", baz = "foo")
or raw(foo = "bar"), raw(baz = "foo")
.
parse(from_occurrences)
parser by @SergioBenitezStructOpt::from_iter
method by @Kerollmops&str
or &OsStr
by @kennytm_raw
suffix by @Flakebi