Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 42 additions & 0 deletions conformance/tests/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,3 +480,45 @@ fn reaching_the_tables_is_free() {
"the tables should be one static, not a build"
);
}

/// The crate-level example from usage-derive's documentation, kept here because
/// that crate cannot dev-depend on usage-argv without making itself unpublishable
/// — see the note in `derive/Cargo.toml`. If this changes, change the docs too.
mod docs_example {
use super::argv;
use usage_derive::Cli;

/// A tool that does things
#[derive(Cli)]
#[usage(bin = "ex", version = "1.0")]
struct Cli {
/// How many jobs to run at once
#[usage(short = 'j', long, env = "EX_JOBS", default = "4")]
jobs: Option<String>,

/// Print more
#[usage(short = 'v', long, count)]
verbose: u8,

/// Colorize output
#[usage(long, negate = "--no-color", default = "true")]
color: bool,

/// Files to process
files: Vec<String>,
}

#[test]
fn the_crate_level_example_from_the_docs() {
let a = argv(["-j8", "--no-color", "a.txt"]);
let cli = Cli::parse_from(&a).unwrap();
assert_eq!(cli.jobs.as_deref(), Some("8"));
assert!(!cli.color);
assert_eq!(cli.files, ["a.txt"]);
assert_eq!(cli.verbose, 0);

// The same declaration is also the spec, which is what generates docs,
// manpages, and completions.
assert!(Cli::to_kdl().contains(r#"flag "-j --jobs""#));
}
}
12 changes: 8 additions & 4 deletions derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ quote = "1"
# needs the newer API, and matching what is there avoids a second copy.
syn = { version = "3", features = ["full"] }

# The generated code refers to usage-argv, so the doc examples need it in scope to
# compile. Not a real dependency: this crate emits tokens and links nothing.
[dev-dependencies]
usage-argv = { workspace = true, features = ["spec"] }
# No dependency on usage-argv, not even for tests. This crate emits tokens and
# links nothing, and dev-depending on the runtime it emits code for creates a cycle
# at publish time: `cargo publish` resolves dev-dependencies against the registry,
# so a feature added to usage-argv within a version makes this crate unpublishable
# until the version bumps. serde_derive avoids the same trap the same way.
#
# The crate-level example is therefore `ignore`d here and compiled for real in
# conformance/tests/derive.rs, which is where the derive is tested anyway.
6 changes: 5 additions & 1 deletion derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
//! to build before a parse can start — and a successful parse touches only the
//! first of the three.
//!
//! ```
//! Not compiled here, because this crate deliberately does not depend on
//! usage-argv — see the note in its `Cargo.toml`. The same example runs as a test
//! in `conformance/tests/derive.rs`, as `the_crate_level_example_from_the_docs`.
//!
//! ```ignore
//! # use usage_derive::Cli;
//! /// A tool that does things
//! #[derive(Cli)]
Expand Down