Bug 1915426 - Update clap/heck/darling/anstyle/strsim, r=glandium,supply-chain-reviewers

Updated:
  - heck 0.4.1 -> 0.5.0
  - clap 4.4.5 -> 4.5.16
  - darling v0.20.1 -> v0.20.10
  - strsim 0.10.0 -> 0.11.1
  - anstyle 1.0.3 -> 1.0.8

This is in preparation of the UniFFI 0.28 upgrade:
https://bugzilla.mozilla.org/show_bug.cgi?id=1914241

Differential Revision: https://phabricator.services.mozilla.com/D220437
This commit is contained in:
Ben Dean-Kawamura 2024-09-09 15:42:31 +00:00
Родитель 19b97ca2a6
Коммит e2f0822153
235 изменённых файлов: 5646 добавлений и 2563 удалений

53
Cargo.lock сгенерированный
Просмотреть файл

@ -88,9 +88,9 @@ dependencies = [
[[package]]
name = "anstyle"
version = "1.0.3"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46"
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "any_all_workaround"
@ -790,9 +790,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.4.5"
version = "4.5.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824956d0dca8334758a5b7f7e50518d66ea319330cbceedcf76905c2f6ab30e3"
checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019"
dependencies = [
"clap_builder",
"clap_derive",
@ -810,9 +810,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.4.5"
version = "4.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "122ec64120a49b4563ccaedcbea7818d069ed8e9aa6d829b82d8a4128936b2ab"
checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6"
dependencies = [
"anstyle",
"clap_lex",
@ -822,11 +822,11 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.4.2"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [
"heck",
"heck 0.5.0",
"proc-macro2",
"quote",
"syn",
@ -834,9 +834,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.5.1"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "cmake"
@ -1263,9 +1263,9 @@ dependencies = [
[[package]]
name = "darling"
version = "0.20.1"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944"
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
dependencies = [
"darling_core",
"darling_macro",
@ -1273,9 +1273,9 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.20.1"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb"
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
dependencies = [
"fnv",
"ident_case",
@ -1287,9 +1287,9 @@ dependencies = [
[[package]]
name = "darling_macro"
version = "0.20.1"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core",
"quote",
@ -2666,9 +2666,16 @@ dependencies = [
[[package]]
name = "heck"
version = "0.4.1"
version = "0.4.999"
dependencies = [
"heck 0.5.0",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
@ -5588,9 +5595,9 @@ dependencies = [
[[package]]
name = "strsim"
version = "0.10.0"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "style"
@ -6227,7 +6234,7 @@ dependencies = [
"camino",
"clap",
"extend",
"heck",
"heck 0.4.999",
"serde",
"toml",
"uniffi",
@ -6320,7 +6327,7 @@ dependencies = [
"fs-err",
"glob",
"goblin 0.8.1",
"heck",
"heck 0.4.999",
"once_cell",
"paste",
"serde",

Просмотреть файл

@ -172,6 +172,9 @@ hashbrown = { path = "build/rust/hashbrown" }
# Patch `socket2` 0.4 to 0.5
socket2 = { path = "build/rust/socket2" }
# Patch heck 0.4 to 0.5
heck = { path = "build/rust/heck" }
# The following overrides point to dummy projects, as a temporary measure until this is resolved:
# https://github.com/rust-lang/cargo/issues/6179
js-sys = { path = "build/rust/dummy-web/js-sys" }

Просмотреть файл

@ -0,0 +1,11 @@
[package]
name = "heck"
version = "0.4.999"
edition = "2018"
license = "MPL-2.0"
[lib]
path = "lib.rs"
[dependencies.heck]
version = "0.5.0"

5
build/rust/heck/lib.rs Normal file
Просмотреть файл

@ -0,0 +1,5 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
pub use heck::*;

Просмотреть файл

@ -56,7 +56,7 @@ serde = { version = "1", features = ["alloc", "derive", "rc"] }
serde_json = { version = "1", features = ["preserve_order", "unbounded_depth"], optional = true }
smallvec = { version = "1", features = ["const_new", "serde", "union"], optional = true }
stable_deref_trait = { version = "1", features = ["std"], optional = true }
strsim = { version = "0.10", optional = true }
strsim = { version = "0.11", optional = true }
time = { version = "0.3", features = ["macros", "parsing", "serde"], optional = true }
tinystr = { version = "0.7", features = ["zerovec"], optional = true }
tokio = { version = "1", features = ["fs", "macros", "rt-multi-thread"], optional = true }

Просмотреть файл

@ -1512,6 +1512,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.14.3 -> 0.20.1"
[[audits.darling]]
who = "Ben Dean-Kawamura <bdk@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.20.1 -> 0.20.10"
[[audits.darling_core]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -1527,6 +1532,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.14.3 -> 0.20.1"
[[audits.darling_core]]
who = "Ben Dean-Kawamura <bdk@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.20.1 -> 0.20.10"
[[audits.darling_macro]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -1542,6 +1552,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.14.3 -> 0.20.1"
[[audits.darling_macro]]
who = "Ben Dean-Kawamura <bdk@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.20.1 -> 0.20.10"
[[audits.data-encoding]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -4217,6 +4232,11 @@ criteria = "safe-to-deploy"
version = "0.1.2"
notes = "This crate doesn't use unsafe block, network access and filesystem access."
[[audits.strsim]]
who = "Ben Dean-Kawamura <bdk@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.10.0 -> 0.11.1"
[[audits.subtle]]
who = "Simon Friedberger <simon@mozilla.com>"
criteria = "safe-to-deploy"
@ -5504,7 +5524,7 @@ end = "2025-02-26"
criteria = "safe-to-deploy"
user-id = 6743 # Ed Page (epage)
start = "2021-12-08"
end = "2024-06-02"
end = "2025-08-21"
[[trusted.clap_builder]]
criteria = "safe-to-deploy"
@ -5516,13 +5536,13 @@ end = "2024-06-02"
criteria = "safe-to-deploy"
user-id = 6743 # Ed Page (epage)
start = "2021-12-08"
end = "2024-06-02"
end = "2025-08-21"
[[trusted.clap_lex]]
criteria = "safe-to-deploy"
user-id = 6743 # Ed Page (epage)
start = "2022-04-15"
end = "2024-06-02"
end = "2025-08-21"
[[trusted.dtoa]]
criteria = "safe-to-deploy"

Просмотреть файл

@ -15,6 +15,13 @@ user-id = 6743
user-login = "epage"
user-name = "Ed Page"
[[publisher.anstyle]]
version = "1.0.8"
when = "2024-07-25"
user-id = 6743
user-login = "epage"
user-name = "Ed Page"
[[publisher.arbitrary]]
version = "1.3.2"
when = "2023-10-30"
@ -99,6 +106,13 @@ user-id = 6743
user-login = "epage"
user-name = "Ed Page"
[[publisher.clap]]
version = "4.5.16"
when = "2024-08-15"
user-id = 6743
user-login = "epage"
user-name = "Ed Page"
[[publisher.clap_builder]]
version = "4.4.5"
when = "2023-09-25"
@ -113,6 +127,13 @@ user-id = 6743
user-login = "epage"
user-name = "Ed Page"
[[publisher.clap_derive]]
version = "4.5.13"
when = "2024-07-31"
user-id = 6743
user-login = "epage"
user-name = "Ed Page"
[[publisher.clap_lex]]
version = "0.5.1"
when = "2023-08-24"
@ -120,6 +141,13 @@ user-id = 6743
user-login = "epage"
user-name = "Ed Page"
[[publisher.clap_lex]]
version = "0.7.2"
when = "2024-07-25"
user-id = 6743
user-login = "epage"
user-name = "Ed Page"
[[publisher.core-foundation]]
version = "0.9.3"
when = "2022-02-07"
@ -1033,6 +1061,12 @@ criteria = "safe-to-deploy"
version = "0.4.0"
notes = "Contains `forbid_unsafe` and only uses `std::fmt` from the standard library. Otherwise only contains string manipulation."
[[audits.bytecode-alliance.audits.heck]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
delta = "0.4.1 -> 0.5.0"
notes = "Minor changes for a `no_std` upgrade but otherwise everything looks as expected."
[[audits.bytecode-alliance.audits.id-arena]]
who = "Nick Fitzgerald <fitzgen@gmail.com>"
criteria = "safe-to-deploy"
@ -1265,6 +1299,16 @@ delta = "2.5.0 -> 2.6.0"
notes = "The changes from the previous version are negligible and thus it retains the same properties."
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
[[audits.google.audits.clap_builder]]
who = "Lukasz Anforowicz <lukasza@chromium.org>"
criteria = "safe-to-deploy"
version = "4.5.15"
notes = '''
Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'`, `'\bnet\b'`, `'\bunsafe\b'`
and there were no hits.
'''
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
[[audits.google.audits.equivalent]]
who = "George Burgess IV <gbiv@google.com>"
criteria = "safe-to-deploy"
@ -1297,6 +1341,19 @@ criteria = "safe-to-deploy"
version = "0.3.1"
aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT"
[[audits.google.audits.heck]]
who = "Lukasz Anforowicz <lukasza@chromium.org>"
criteria = "safe-to-deploy"
version = "0.4.1"
notes = """
Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'``, `'\bnet\b'``, `'\bunsafe\b'``
and there were no hits.
`heck` (version `0.3.3`) has been added to Chromium in
https://source.chromium.org/chromium/chromium/src/+/28841c33c77833cc30b286f9ae24c97e7a8f4057
"""
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
[[audits.google.audits.http]]
who = "ChromeOS"
criteria = "safe-to-run"

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.lock":"25a8765691ebacef2996651a2a08b57a2e9f7f782a7894fd3bb8016ca0c9a4e7","Cargo.toml":"1595ad36f00f988ce802dd2916ce25f07e476bf5d7440a192991d9472614c03c","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"3dad3b7606dec7ce40f54546e0dd485aeb52a45d4fcdfdaf830fd8349bbe43a5","README.md":"dcb157ba695dd8f1572944cc5bf84b8f67f8bb73925a5b725a9e274c755ce1a6","examples/dump.rs":"236dd2a3dce7512d1faeda5caec8d272299441b5d204696957940c687a021be8","src/color.rs":"33c9af0614e86612430e496d3add4cdcf4b9a6b5a8cc532d3caeb561a7d8fdfd","src/effect.rs":"c622c5472ba34d368a25341ce9488674b1e8516704aba80ae308e04b28136cd5","src/lib.rs":"0106395ba7263dbee67458e5ff4038cab493a3d34f3dcf0cb75504b1531a58e1","src/macros.rs":"0c90b45626fe8331d5b3326abb831f4ba6e04bcc975b1b9c01e465715050caa2","src/reset.rs":"65658e159fdf8f018bcfe6fdcfff688dbc4f3579fe1c685abdf92af6267165f8","src/style.rs":"f17ae53e38a3551ee8e3092f259aadfafabd3103e2db7fb3af291241dc6b8f46"},"package":"b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46"}
{"files":{"Cargo.lock":"f1b654e343f2784fcee83c618945ba6ebfd0dfa378f2d77c231348150322c58b","Cargo.toml":"647d64af5a7a10bdad5bc17e6678315d80382da525737f04e05a8a9ff996ce31","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"3dad3b7606dec7ce40f54546e0dd485aeb52a45d4fcdfdaf830fd8349bbe43a5","README.md":"dcb157ba695dd8f1572944cc5bf84b8f67f8bb73925a5b725a9e274c755ce1a6","examples/dump-style.rs":"a6c89b70be79594485312ec4670886ea9f4bebbf2f39fedfbd16d92745824f82","src/color.rs":"5a53d01fe9c28794ffbbf6f687f2f2ab70f19beea583bbdf7bdf874ea8280886","src/effect.rs":"f4dc053212f0a0da33fb75ad5888feaf8a76be382e889e002f9e9c74885f98a2","src/lib.rs":"fdd7cb0f5ae4b6a964be6bccd0651dbde50d7bf82a24c044f4cc4ac61957e8dd","src/macros.rs":"0c90b45626fe8331d5b3326abb831f4ba6e04bcc975b1b9c01e465715050caa2","src/reset.rs":"df498292ee2670f40e101a99099135db29c603a01b7cb5124e4cd5e553b4e84b","src/style.rs":"9dbe81c3efc24603ba1bac2a8297f5118398b5799e546b1236e84767e181d3f0"},"package":"1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"}

2
third_party/rust/anstyle/Cargo.lock сгенерированный поставляемый
Просмотреть файл

@ -4,7 +4,7 @@ version = 3
[[package]]
name = "anstyle"
version = "1.0.3"
version = "1.0.8"
dependencies = [
"lexopt",
]

94
third_party/rust/anstyle/Cargo.toml поставляемый
Просмотреть файл

@ -11,9 +11,10 @@
[package]
edition = "2021"
rust-version = "1.70.0"
rust-version = "1.65.0"
name = "anstyle"
version = "1.0.3"
version = "1.0.8"
build = false
include = [
"build.rs",
"src/**/*",
@ -24,6 +25,10 @@ include = [
"benches/**/*",
"examples/**/*",
]
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "ANSI text styling"
homepage = "https://github.com/rust-cli/anstyle"
readme = "README.md"
@ -37,6 +42,13 @@ categories = ["command-line-interface"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-cli/anstyle.git"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = [
"--cfg",
"docsrs",
]
[package.metadata.release]
tag-prefix = ""
@ -75,6 +87,14 @@ replace = """
[Unreleased]: https://github.com/rust-cli/anstyle/compare/{{tag_name}}...HEAD"""
search = "<!-- next-url -->"
[lib]
name = "anstyle"
path = "src/lib.rs"
[[example]]
name = "dump-style"
path = "examples/dump-style.rs"
[dependencies]
[dev-dependencies.lexopt]
@ -83,3 +103,73 @@ version = "0.3.0"
[features]
default = ["std"]
std = []
[lints.clippy]
bool_assert_comparison = "allow"
branches_sharing_code = "allow"
checked_conversions = "warn"
collapsible_else_if = "allow"
create_dir = "warn"
dbg_macro = "warn"
debug_assert_with_mut_call = "warn"
doc_markdown = "warn"
empty_enum = "warn"
enum_glob_use = "warn"
expl_impl_clone_on_copy = "warn"
explicit_deref_methods = "warn"
explicit_into_iter_loop = "warn"
fallible_impl_from = "warn"
filter_map_next = "warn"
flat_map_option = "warn"
float_cmp_const = "warn"
fn_params_excessive_bools = "warn"
from_iter_instead_of_collect = "warn"
if_same_then_else = "allow"
implicit_clone = "warn"
imprecise_flops = "warn"
inconsistent_struct_constructor = "warn"
inefficient_to_string = "warn"
infinite_loop = "warn"
invalid_upcast_comparisons = "warn"
items_after_statements = "warn"
large_digit_groups = "warn"
large_stack_arrays = "warn"
large_types_passed_by_value = "warn"
let_and_return = "allow"
linkedlist = "warn"
lossy_float_literal = "warn"
macro_use_imports = "warn"
match_wildcard_for_single_variants = "warn"
mem_forget = "warn"
mutex_integer = "warn"
needless_continue = "warn"
needless_for_each = "warn"
negative_feature_names = "warn"
path_buf_push_overwrite = "warn"
ptr_as_ptr = "warn"
rc_mutex = "warn"
redundant_feature_names = "warn"
ref_option_ref = "warn"
rest_pat_in_fully_bound_structs = "warn"
same_functions_in_if_condition = "warn"
self_named_module_files = "warn"
semicolon_if_nothing_returned = "warn"
single_match_else = "warn"
str_to_string = "warn"
string_add = "warn"
string_add_assign = "warn"
string_lit_as_bytes = "warn"
string_to_string = "warn"
todo = "warn"
trait_duplication_in_bounds = "warn"
verbose_file_reads = "warn"
wildcard_imports = "warn"
zero_sized_map_values = "warn"
[lints.rust]
rust_2018_idioms = "warn"
unreachable_pub = "warn"
unsafe_op_in_unsafe_fn = "warn"
unused_lifetimes = "warn"
unused_macro_rules = "warn"
unused_qualifications = "warn"

Просмотреть файл

@ -1,3 +1,5 @@
//! Write ANSI escape code colored text
use std::io::Write;
fn main() -> Result<(), lexopt::Error> {
@ -6,39 +8,45 @@ fn main() -> Result<(), lexopt::Error> {
let mut stdout = stdout.lock();
for fixed in 0..16 {
let style = style(fixed, args.layer, args.effects);
let color = anstyle::Ansi256Color(fixed)
.into_ansi()
.expect("4-bit range used");
let style = style(color, args.layer, args.effects);
let _ = print_number(&mut stdout, fixed, style);
if fixed == 7 || fixed == 15 {
let _ = writeln!(&mut stdout);
}
}
for r in 0..6 {
let _ = writeln!(stdout);
for g in 0..6 {
for b in 0..6 {
let fixed = r * 36 + g * 6 + b + 16;
let style = style(fixed, args.layer, args.effects);
let _ = print_number(&mut stdout, fixed, style);
}
for fixed in 16..232 {
let col = (fixed - 16) % 36;
if col == 0 {
let _ = writeln!(stdout);
}
}
for c in 0..24 {
if 0 == c % 8 {
let _ = writeln!(stdout);
}
let fixed = 232 + c;
let style = style(fixed, args.layer, args.effects);
let color = anstyle::Ansi256Color(fixed);
let style = style(color, args.layer, args.effects);
let _ = print_number(&mut stdout, fixed, style);
}
let _ = writeln!(stdout);
let _ = writeln!(stdout);
for fixed in 232..=255 {
let color = anstyle::Ansi256Color(fixed);
let style = style(color, args.layer, args.effects);
let _ = print_number(&mut stdout, fixed, style);
}
let _ = writeln!(stdout);
Ok(())
}
fn style(fixed: u8, layer: Layer, effects: anstyle::Effects) -> anstyle::Style {
let color = anstyle::Ansi256Color(fixed).into();
fn style(
color: impl Into<anstyle::Color>,
layer: Layer,
effects: anstyle::Effects,
) -> anstyle::Style {
let color = color.into();
(match layer {
Layer::Fg => anstyle::Style::new().fg_color(Some(color)),
Layer::Bg => anstyle::Style::new().bg_color(Some(color)),
@ -51,13 +59,7 @@ fn print_number(
fixed: u8,
style: anstyle::Style,
) -> std::io::Result<()> {
write!(
stdout,
"{}{:>4}{}",
style.render(),
fixed,
anstyle::Reset.render()
)
write!(stdout, "{style}{fixed:>3X}{style:#}",)
}
#[derive(Default)]

114
third_party/rust/anstyle/src/color.rs поставляемый
Просмотреть файл

@ -1,8 +1,18 @@
/// Any ANSI color code scheme
#[allow(clippy::exhaustive_enums)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Color {
/// Available 4-bit ANSI color palette codes
///
/// The user's terminal defines the meaning of the each palette code.
Ansi(AnsiColor),
/// 256 (8-bit) color support
///
/// - `0..16` are [`AnsiColor`] palette codes
/// - `0..232` map to [`RgbColor`] color values
/// - `232..` map to [`RgbColor`] gray-scale values
Ansi256(Ansi256Color),
/// 24-bit ANSI RGB color codes
Rgb(RgbColor),
}
@ -23,9 +33,9 @@ impl Color {
/// Render the ANSI code for a foreground color
#[inline]
pub fn render_fg(self) -> impl core::fmt::Display {
pub fn render_fg(self) -> impl core::fmt::Display + Copy {
match self {
Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_fg_str()),
Self::Ansi(color) => color.as_fg_buffer(),
Self::Ansi256(color) => color.as_fg_buffer(),
Self::Rgb(color) => color.as_fg_buffer(),
}
@ -35,7 +45,7 @@ impl Color {
#[cfg(feature = "std")]
pub(crate) fn write_fg_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> {
let buffer = match self {
Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_fg_str()),
Self::Ansi(color) => color.as_fg_buffer(),
Self::Ansi256(color) => color.as_fg_buffer(),
Self::Rgb(color) => color.as_fg_buffer(),
};
@ -44,9 +54,9 @@ impl Color {
/// Render the ANSI code for a background color
#[inline]
pub fn render_bg(self) -> impl core::fmt::Display {
pub fn render_bg(self) -> impl core::fmt::Display + Copy {
match self {
Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_bg_str()),
Self::Ansi(color) => color.as_bg_buffer(),
Self::Ansi256(color) => color.as_bg_buffer(),
Self::Rgb(color) => color.as_bg_buffer(),
}
@ -56,7 +66,7 @@ impl Color {
#[cfg(feature = "std")]
pub(crate) fn write_bg_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> {
let buffer = match self {
Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_bg_str()),
Self::Ansi(color) => color.as_bg_buffer(),
Self::Ansi256(color) => color.as_bg_buffer(),
Self::Rgb(color) => color.as_bg_buffer(),
};
@ -64,7 +74,7 @@ impl Color {
}
#[inline]
pub(crate) fn render_underline(self) -> impl core::fmt::Display {
pub(crate) fn render_underline(self) -> impl core::fmt::Display + Copy {
match self {
Self::Ansi(color) => color.as_underline_buffer(),
Self::Ansi256(color) => color.as_underline_buffer(),
@ -122,6 +132,7 @@ impl From<(u8, u8, u8)> for Color {
/// Available 4-bit ANSI color palette codes
///
/// The user's terminal defines the meaning of the each palette code.
#[allow(clippy::exhaustive_enums)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum AnsiColor {
@ -191,8 +202,8 @@ impl AnsiColor {
/// Render the ANSI code for a foreground color
#[inline]
pub fn render_fg(self) -> impl core::fmt::Display {
self.as_fg_str()
pub fn render_fg(self) -> impl core::fmt::Display + Copy {
NullFormatter(self.as_fg_str())
}
#[inline]
@ -217,10 +228,15 @@ impl AnsiColor {
}
}
#[inline]
fn as_fg_buffer(&self) -> DisplayBuffer {
DisplayBuffer::default().write_str(self.as_fg_str())
}
/// Render the ANSI code for a background color
#[inline]
pub fn render_bg(self) -> impl core::fmt::Display {
self.as_bg_str()
pub fn render_bg(self) -> impl core::fmt::Display + Copy {
NullFormatter(self.as_bg_str())
}
#[inline]
@ -245,6 +261,11 @@ impl AnsiColor {
}
}
#[inline]
fn as_bg_buffer(&self) -> DisplayBuffer {
DisplayBuffer::default().write_str(self.as_bg_str())
}
#[inline]
fn as_underline_buffer(&self) -> DisplayBuffer {
// No per-color codes; must delegate to `Ansi256Color`
@ -325,6 +346,7 @@ impl AnsiColor {
/// - `0..16` are [`AnsiColor`] palette codes
/// - `0..232` map to [`RgbColor`] color values
/// - `232..` map to [`RgbColor`] gray-scale values
#[allow(clippy::exhaustive_structs)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct Ansi256Color(pub u8);
@ -344,11 +366,13 @@ impl Ansi256Color {
crate::Style::new().fg_color(Some(Color::Ansi256(self)))
}
/// Get the raw value
#[inline]
pub const fn index(self) -> u8 {
self.0
}
/// Convert to [`AnsiColor`] when there is a 1:1 mapping
#[inline]
pub const fn into_ansi(self) -> Option<AnsiColor> {
match self.index() {
@ -372,6 +396,7 @@ impl Ansi256Color {
}
}
/// Losslessly convert from [`AnsiColor`]
#[inline]
pub const fn from_ansi(color: AnsiColor) -> Self {
match color {
@ -396,7 +421,7 @@ impl Ansi256Color {
/// Render the ANSI code for a foreground color
#[inline]
pub fn render_fg(self) -> impl core::fmt::Display {
pub fn render_fg(self) -> impl core::fmt::Display + Copy {
self.as_fg_buffer()
}
@ -410,7 +435,7 @@ impl Ansi256Color {
/// Render the ANSI code for a background color
#[inline]
pub fn render_bg(self) -> impl core::fmt::Display {
pub fn render_bg(self) -> impl core::fmt::Display + Copy {
self.as_bg_buffer()
}
@ -446,6 +471,7 @@ impl From<AnsiColor> for Ansi256Color {
}
/// 24-bit ANSI RGB color codes
#[allow(clippy::exhaustive_structs)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RgbColor(pub u8, pub u8, pub u8);
@ -464,16 +490,19 @@ impl RgbColor {
crate::Style::new().fg_color(Some(Color::Rgb(self)))
}
/// Red
#[inline]
pub const fn r(self) -> u8 {
self.0
}
/// Green
#[inline]
pub const fn g(self) -> u8 {
self.1
}
/// Blue
#[inline]
pub const fn b(self) -> u8 {
self.2
@ -481,7 +510,7 @@ impl RgbColor {
/// Render the ANSI code for a foreground color
#[inline]
pub fn render_fg(self) -> impl core::fmt::Display {
pub fn render_fg(self) -> impl core::fmt::Display + Copy {
self.as_fg_buffer()
}
@ -499,7 +528,7 @@ impl RgbColor {
/// Render the ANSI code for a background color
#[inline]
pub fn render_bg(self) -> impl core::fmt::Display {
pub fn render_bg(self) -> impl core::fmt::Display + Copy {
self.as_bg_buffer()
}
@ -536,9 +565,11 @@ impl From<(u8, u8, u8)> for RgbColor {
}
}
#[derive(Default, Debug)]
const DISPLAY_BUFFER_CAPACITY: usize = 19;
#[derive(Copy, Clone, Default, Debug)]
struct DisplayBuffer {
buffer: [u8; 19],
buffer: [u8; DISPLAY_BUFFER_CAPACITY],
len: usize,
}
@ -580,7 +611,10 @@ impl DisplayBuffer {
#[inline]
fn as_str(&self) -> &str {
// SAFETY: Only `&str` can be written to the buffer
unsafe { core::str::from_utf8_unchecked(&self.buffer[0..self.len]) }
#[allow(unsafe_code)]
unsafe {
core::str::from_utf8_unchecked(&self.buffer[0..self.len])
}
}
#[inline]
@ -593,7 +627,19 @@ impl DisplayBuffer {
impl core::fmt::Display for DisplayBuffer {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.as_str().fmt(f)
let s = self.as_str();
write!(f, "{s}")
}
}
#[derive(Copy, Clone, Default, Debug)]
struct NullFormatter<D: core::fmt::Display>(D);
impl<D: core::fmt::Display> core::fmt::Display for NullFormatter<D> {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let d = &self.0;
write!(f, "{d}")
}
}
@ -607,5 +653,35 @@ mod test {
let c = RgbColor(255, 255, 255);
let actual = c.render_fg().to_string();
assert_eq!(actual, "\u{1b}[38;2;255;255;255m");
assert_eq!(actual.len(), DISPLAY_BUFFER_CAPACITY);
}
#[test]
fn print_size_of() {
use std::mem::size_of;
dbg!(size_of::<Color>());
dbg!(size_of::<AnsiColor>());
dbg!(size_of::<Ansi256Color>());
dbg!(size_of::<RgbColor>());
dbg!(size_of::<DisplayBuffer>());
}
#[test]
fn no_align() {
#[track_caller]
fn assert_no_align(d: impl core::fmt::Display) {
let expected = format!("{d}");
let actual = format!("{d:<10}");
assert_eq!(expected, actual);
}
assert_no_align(AnsiColor::White.render_fg());
assert_no_align(AnsiColor::White.render_bg());
assert_no_align(Ansi256Color(0).render_fg());
assert_no_align(Ansi256Color(0).render_bg());
assert_no_align(RgbColor(0, 0, 0).render_fg());
assert_no_align(RgbColor(0, 0, 0).render_bg());
assert_no_align(Color::Ansi(AnsiColor::White).render_fg());
assert_no_align(Color::Ansi(AnsiColor::White).render_bg());
}
}

41
third_party/rust/anstyle/src/effect.rs поставляемый
Просмотреть файл

@ -9,21 +9,30 @@
pub struct Effects(u16);
impl Effects {
/// No [`Effects`] applied
const PLAIN: Self = Effects(0);
#[allow(missing_docs)]
pub const BOLD: Self = Effects(1 << 0);
#[allow(missing_docs)]
pub const DIMMED: Self = Effects(1 << 1);
/// Not widely supported. Sometimes treated as inverse or blink
pub const ITALIC: Self = Effects(1 << 2);
/// Style extensions exist for Kitty, VTE, mintty and iTerm2.
pub const UNDERLINE: Self = Effects(1 << 3);
#[allow(missing_docs)]
pub const DOUBLE_UNDERLINE: Self = Effects(1 << 4);
#[allow(missing_docs)]
pub const CURLY_UNDERLINE: Self = Effects(1 << 5);
#[allow(missing_docs)]
pub const DOTTED_UNDERLINE: Self = Effects(1 << 6);
#[allow(missing_docs)]
pub const DASHED_UNDERLINE: Self = Effects(1 << 7);
#[allow(missing_docs)]
pub const BLINK: Self = Effects(1 << 8);
/// Swap foreground and background colors; inconsistent emulation
pub const INVERT: Self = Effects(1 << 9);
#[allow(missing_docs)]
pub const HIDDEN: Self = Effects(1 << 10);
/// Characters legible but marked as if for deletion. Not supported in Terminal.app
pub const STRIKETHROUGH: Self = Effects(1 << 11);
@ -156,7 +165,7 @@ impl Effects {
/// Render the ANSI code
#[inline]
pub fn render(self) -> impl core::fmt::Display {
pub fn render(self) -> impl core::fmt::Display + Copy {
EffectsDisplay(self)
}
@ -307,18 +316,21 @@ pub(crate) const METADATA: [Metadata; 12] = [
},
];
#[derive(Copy, Clone, Default, Debug)]
struct EffectsDisplay(Effects);
impl core::fmt::Display for EffectsDisplay {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
for index in self.0.index_iter() {
METADATA[index].escape.fmt(f)?;
let escape = METADATA[index].escape;
write!(f, "{escape}")?;
}
Ok(())
}
}
/// Enumerate each enabled value in [`Effects`]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EffectIter {
index: usize,
@ -366,3 +378,28 @@ impl Iterator for EffectIndexIter {
None
}
}
#[cfg(test)]
#[cfg(feature = "std")]
mod test {
use super::*;
#[test]
fn print_size_of() {
use std::mem::size_of;
dbg!(size_of::<Effects>());
dbg!(size_of::<EffectsDisplay>());
}
#[test]
fn no_align() {
#[track_caller]
fn assert_no_align(d: impl core::fmt::Display) {
let expected = format!("{d}");
let actual = format!("{d:<10}");
assert_eq!(expected, actual);
}
assert_no_align(Effects::BOLD.render());
}
}

7
third_party/rust/anstyle/src/lib.rs поставляемый
Просмотреть файл

@ -25,11 +25,12 @@
//!
//! User-styling parsers:
//! - [anstyle-git](https://docs.rs/anstyle-git): Parse Git style descriptions
//! - [anstyle-ls](https://docs.rs/anstyle-ls): Parse LS_COLORS style descriptions
//! - [anstyle-ls](https://docs.rs/anstyle-ls): Parse `LS_COLORS` style descriptions
//!
//! Convert to other formats
//! - [anstream](https://docs.rs/anstream): A simple cross platform library for writing colored text to a terminal
//! - [anstyle-roff](https://docs.rs/anstyle-roff): For converting to ROFF
//! - [anstyle-syntect](https://docs.rs/anstyle-syntect): For working with syntax highlighting
//!
//! Utilities
//! - [anstyle-lossy](https://docs.rs/anstyle-lossy): Convert between `anstyle::Color` types
@ -44,6 +45,10 @@
//! ```
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![warn(missing_docs)]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
#[macro_use]
mod macros;

38
third_party/rust/anstyle/src/reset.rs поставляемый
Просмотреть файл

@ -1,21 +1,47 @@
/// Reset terminal formatting
#[allow(clippy::exhaustive_structs)]
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Reset;
impl Reset {
/// Render the ANSI code
///
/// `Reset` also implements `Display` directly, so calling this method is optional.
#[inline]
pub fn render(self) -> impl core::fmt::Display {
ResetDisplay
pub fn render(self) -> impl core::fmt::Display + Copy {
self
}
}
struct ResetDisplay;
impl core::fmt::Display for ResetDisplay {
impl core::fmt::Display for Reset {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
RESET.fmt(f)
write!(f, "{RESET}")
}
}
pub(crate) const RESET: &str = "\x1B[0m";
#[cfg(test)]
#[cfg(feature = "std")]
mod test {
use super::*;
#[test]
fn print_size_of() {
use std::mem::size_of;
dbg!(size_of::<Reset>());
}
#[test]
fn no_align() {
#[track_caller]
fn assert_no_align(d: impl core::fmt::Display) {
let expected = format!("{d}");
let actual = format!("{d:<10}");
assert_eq!(expected, actual);
}
assert_no_align(Reset);
assert_no_align(Reset.render());
}
}

78
third_party/rust/anstyle/src/style.rs поставляемый
Просмотреть файл

@ -2,10 +2,17 @@ use crate::reset::RESET;
/// ANSI Text styling
///
/// You can print a `Style` to render the corresponding ANSI code.
/// Using the alternate flag `#` will render the ANSI reset code, if needed.
/// Together, this makes it convenient to render styles using inline format arguments.
///
/// # Examples
///
/// ```rust
/// let style = anstyle::Style::new().bold();
///
/// let value = 42;
/// println!("{style}{value}{style:#}");
/// ```
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Style {
@ -91,11 +98,33 @@ impl Style {
}
/// Render the ANSI code
///
/// `Style` also implements `Display` directly, so calling this method is optional.
#[inline]
pub fn render(self) -> impl core::fmt::Display {
pub fn render(self) -> impl core::fmt::Display + Copy {
StyleDisplay(self)
}
fn fmt_to(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use core::fmt::Display as _;
self.effects.render().fmt(f)?;
if let Some(fg) = self.fg {
fg.render_fg().fmt(f)?;
}
if let Some(bg) = self.bg {
bg.render_bg().fmt(f)?;
}
if let Some(underline) = self.underline {
underline.render_underline().fmt(f)?;
}
Ok(())
}
/// Write the ANSI code
#[inline]
#[cfg(feature = "std")]
@ -121,7 +150,7 @@ impl Style {
///
/// Unlike [`Reset::render`][crate::Reset::render], this will elide the code if there is nothing to reset.
#[inline]
pub fn render_reset(self) -> impl core::fmt::Display {
pub fn render_reset(self) -> impl core::fmt::Display + Copy {
if self != Self::new() {
RESET
} else {
@ -260,27 +289,32 @@ impl Style {
/// # Reflection
impl Style {
/// Get the foreground color
#[inline]
pub const fn get_fg_color(self) -> Option<crate::Color> {
self.fg
}
/// Get the background color
#[inline]
#[allow(missing_docs)]
pub const fn get_bg_color(self) -> Option<crate::Color> {
self.bg
}
#[inline]
#[allow(missing_docs)]
pub const fn get_underline_color(self) -> Option<crate::Color> {
self.underline
}
#[inline]
#[allow(missing_docs)]
pub const fn get_effects(self) -> crate::Effects {
self.effects
}
/// Check if no effects are enabled
/// Check if no styling is enabled
#[inline]
pub const fn is_plain(self) -> bool {
self.fg.is_none()
@ -366,7 +400,7 @@ impl core::ops::SubAssign<crate::Effects> for Style {
/// assert_ne!(anstyle::Effects::UNDERLINE | effects, effects);
/// assert_ne!(anstyle::RgbColor(0, 0, 0).on_default() | effects, effects);
/// ```
impl core::cmp::PartialEq<crate::Effects> for Style {
impl PartialEq<crate::Effects> for Style {
#[inline]
fn eq(&self, other: &crate::Effects) -> bool {
let other = Self::from(*other);
@ -374,24 +408,30 @@ impl core::cmp::PartialEq<crate::Effects> for Style {
}
}
impl core::fmt::Display for Style {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if f.alternate() {
self.render_reset().fmt(f)
} else {
self.fmt_to(f)
}
}
}
#[derive(Copy, Clone, Default, Debug)]
struct StyleDisplay(Style);
impl core::fmt::Display for StyleDisplay {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.effects.render().fmt(f)?;
if let Some(fg) = self.0.fg {
fg.render_fg().fmt(f)?;
}
if let Some(bg) = self.0.bg {
bg.render_bg().fmt(f)?;
}
if let Some(underline) = self.0.underline {
underline.render_underline().fmt(f)?;
}
Ok(())
self.0.fmt_to(f)
}
}
#[test]
#[cfg(feature = "std")]
fn print_size_of() {
use std::mem::size_of;
dbg!(size_of::<Style>());
dbg!(size_of::<StyleDisplay>());
}

2
third_party/rust/clap/.cargo-checksum.json поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

563
third_party/rust/clap/Cargo.lock сгенерированный поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

439
third_party/rust/clap/Cargo.toml поставляемый
Просмотреть файл

@ -11,9 +11,10 @@
[package]
edition = "2021"
rust-version = "1.70.0"
rust-version = "1.74"
name = "clap"
version = "4.4.5"
version = "4.5.16"
build = false
include = [
"build.rs",
"src/**/*",
@ -23,6 +24,10 @@ include = [
"benches/**/*",
"examples/**/*",
]
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "A simple to use, efficient, and full-featured Command Line Argument Parser"
readme = "README.md"
keywords = [
@ -100,6 +105,12 @@ file = "CITATION.cff"
replace = "version: {{version}}"
search = '^version: .+\..+\..+'
[[package.metadata.release.pre-release-replacements]]
exactly = 1
file = "src/lib.rs"
replace = "blob/v{{version}}/CHANGELOG.md"
search = 'blob/v.+\..+\..+/CHANGELOG.md'
[profile.bench]
lto = true
codegen-units = 1
@ -108,244 +119,258 @@ codegen-units = 1
opt-level = 1
[lib]
name = "clap"
path = "src/lib.rs"
bench = false
[[example]]
name = "demo"
required-features = ["derive"]
[[example]]
name = "cargo-example"
required-features = ["cargo"]
[[example]]
name = "cargo-example-derive"
required-features = ["derive"]
[[example]]
name = "escaped-positional"
required-features = ["cargo"]
[[example]]
name = "escaped-positional-derive"
required-features = ["derive"]
[[example]]
name = "find"
required-features = ["cargo"]
[[example]]
name = "git-derive"
required-features = ["derive"]
[[example]]
name = "typed-derive"
required-features = ["derive"]
[[example]]
name = "busybox"
path = "examples/multicall-busybox.rs"
[[example]]
name = "hostname"
path = "examples/multicall-hostname.rs"
[[example]]
name = "repl"
path = "examples/repl.rs"
required-features = ["help"]
[[bin]]
name = "stdio-fixture"
path = "src/bin/stdio-fixture.rs"
[[example]]
name = "01_quick"
path = "examples/tutorial_builder/01_quick.rs"
required-features = ["cargo"]
[[example]]
name = "02_apps"
path = "examples/tutorial_builder/02_apps.rs"
[[example]]
name = "02_crate"
path = "examples/tutorial_builder/02_crate.rs"
required-features = ["cargo"]
[[example]]
name = "02_app_settings"
path = "examples/tutorial_builder/02_app_settings.rs"
required-features = ["cargo"]
[[example]]
name = "03_01_flag_bool"
path = "examples/tutorial_builder/03_01_flag_bool.rs"
required-features = ["cargo"]
[[example]]
name = "03_01_flag_count"
path = "examples/tutorial_builder/03_01_flag_count.rs"
required-features = ["cargo"]
[[example]]
name = "03_02_option"
path = "examples/tutorial_builder/03_02_option.rs"
required-features = ["cargo"]
[[example]]
name = "03_02_option_mult"
path = "examples/tutorial_builder/03_02_option_mult.rs"
required-features = ["cargo"]
[[example]]
name = "03_03_positional"
path = "examples/tutorial_builder/03_03_positional.rs"
required-features = ["cargo"]
[[example]]
name = "03_03_positional_mult"
path = "examples/tutorial_builder/03_03_positional_mult.rs"
required-features = ["cargo"]
[[example]]
name = "03_04_subcommands"
path = "examples/tutorial_builder/03_04_subcommands.rs"
required-features = ["cargo"]
[[example]]
name = "03_05_default_values"
path = "examples/tutorial_builder/03_05_default_values.rs"
required-features = ["cargo"]
[[example]]
name = "04_01_possible"
path = "examples/tutorial_builder/04_01_possible.rs"
required-features = ["cargo"]
[[example]]
name = "04_01_enum"
path = "examples/tutorial_builder/04_01_enum.rs"
required-features = ["cargo"]
[[example]]
name = "04_02_parse"
path = "examples/tutorial_builder/04_02_parse.rs"
required-features = ["cargo"]
[[example]]
name = "04_02_validate"
path = "examples/tutorial_builder/04_02_validate.rs"
required-features = ["cargo"]
[[example]]
name = "04_03_relations"
path = "examples/tutorial_builder/04_03_relations.rs"
required-features = ["cargo"]
[[example]]
name = "04_04_custom"
path = "examples/tutorial_builder/04_04_custom.rs"
required-features = ["cargo"]
[[example]]
name = "05_01_assert"
path = "examples/tutorial_builder/05_01_assert.rs"
test = true
required-features = ["cargo"]
[[example]]
name = "01_quick_derive"
path = "examples/tutorial_derive/01_quick.rs"
required-features = ["derive"]
[[example]]
name = "02_apps_derive"
path = "examples/tutorial_derive/02_apps.rs"
required-features = ["derive"]
[[example]]
name = "02_crate_derive"
path = "examples/tutorial_derive/02_crate.rs"
required-features = ["derive"]
name = "02_app_settings"
path = "examples/tutorial_builder/02_app_settings.rs"
required-features = ["cargo"]
[[example]]
name = "02_app_settings_derive"
path = "examples/tutorial_derive/02_app_settings.rs"
required-features = ["derive"]
[[example]]
name = "02_apps"
path = "examples/tutorial_builder/02_apps.rs"
[[example]]
name = "02_apps_derive"
path = "examples/tutorial_derive/02_apps.rs"
required-features = ["derive"]
[[example]]
name = "02_crate"
path = "examples/tutorial_builder/02_crate.rs"
required-features = ["cargo"]
[[example]]
name = "02_crate_derive"
path = "examples/tutorial_derive/02_crate.rs"
required-features = ["derive"]
[[example]]
name = "03_01_flag_bool"
path = "examples/tutorial_builder/03_01_flag_bool.rs"
required-features = ["cargo"]
[[example]]
name = "03_01_flag_bool_derive"
path = "examples/tutorial_derive/03_01_flag_bool.rs"
required-features = ["derive"]
[[example]]
name = "03_01_flag_count"
path = "examples/tutorial_builder/03_01_flag_count.rs"
required-features = ["cargo"]
[[example]]
name = "03_01_flag_count_derive"
path = "examples/tutorial_derive/03_01_flag_count.rs"
required-features = ["derive"]
[[example]]
name = "03_02_option"
path = "examples/tutorial_builder/03_02_option.rs"
required-features = ["cargo"]
[[example]]
name = "03_02_option_derive"
path = "examples/tutorial_derive/03_02_option.rs"
required-features = ["derive"]
[[example]]
name = "03_02_option_mult"
path = "examples/tutorial_builder/03_02_option_mult.rs"
required-features = ["cargo"]
[[example]]
name = "03_02_option_mult_derive"
path = "examples/tutorial_derive/03_02_option_mult.rs"
required-features = ["derive"]
[[example]]
name = "03_03_positional"
path = "examples/tutorial_builder/03_03_positional.rs"
required-features = ["cargo"]
[[example]]
name = "03_03_positional_derive"
path = "examples/tutorial_derive/03_03_positional.rs"
required-features = ["derive"]
[[example]]
name = "03_03_positional_mult"
path = "examples/tutorial_builder/03_03_positional_mult.rs"
required-features = ["cargo"]
[[example]]
name = "03_03_positional_mult_derive"
path = "examples/tutorial_derive/03_03_positional_mult.rs"
required-features = ["derive"]
[[example]]
name = "03_04_subcommands"
path = "examples/tutorial_builder/03_04_subcommands.rs"
required-features = ["cargo"]
[[example]]
name = "03_04_subcommands_alt_derive"
path = "examples/tutorial_derive/03_04_subcommands_alt.rs"
required-features = ["derive"]
[[example]]
name = "03_04_subcommands_derive"
path = "examples/tutorial_derive/03_04_subcommands.rs"
required-features = ["derive"]
[[example]]
name = "03_04_subcommands_alt_derive"
path = "examples/tutorial_derive/03_04_subcommands_alt.rs"
required-features = ["derive"]
name = "03_05_default_values"
path = "examples/tutorial_builder/03_05_default_values.rs"
required-features = ["cargo"]
[[example]]
name = "03_05_default_values_derive"
path = "examples/tutorial_derive/03_05_default_values.rs"
required-features = ["derive"]
[[example]]
name = "04_01_enum"
path = "examples/tutorial_builder/04_01_enum.rs"
required-features = ["cargo"]
[[example]]
name = "04_01_enum_derive"
path = "examples/tutorial_derive/04_01_enum.rs"
required-features = ["derive"]
[[example]]
name = "04_01_possible"
path = "examples/tutorial_builder/04_01_possible.rs"
required-features = ["cargo"]
[[example]]
name = "04_02_parse"
path = "examples/tutorial_builder/04_02_parse.rs"
required-features = ["cargo"]
[[example]]
name = "04_02_parse_derive"
path = "examples/tutorial_derive/04_02_parse.rs"
required-features = ["derive"]
[[example]]
name = "04_02_validate"
path = "examples/tutorial_builder/04_02_validate.rs"
required-features = ["cargo"]
[[example]]
name = "04_02_validate_derive"
path = "examples/tutorial_derive/04_02_validate.rs"
required-features = ["derive"]
[[example]]
name = "04_03_relations"
path = "examples/tutorial_builder/04_03_relations.rs"
required-features = ["cargo"]
[[example]]
name = "04_03_relations_derive"
path = "examples/tutorial_derive/04_03_relations.rs"
required-features = ["derive"]
[[example]]
name = "04_04_custom"
path = "examples/tutorial_builder/04_04_custom.rs"
required-features = ["cargo"]
[[example]]
name = "04_04_custom_derive"
path = "examples/tutorial_derive/04_04_custom.rs"
required-features = ["derive"]
[[example]]
name = "05_01_assert"
path = "examples/tutorial_builder/05_01_assert.rs"
test = true
required-features = ["cargo"]
[[example]]
name = "05_01_assert_derive"
path = "examples/tutorial_derive/05_01_assert.rs"
test = true
required-features = ["derive"]
[[example]]
name = "busybox"
path = "examples/multicall-busybox.rs"
[[example]]
name = "cargo-example"
path = "examples/cargo-example.rs"
required-features = [
"cargo",
"color",
]
[[example]]
name = "cargo-example-derive"
path = "examples/cargo-example-derive.rs"
required-features = [
"derive",
"color",
]
[[example]]
name = "demo"
path = "examples/demo.rs"
required-features = ["derive"]
[[example]]
name = "escaped-positional"
path = "examples/escaped-positional.rs"
required-features = ["cargo"]
[[example]]
name = "escaped-positional-derive"
path = "examples/escaped-positional-derive.rs"
required-features = ["derive"]
[[example]]
name = "find"
path = "examples/find.rs"
required-features = ["cargo"]
[[example]]
name = "git"
path = "examples/git.rs"
[[example]]
name = "git-derive"
path = "examples/git-derive.rs"
required-features = ["derive"]
[[example]]
name = "hostname"
path = "examples/multicall-hostname.rs"
[[example]]
name = "interop_augment_args"
path = "examples/derive_ref/augment_args.rs"
@ -356,44 +381,67 @@ name = "interop_augment_subcommands"
path = "examples/derive_ref/augment_subcommands.rs"
required-features = ["derive"]
[[example]]
name = "interop_flatten_hand_args"
path = "examples/derive_ref/flatten_hand_args.rs"
required-features = ["derive"]
[[example]]
name = "interop_hand_subcommand"
path = "examples/derive_ref/hand_subcommand.rs"
required-features = ["derive"]
[[example]]
name = "interop_flatten_hand_args"
path = "examples/derive_ref/flatten_hand_args.rs"
name = "pacman"
path = "examples/pacman.rs"
[[example]]
name = "repl"
path = "examples/repl.rs"
required-features = ["help"]
[[example]]
name = "repl-derive"
path = "examples/repl-derive.rs"
required-features = ["derive"]
[[example]]
name = "typed-derive"
path = "examples/typed-derive.rs"
required-features = ["derive"]
[dependencies.clap_builder]
version = "=4.4.5"
version = "=4.5.15"
default-features = false
[dependencies.clap_derive]
version = "=4.4.2"
version = "=4.5.13"
optional = true
[dev-dependencies.automod]
version = "1.0.14"
[dev-dependencies.clap-cargo]
version = "0.14.1"
default-features = false
[dev-dependencies.humantime]
version = "2.1.0"
[dev-dependencies.rustversion]
version = "1.0.14"
version = "1.0.15"
[dev-dependencies.shlex]
version = "1.1.0"
version = "1.3.0"
[dev-dependencies.snapbox]
version = "0.4.12"
[dev-dependencies.static_assertions]
version = "1.1.0"
version = "0.6.16"
[dev-dependencies.trybuild]
version = "1.0.83"
version = "1.0.91"
[dev-dependencies.trycmd]
version = "0.14.17"
version = "0.15.3"
features = [
"color-auto",
"diff",
@ -401,9 +449,6 @@ features = [
]
default-features = false
[dev-dependencies.unic-emoji-char]
version = "0.9.0"
[features]
cargo = ["clap_builder/cargo"]
color = ["clap_builder/color"]
@ -435,6 +480,7 @@ unstable-doc = [
"clap_builder/unstable-doc",
"derive",
]
unstable-ext = ["clap_builder/unstable-ext"]
unstable-styles = ["clap_builder/unstable-styles"]
unstable-v5 = [
"clap_builder/unstable-v5",
@ -443,3 +489,72 @@ unstable-v5 = [
]
usage = ["clap_builder/usage"]
wrap_help = ["clap_builder/wrap_help"]
[lints.clippy]
assigning_clones = "allow"
blocks_in_conditions = "allow"
bool_assert_comparison = "allow"
branches_sharing_code = "allow"
checked_conversions = "warn"
collapsible_else_if = "allow"
create_dir = "warn"
dbg_macro = "warn"
debug_assert_with_mut_call = "warn"
doc_markdown = "warn"
empty_enum = "warn"
enum_glob_use = "warn"
expl_impl_clone_on_copy = "warn"
explicit_deref_methods = "warn"
explicit_into_iter_loop = "warn"
fallible_impl_from = "warn"
filter_map_next = "warn"
flat_map_option = "warn"
float_cmp_const = "warn"
fn_params_excessive_bools = "warn"
from_iter_instead_of_collect = "warn"
if_same_then_else = "allow"
implicit_clone = "warn"
imprecise_flops = "warn"
inconsistent_struct_constructor = "warn"
inefficient_to_string = "warn"
infinite_loop = "warn"
invalid_upcast_comparisons = "warn"
large_digit_groups = "warn"
large_stack_arrays = "warn"
large_types_passed_by_value = "warn"
let_and_return = "allow"
linkedlist = "warn"
lossy_float_literal = "warn"
macro_use_imports = "warn"
mem_forget = "warn"
multiple_bound_locations = "allow"
mutex_integer = "warn"
needless_continue = "warn"
needless_for_each = "warn"
negative_feature_names = "warn"
path_buf_push_overwrite = "warn"
ptr_as_ptr = "warn"
rc_mutex = "warn"
redundant_feature_names = "warn"
ref_option_ref = "warn"
rest_pat_in_fully_bound_structs = "warn"
same_functions_in_if_condition = "warn"
self_named_module_files = "warn"
semicolon_if_nothing_returned = "warn"
string_add_assign = "warn"
string_lit_as_bytes = "warn"
todo = "warn"
trait_duplication_in_bounds = "warn"
verbose_file_reads = "warn"
zero_sized_map_values = "warn"
[lints.rust]
unreachable_pub = "warn"
unsafe_op_in_unsafe_fn = "warn"
unused_lifetimes = "warn"
unused_macro_rules = "warn"
unused_qualifications = "warn"
[lints.rust.rust_2018_idioms]
level = "warn"
priority = -1

Просмотреть файл

@ -3,12 +3,23 @@ use clap::Parser;
#[derive(Parser)] // requires `derive` feature
#[command(name = "cargo")]
#[command(bin_name = "cargo")]
#[command(styles = CLAP_STYLING)]
enum CargoCli {
ExampleDerive(ExampleDeriveArgs),
}
// See also `clap_cargo::style::CLAP_STYLING`
pub const CLAP_STYLING: clap::builder::styling::Styles = clap::builder::styling::Styles::styled()
.header(clap_cargo::style::HEADER)
.usage(clap_cargo::style::USAGE)
.literal(clap_cargo::style::LITERAL)
.placeholder(clap_cargo::style::PLACEHOLDER)
.error(clap_cargo::style::ERROR)
.valid(clap_cargo::style::VALID)
.invalid(clap_cargo::style::INVALID);
#[derive(clap::Args)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct ExampleDeriveArgs {
#[arg(long)]
manifest_path: Option<std::path::PathBuf>,

Просмотреть файл

@ -1,6 +1,7 @@
fn main() {
let cmd = clap::Command::new("cargo")
.bin_name("cargo")
.styles(CLAP_STYLING)
.subcommand_required(true)
.subcommand(
clap::command!("example").arg(
@ -16,3 +17,13 @@ fn main() {
let manifest_path = matches.get_one::<std::path::PathBuf>("manifest-path");
println!("{manifest_path:?}");
}
// See also `clap_cargo::style::CLAP_STYLING`
pub const CLAP_STYLING: clap::builder::styling::Styles = clap::builder::styling::Styles::styled()
.header(clap_cargo::style::HEADER)
.usage(clap_cargo::style::USAGE)
.literal(clap_cargo::style::LITERAL)
.placeholder(clap_cargo::style::PLACEHOLDER)
.error(clap_cargo::style::ERROR)
.valid(clap_cargo::style::VALID)
.invalid(clap_cargo::style::INVALID);

4
third_party/rust/clap/examples/demo.rs поставляемый
Просмотреть файл

@ -2,7 +2,7 @@ use clap::Parser;
/// Simple program to greet a person
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Args {
/// Name of the person to greet
#[arg(short, long)]
@ -17,6 +17,6 @@ fn main() {
let args = Args::parse();
for _ in 0..args.count {
println!("Hello {}!", args.name)
println!("Hello {}!", args.name);
}
}

Просмотреть файл

@ -1,3 +1,4 @@
#![allow(dead_code)]
use clap::error::{Error, ErrorKind};
use clap::{ArgMatches, Args as _, Command, FromArgMatches, Parser, Subcommand};

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)] // requires `derive` feature
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
#[arg(short = 'f')]
eff: bool,

36
third_party/rust/clap/examples/find.md поставляемый
Просмотреть файл

@ -12,7 +12,7 @@ Options:
TESTS:
--empty File is empty and is either a regular file or a directory
--name <NAME> Base of file name (the path with the leading directories removed) matches shell
--name <name> Base of file name (the path with the leading directories removed) matches shell
pattern pattern
OPERATORS:
@ -41,5 +41,39 @@ $ find --empty -o --name .keep
),
]
$ find --empty -o --name .keep -o --name foo
[
(
"empty",
Bool(
true,
),
),
(
"or",
Bool(
true,
),
),
(
"name",
String(
".keep",
),
),
(
"or",
Bool(
true,
),
),
(
"name",
String(
"foo",
),
),
]
```

37
third_party/rust/clap/examples/find.rs поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
use std::collections::BTreeMap;
use clap::{arg, command, ArgGroup, ArgMatches, Command};
use clap::{command, value_parser, Arg, ArgAction, ArgGroup, ArgMatches, Command};
fn main() {
let matches = cli().get_matches();
@ -13,17 +13,44 @@ fn cli() -> Command {
.group(ArgGroup::new("tests").multiple(true))
.next_help_heading("TESTS")
.args([
arg!(--empty "File is empty and is either a regular file or a directory").group("tests"),
arg!(--name <NAME> "Base of file name (the path with the leading directories removed) matches shell pattern pattern").group("tests"),
position_sensitive_flag(Arg::new("empty"))
.long("empty")
.action(ArgAction::Append)
.help("File is empty and is either a regular file or a directory")
.group("tests"),
Arg::new("name")
.long("name")
.action(ArgAction::Append)
.help("Base of file name (the path with the leading directories removed) matches shell pattern pattern")
.group("tests")
])
.group(ArgGroup::new("operators").multiple(true))
.next_help_heading("OPERATORS")
.args([
arg!(-o - -or "expr2 is not evaluate if exp1 is true").group("operators"),
arg!(-a - -and "Same as `expr1 expr1`").group("operators"),
position_sensitive_flag(Arg::new("or"))
.short('o')
.long("or")
.action(ArgAction::Append)
.help("expr2 is not evaluate if exp1 is true")
.group("operators"),
position_sensitive_flag(Arg::new("and"))
.short('a')
.long("and")
.action(ArgAction::Append)
.help("Same as `expr1 expr1`")
.group("operators"),
])
}
fn position_sensitive_flag(arg: Arg) -> Arg {
// Flags don't track the position of each occurrence, so we need to emulate flags with
// value-less options to get the same result
arg.num_args(0)
.value_parser(value_parser!(bool))
.default_missing_value("true")
.default_value("false")
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum Value {
Bool(bool),

27
third_party/rust/clap/examples/git-derive.md поставляемый
Просмотреть файл

@ -73,18 +73,31 @@ Default subcommand:
```console
$ git-derive stash -h
Usage: git-derive[EXE] stash [OPTIONS]
git-derive[EXE] stash <COMMAND>
Commands:
push
pop
apply
help Print this message or the help of the given subcommand(s)
git-derive[EXE] stash push [OPTIONS]
git-derive[EXE] stash pop [STASH]
git-derive[EXE] stash apply [STASH]
git-derive[EXE] stash help [COMMAND]...
Options:
-m, --message <MESSAGE>
-h, --help Print help
git-derive[EXE] stash push:
-m, --message <MESSAGE>
-h, --help Print help
git-derive[EXE] stash pop:
-h, --help Print help
[STASH]
git-derive[EXE] stash apply:
-h, --help Print help
[STASH]
git-derive[EXE] stash help:
Print this message or the help of the given subcommand(s)
[COMMAND]... Print help for the subcommand(s)
$ git-derive stash push -h
Usage: git-derive[EXE] stash push [OPTIONS]

Просмотреть файл

@ -76,6 +76,7 @@ impl std::fmt::Display for ColorWhen {
#[derive(Debug, Args)]
#[command(args_conflicts_with_subcommands = true)]
#[command(flatten_help = true)]
struct StashArgs {
#[command(subcommand)]
command: Option<StashCommands>,

27
third_party/rust/clap/examples/git.md поставляемый
Просмотреть файл

@ -71,18 +71,31 @@ Default subcommand:
```console
$ git stash -h
Usage: git[EXE] stash [OPTIONS]
git[EXE] stash <COMMAND>
Commands:
push
pop
apply
help Print this message or the help of the given subcommand(s)
git[EXE] stash push [OPTIONS]
git[EXE] stash pop [STASH]
git[EXE] stash apply [STASH]
git[EXE] stash help [COMMAND]...
Options:
-m, --message <MESSAGE>
-h, --help Print help
git[EXE] stash push:
-m, --message <MESSAGE>
-h, --help Print help
git[EXE] stash pop:
-h, --help Print help
[STASH]
git[EXE] stash apply:
-h, --help Print help
[STASH]
git[EXE] stash help:
Print this message or the help of the given subcommand(s)
[COMMAND]... Print help for the subcommand(s)
$ git stash push -h
Usage: git[EXE] stash push [OPTIONS]

1
third_party/rust/clap/examples/git.rs поставляемый
Просмотреть файл

@ -45,6 +45,7 @@ fn cli() -> Command {
.subcommand(
Command::new("stash")
.args_conflicts_with_subcommands(true)
.flatten_help(true)
.args(push_args())
.subcommand(Command::new("push").args(push_args()))
.subcommand(Command::new("pop").arg(arg!([STASH])))

1
third_party/rust/clap/examples/pacman.rs поставляемый
Просмотреть файл

@ -6,7 +6,6 @@ fn main() {
.version("5.2.1")
.subcommand_required(true)
.arg_required_else_help(true)
.author("Pacman Development Team")
// Query subcommand
//
// Only a few of its arguments are implemented below.

67
third_party/rust/clap/examples/repl-derive.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,67 @@
use std::io::Write;
use clap::{Parser, Subcommand};
fn main() -> Result<(), String> {
loop {
let line = readline()?;
let line = line.trim();
if line.is_empty() {
continue;
}
match respond(line) {
Ok(quit) => {
if quit {
break;
}
}
Err(err) => {
write!(std::io::stdout(), "{err}").map_err(|e| e.to_string())?;
std::io::stdout().flush().map_err(|e| e.to_string())?;
}
}
}
Ok(())
}
fn respond(line: &str) -> Result<bool, String> {
let args = shlex::split(line).ok_or("error: Invalid quoting")?;
let cli = Cli::try_parse_from(args).map_err(|e| e.to_string())?;
match cli.command {
Commands::Ping => {
write!(std::io::stdout(), "Pong").map_err(|e| e.to_string())?;
std::io::stdout().flush().map_err(|e| e.to_string())?;
}
Commands::Exit => {
write!(std::io::stdout(), "Exiting ...").map_err(|e| e.to_string())?;
std::io::stdout().flush().map_err(|e| e.to_string())?;
return Ok(true);
}
}
Ok(false)
}
#[derive(Debug, Parser)]
#[command(multicall = true)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Debug, Subcommand)]
enum Commands {
Ping,
Exit,
}
fn readline() -> Result<String, String> {
write!(std::io::stdout(), "$ ").map_err(|e| e.to_string())?;
std::io::stdout().flush().map_err(|e| e.to_string())?;
let mut buffer = String::new();
std::io::stdin()
.read_line(&mut buffer)
.map_err(|e| e.to_string())?;
Ok(buffer)
}

Просмотреть файл

@ -36,7 +36,7 @@ fn main() {
// Note, only flags can have multiple occurrences
match matches
.get_one::<u8>("debug")
.expect("Count's are defaulted")
.expect("Counts are defaulted")
{
0 => println!("Debug mode is off"),
1 => println!("Debug mode is kind of on"),

Просмотреть файл

@ -3,7 +3,6 @@ use clap::{arg, Command};
fn main() {
let matches = Command::new("MyApp")
.version("1.0")
.author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things")
.arg(arg!(--two <VALUE>).required(true))
.arg(arg!(--one <VALUE>).required(true))

Просмотреть файл

@ -10,21 +10,15 @@ Options:
-V, --version Print version
$ 03_02_option_mult
name: None
names: []
$ 03_02_option_mult --name bob
name: Some("bob")
names: ["bob"]
$ 03_02_option_mult --name=bob
name: Some("bob")
$ 03_02_option_mult --name bob --name john
names: ["bob", "john"]
$ 03_02_option_mult -n bob
name: Some("bob")
$ 03_02_option_mult -n=bob
name: Some("bob")
$ 03_02_option_mult -nbob
name: Some("bob")
$ 03_02_option_mult_derive --name bob --name=john -n tom -n=chris -nsteve
name: ["bob", "john", "tom", "chris", "steve"]
```

Просмотреть файл

@ -10,5 +10,11 @@ fn main() {
)
.get_matches();
println!("name: {:?}", matches.get_one::<String>("name"));
let args = matches
.get_many::<String>("name")
.unwrap_or_default()
.map(|v| v.as_str())
.collect::<Vec<_>>();
println!("names: {:?}", &args);
}

Просмотреть файл

@ -12,7 +12,7 @@ impl ValueEnum for Mode {
&[Mode::Fast, Mode::Slow]
}
fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
fn to_possible_value(&self) -> Option<PossibleValue> {
Some(match self {
Mode::Fast => PossibleValue::new("fast").help("Run swiftly"),
Mode::Slow => PossibleValue::new("slow").help("Crawl slowly but steadily"),

Просмотреть файл

@ -3,7 +3,7 @@ use std::path::PathBuf;
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
/// Optional name to operate on
name: Option<String>,

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
#[command(next_line_help = true)]
struct Cli {
#[arg(long)]

Просмотреть файл

@ -2,7 +2,6 @@ use clap::Parser;
#[derive(Parser)]
#[command(name = "MyApp")]
#[command(author = "Kevin K. <kbknapp@gmail.com>")]
#[command(version = "1.0")]
#[command(about = "Does awesome things", long_about = None)]
struct Cli {

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)] // Read from `Cargo.toml`
#[command(version, about, long_about = None)] // Read from `Cargo.toml`
struct Cli {
#[arg(long)]
two: String,

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
#[arg(short, long)]
verbose: bool,

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
#[arg(short, long, action = clap::ArgAction::Count)]
verbose: u8,

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
#[arg(short, long)]
name: Option<String>,

Просмотреть файл

@ -15,16 +15,10 @@ name: []
$ 03_02_option_mult_derive --name bob
name: ["bob"]
$ 03_02_option_mult_derive --name=bob
name: ["bob"]
$ 03_02_option_mult_derive --name bob --name john
name: ["bob", "john"]
$ 03_02_option_mult_derive -n bob
name: ["bob"]
$ 03_02_option_mult_derive -n=bob
name: ["bob"]
$ 03_02_option_mult_derive -nbob
name: ["bob"]
$ 03_02_option_mult_derive --name bob --name=john -n tom -n=chris -nsteve
name: ["bob", "john", "tom", "chris", "steve"]
```

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
#[arg(short, long)]
name: Vec<String>,

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
name: Option<String>,
}

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
name: Vec<String>,
}

Просмотреть файл

@ -1,7 +1,7 @@
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
#[command(subcommand)]
@ -21,7 +21,7 @@ fn main() {
// matches just as you would the top level cmd
match &cli.command {
Commands::Add { name } => {
println!("'myapp add' was used, name is: {name:?}")
println!("'myapp add' was used, name is: {name:?}");
}
}
}

Просмотреть файл

@ -1,7 +1,7 @@
use clap::{Args, Parser, Subcommand};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
#[command(subcommand)]
@ -26,7 +26,7 @@ fn main() {
// matches just as you would the top level cmd
match &cli.command {
Commands::Add(name) => {
println!("'myapp add' was used, name is: {:?}", name.name)
println!("'myapp add' was used, name is: {:?}", name.name);
}
}
}

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
#[arg(default_value_t = 2020)]
port: u16,

Просмотреть файл

@ -1,7 +1,7 @@
use clap::{Parser, ValueEnum};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
/// What mode to run the program in
#[arg(value_enum)]

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
/// Network port to use
#[arg(value_parser = clap::value_parser!(u16).range(1..))]

Просмотреть файл

@ -3,7 +3,7 @@ use std::ops::RangeInclusive;
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
/// Network port to use
#[arg(value_parser = port_in_range)]

Просмотреть файл

@ -1,7 +1,7 @@
use clap::{Args, Parser};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
#[command(flatten)]
vers: Vers,

Просмотреть файл

@ -2,7 +2,7 @@ use clap::error::ErrorKind;
use clap::{CommandFactory, Parser};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
/// set version manually
#[arg(long, value_name = "VER")]

Просмотреть файл

@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(version, about, long_about = None)]
struct Cli {
/// Network port to use
port: u16,
@ -16,5 +16,5 @@ fn main() {
#[test]
fn verify_cli() {
use clap::CommandFactory;
Cli::command().debug_assert()
Cli::command().debug_assert();
}

Просмотреть файл

@ -60,7 +60,7 @@ where
mod foreign_crate {
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum LogLevel {
pub(crate) enum LogLevel {
Trace,
Debug,
Info,

4
third_party/rust/clap/src/_cookbook/mod.rs поставляемый
Просмотреть файл

@ -15,6 +15,7 @@
//! - Topics:
//! - Subcommands
//! - Cargo plugins
//! - custom terminal [styles][crate::Command::styles] (colors)
//!
//! find-like interface: [builder][find]
//! - Topics:
@ -43,7 +44,7 @@
//! - Topics:
//! - Subcommands
//!
//! repl: [builder][repl]
//! repl: [builder][repl], [derive][repl_derive]
//! - Topics:
//! - Read-Eval-Print Loops / Custom command lines
@ -58,4 +59,5 @@ pub mod multicall_busybox;
pub mod multicall_hostname;
pub mod pacman;
pub mod repl;
pub mod repl_derive;
pub mod typed_derive;

4
third_party/rust/clap/src/_cookbook/repl_derive.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,4 @@
//! # Example: REPL (Derive API)
//!
//! ```rust
#![doc = include_str!("../../examples/repl-derive.rs")]

Просмотреть файл

@ -22,4 +22,4 @@
use crate::builder::*;
pub use super::chapter_1 as next;
pub use crate::_tutorial as table_of_contents;
pub use crate::_derive::_tutorial as table_of_contents;

Просмотреть файл

@ -8,7 +8,7 @@
//!
#![doc = include_str!("../../../examples/tutorial_derive/02_apps.md")]
//!
//! You can use [`#[command(author, version, about)]` attribute defaults][super#command-attributes] on the struct to fill these fields in from your `Cargo.toml` file.
//! You can use [`#[command(version, about)]` attribute defaults][super#command-attributes] on the struct to fill these fields in from your `Cargo.toml` file.
//!
//! ```rust
#![doc = include_str!("../../../examples/tutorial_derive/02_crate.rs")]
@ -26,4 +26,4 @@ use crate::builder::*;
pub use super::chapter_0 as previous;
pub use super::chapter_2 as next;
pub use crate::_tutorial as table_of_contents;
pub use crate::_derive::_tutorial as table_of_contents;

Просмотреть файл

@ -100,4 +100,4 @@ use crate::builder::*;
pub use super::chapter_1 as previous;
pub use super::chapter_3 as next;
pub use crate::_tutorial as table_of_contents;
pub use crate::_derive::_tutorial as table_of_contents;

Просмотреть файл

@ -75,4 +75,4 @@ use crate::builder::*;
pub use super::chapter_2 as previous;
pub use super::chapter_4 as next;
pub use crate::_tutorial as table_of_contents;
pub use crate::_derive::_tutorial as table_of_contents;

Просмотреть файл

@ -12,4 +12,4 @@ use crate::builder::*;
pub use super::chapter_3 as previous;
pub use super::chapter_5 as next;
pub use crate::_tutorial as table_of_contents;
pub use crate::_derive::_tutorial as table_of_contents;

Просмотреть файл

@ -11,4 +11,4 @@
use crate::builder::*;
pub use super::chapter_4 as previous;
pub use crate::_tutorial as table_of_contents;
pub use crate::_derive::_tutorial as table_of_contents;

40
third_party/rust/clap/src/_derive/mod.rs поставляемый
Просмотреть файл

@ -148,6 +148,7 @@
//! - `author [= <expr>]`: [`Command::author`][crate::Command::author]
//! - When not present: no author set
//! - Without `<expr>`: defaults to [crate `authors`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field)
//! - **NOTE:** A custom [`help_template`][crate::Command::help_template] is needed for author to show up.
//! - `about [= <expr>]`: [`Command::about`][crate::Command::about]
//! - When not present: [Doc comment summary](#doc-comments)
//! - Without `<expr>`: [crate `description`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-description-field) ([`Parser`][crate::Parser] container)
@ -189,6 +190,9 @@
//! [`Subcommand`][crate::Subcommand])
//! - When `Option<T>`, the subcommand becomes optional
//!
//! See [Configuring the Parser][_tutorial::chapter_1] and
//! [Subcommands][_tutorial::chapter_2#subcommands] from the tutorial.
//!
//! ### ArgGroup Attributes
//!
//! These correspond to the [`ArgGroup`][crate::ArgGroup] which is implicitly created for each
@ -203,12 +207,18 @@
//! - `skip [= <expr>]`: Ignore this field, filling in with `<expr>`
//! - Without `<expr>`: fills the field with `Default::default()`
//!
//! Note:
//! - For `struct`s, [`multiple = true`][crate::ArgGroup::multiple] is implied
//! - `enum` support is tracked at [#2621](https://github.com/clap-rs/clap/issues/2621)
//!
//! See [Argument Relations][_tutorial::chapter_3#argument-relations] from the tutorial.
//!
//! ### Arg Attributes
//!
//! These correspond to a [`Arg`][crate::Arg].
//!
//! **Raw attributes:** Any [`Arg` method][crate::Arg] can also be used as an attribute, see [Terminology](#terminology) for syntax.
//! - e.g. `#[arg(max_values(3))]` would translate to `arg.max_values(3)`
//! - e.g. `#[arg(num_args(..=3))]` would translate to `arg.num_args(..=3)`
//!
//! **Magic attributes**:
//! - `id = <expr>`: [`Arg::id`][crate::Arg::id]
@ -252,12 +262,17 @@
//! - Requires field arg to be of type `Vec<T>` and `T` to implement `std::convert::Into<OsString>` or `#[arg(value_enum)]`
//! - `<expr>` must implement `IntoIterator<T>`
//!
//! See [Adding Arguments][_tutorial::chapter_2] and [Validation][_tutorial::chapter_3] from the
//! tutorial.
//!
//! ### ValueEnum Attributes
//!
//! - `rename_all = <string_literal>`: Override default field / variant name case conversion for [`PossibleValue::new`][crate::builder::PossibleValue]
//! - When not present: `"kebab-case"`
//! - Available values: `"camelCase"`, `"kebab-case"`, `"PascalCase"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"lower"`, `"UPPER"`, `"verbatim"`
//!
//! See [Enumerated values][_tutorial::chapter_3#enumerated-values] from the tutorial.
//!
//! ### Possible Value Attributes
//!
//! These correspond to a [`PossibleValue`][crate::builder::PossibleValue].
@ -276,15 +291,17 @@
//!
//! `clap` assumes some intent based on the type used:
//!
//! | Type | Effect | Implies |
//! |---------------------|--------------------------------------|-------------------------------------------------------------|
//! | `()` | user-defined | `.action(ArgAction::Set).required(false)` |
//! | `bool` | flag | `.action(ArgAction::SetTrue)` |
//! | `Option<T>` | optional argument | `.action(ArgAction::Set).required(false)` |
//! | `Option<Option<T>>` | optional value for optional argument | `.action(ArgAction::Set).required(false).num_args(0..=1)` |
//! | `T` | required argument | `.action(ArgAction::Set).required(!has_default)` |
//! | `Vec<T>` | `0..` occurrences of argument | `.action(ArgAction::Append).required(false)` |
//! | `Option<Vec<T>>` | `0..` occurrences of argument | `.action(ArgAction::Append).required(false)` |
//! | Type | Effect | Implies | Notes |
//! |-----------------------|------------------------------------------------------|-------------------------------------------------------------|-------|
//! | `()` | user-defined | `.action(ArgAction::Set).required(false)` | |
//! | `bool` | flag | `.action(ArgAction::SetTrue)` | |
//! | `Option<T>` | optional argument | `.action(ArgAction::Set).required(false)` | |
//! | `Option<Option<T>>` | optional value for optional argument | `.action(ArgAction::Set).required(false).num_args(0..=1)` | |
//! | `T` | required argument | `.action(ArgAction::Set).required(!has_default)` | |
//! | `Vec<T>` | `0..` occurrences of argument | `.action(ArgAction::Append).required(false)` | |
//! | `Option<Vec<T>>` | `0..` occurrences of argument | `.action(ArgAction::Append).required(false)` | |
//! | `Vec<Vec<T>>` | `0..` occurrences of argument, grouped by occurrence | `.action(ArgAction::Append).required(false)` | requires `unstable-v5` |
//! | `Option<Vec<Vec<T>>>` | `0..` occurrences of argument, grouped by occurrence | `.action(ArgAction::Append).required(false)` | requires `unstable-v5` |
//!
//! In addition, [`.value_parser(value_parser!(T))`][crate::value_parser!] is called for each
//! field.
@ -294,8 +311,9 @@
//! - To force any inferred type (like `Vec<T>`) to be treated as `T`, you can refer to the type
//! by another means, like using `std::vec::Vec` instead of `Vec`. For improving this, see
//! [#4626](https://github.com/clap-rs/clap/issues/4626).
//! - `Option<Vec<T>>` will be `None` instead of `vec![]` if no arguments are provided.
//! - `Option<Vec<T>>` and `Option<Vec<Vec<T>>` will be `None` instead of `vec![]` if no arguments are provided.
//! - This gives the user some flexibility in designing their argument, like with `num_args(0..)`
//! - `Vec<Vec<T>>` will need [`Arg::num_args`][crate::Arg::num_args] set to be meaningful
//!
//! ## Doc Comments
//!

6
third_party/rust/clap/src/_faq.rs поставляемый
Просмотреть файл

@ -31,14 +31,14 @@
//!
//! The benefits of integrating `structopt` and `clap` are:
//! - Easier cross-linking in documentation
//! - [Documentation parity](../examples)
//! - Documentation parity
//! - Tighter design feedback loop, ensuring all new features are designed with
//! derives in mind and easier to change `clap` in response to `structopt` bugs.
//! - Clearer endorsement of `structopt`
//!
//! See also
//! - [`clap` v3 CHANGELOG](../CHANGELOG.md#300---2021-12-31)
//! - [`structopt` migration guide](../CHANGELOG.md#migrate-structopt)
//! - [`clap` v3 CHANGELOG](https://github.com/clap-rs/clap/blob/v3-master/CHANGELOG.md#300---2021-12-31)
//! - [`structopt` migration guide](https://github.com/clap-rs/clap/blob/v3-master/CHANGELOG.md#migrate-structopt)
//!
//! #### What are some reasons to use `clap`? (The Pitch)
//!

29
third_party/rust/clap/src/_features.rs поставляемый
Просмотреть файл

@ -4,25 +4,26 @@
//!
//! #### Default Features
//!
//! * **std**: _Not Currently Used._ Placeholder for supporting `no_std` environments in a backwards compatible manner.
//! * **color**: Turns on colored error messages.
//! * **help**: Auto-generate help output
//! * **usage**: Auto-generate usage
//! * **error-context**: Include contextual information for errors (which arg failed, etc)
//! * **suggestions**: Turns on the `Did you mean '--myoption'?` feature for when users make typos.
//! * `std`: _Not Currently Used._ Placeholder for supporting `no_std` environments in a backwards compatible manner.
//! * `color`: Turns on terminal styling of help and error messages. See
//! [`Command::styles`][crate::Command::styles] to customize this.
//! * `help`: Auto-generate help output
//! * `usage`: Auto-generate usage
//! * `error-context`: Include contextual information for errors (which arg failed, etc)
//! * `suggestions`: Turns on the `Did you mean '--myoption'?` feature for when users make typos.
//!
//! #### Optional features
//!
//! * **deprecated**: Guided experience to prepare for next breaking release (at different stages of development, this may become default)
//! * **derive**: Enables the custom derive (i.e. `#[derive(Parser)]`). Without this you must use one of the other methods of creating a `clap` CLI listed above.
//! * **cargo**: Turns on macros that read values from [`CARGO_*` environment variables](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates).
//! * **env**: Turns on the usage of environment variables during parsing.
//! * **unicode**: Turns on support for unicode characters (including emoji) in arguments and help messages.
//! * **wrap_help**: Turns on the help text wrapping feature, based on the terminal size.
//! * **string**: Allow runtime generated strings (e.g. with [`Str`][crate::builder::Str]).
//! * `deprecated`: Guided experience to prepare for next breaking release (at different stages of development, this may become default)
//! * `derive`: Enables the custom derive (i.e. `#[derive(Parser)]`). Without this you must use one of the other methods of creating a `clap` CLI listed above.
//! * `cargo`: Turns on macros that read values from [`CARGO_*` environment variables](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates).
//! * `env`: Turns on the usage of environment variables during parsing.
//! * `unicode`: Turns on support for unicode characters (including emoji) in arguments and help messages.
//! * ``wrap_help``: Turns on the help text wrapping feature, based on the terminal size.
//! * `string`: Allow runtime generated strings (e.g. with [`Str`][crate::builder::Str]).
//!
//! #### Experimental features
//!
//! **Warning:** These may contain breaking changes between minor releases.
//!
//! * **unstable-v5**: Preview features which will be stable on the v5.0 release
//! * `unstable-v5`: Preview features which will be stable on the v5.0 release

Просмотреть файл

@ -15,12 +15,12 @@ fn main() {
#[cfg(feature = "color")]
{
use clap::builder::styling;
let styles = styling::Styles::styled()
.header(styling::AnsiColor::Green.on_default() | styling::Effects::BOLD)
.usage(styling::AnsiColor::Green.on_default() | styling::Effects::BOLD)
.literal(styling::AnsiColor::Blue.on_default() | styling::Effects::BOLD)
const STYLES: styling::Styles = styling::Styles::styled()
.header(styling::AnsiColor::Green.on_default().bold())
.usage(styling::AnsiColor::Green.on_default().bold())
.literal(styling::AnsiColor::Blue.on_default().bold())
.placeholder(styling::AnsiColor::Cyan.on_default());
cmd = cmd.styles(styles);
cmd = cmd.styles(STYLES);
}
cmd.get_matches();
}

29
third_party/rust/clap/src/lib.rs поставляемый
Просмотреть файл

@ -11,6 +11,8 @@
//! - [Cookbook][_cookbook]
//! - [FAQ][_faq]
//! - [Discussions](https://github.com/clap-rs/clap/discussions)
//! - [CHANGELOG](https://github.com/clap-rs/clap/blob/v4.5.16/CHANGELOG.md) (includes major version migration
//! guides)
//!
//! ## Aspirations
//!
@ -24,7 +26,7 @@
//! - Leverage feature flags to keep to one active branch
//! - Being under [WG-CLI](https://github.com/rust-cli/team/) to increase the bus factor
//! - We follow semver and will wait about 6-9 months between major breaking changes
//! - We will support the last two minor Rust releases (MSRV, currently 1.70.0)
//! - We will support the last two minor Rust releases (MSRV, currently 1.74)
//!
//! While these aspirations can be at odds with fast build times and low binary
//! size, we will still strive to keep these reasonable for the flexibility you
@ -62,7 +64,7 @@
//! - [clap_complete](https://crates.io/crates/clap_complete) for shell completion support
//!
//! CLI Helpers
//! - [cio](https://crates.io/crates/clio) for reading/writing to files specified as arguments
//! - [clio](https://crates.io/crates/clio) for reading/writing to files specified as arguments
//! - [clap-verbosity-flag](https://crates.io/crates/clap-verbosity-flag)
//! - [clap-cargo](https://crates.io/crates/clap-cargo)
//! - [concolor-clap](https://crates.io/crates/concolor-clap)
@ -76,30 +78,17 @@
//! - [Command-line Apps for Rust](https://rust-cli.github.io/book/index.html) book
//!
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc(html_logo_url = "https://raw.githubusercontent.com/clap-rs/clap/master/assets/clap.png")]
#![warn(
missing_docs,
missing_debug_implementations,
missing_copy_implementations,
trivial_casts,
unused_allocation,
trivial_numeric_casts,
clippy::single_char_pattern
)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![forbid(unsafe_code)]
// HACK https://github.com/rust-lang/rust-clippy/issues/7290
#![allow(clippy::single_component_path_imports)]
#![allow(clippy::branches_sharing_code)]
// Doesn't allow for debug statements, etc to be unique
#![allow(clippy::if_same_then_else)]
// Breaks up parallelism that clarifies intent
#![allow(clippy::collapsible_else_if)]
#![warn(missing_docs)]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
pub use clap_builder::*;
#[cfg(feature = "derive")]
#[doc(hidden)]
pub use clap_derive::{self, *};
pub use clap_derive::{self, Args, Parser, Subcommand, ValueEnum};
#[cfg(feature = "unstable-doc")]
pub mod _cookbook;

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

118
third_party/rust/clap_builder/Cargo.toml поставляемый
Просмотреть файл

@ -11,9 +11,10 @@
[package]
edition = "2021"
rust-version = "1.70.0"
rust-version = "1.74"
name = "clap_builder"
version = "4.4.5"
version = "4.5.15"
build = false
include = [
"build.rs",
"src/**/*",
@ -23,6 +24,10 @@ include = [
"benches/**/*",
"examples/**/*",
]
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "A simple to use, efficient, and full-featured Command Line Argument Parser"
readme = "README.md"
keywords = [
@ -56,24 +61,26 @@ shared-version = true
tag-name = "v{{version}}"
[lib]
name = "clap_builder"
path = "src/lib.rs"
bench = false
[dependencies.anstream]
version = "0.5.0"
version = "0.6.7"
optional = true
[dependencies.anstyle]
version = "1.0.0"
version = "1.0.8"
[dependencies.backtrace]
version = "0.3.67"
version = "0.3.73"
optional = true
[dependencies.clap_lex]
version = "0.5.0"
version = "0.7.0"
[dependencies.strsim]
version = "0.10.0"
version = "0.11.0"
optional = true
[dependencies.terminal_size]
@ -89,35 +96,11 @@ version = "0.1.9"
optional = true
[dev-dependencies.color-print]
version = "0.3.4"
[dev-dependencies.humantime]
version = "2.1.0"
[dev-dependencies.rustversion]
version = "1.0.14"
[dev-dependencies.shlex]
version = "1.1.0"
[dev-dependencies.snapbox]
version = "0.4.12"
version = "0.3.6"
[dev-dependencies.static_assertions]
version = "1.1.0"
[dev-dependencies.trybuild]
version = "1.0.83"
[dev-dependencies.trycmd]
version = "0.14.17"
features = [
"color-auto",
"diff",
"examples",
]
default-features = false
[dev-dependencies.unic-emoji-char]
version = "0.9.0"
@ -153,7 +136,9 @@ unstable-doc = [
"env",
"unicode",
"string",
"unstable-ext",
]
unstable-ext = []
unstable-styles = ["color"]
unstable-v5 = ["deprecated"]
usage = []
@ -161,3 +146,72 @@ wrap_help = [
"help",
"dep:terminal_size",
]
[lints.clippy]
assigning_clones = "allow"
blocks_in_conditions = "allow"
bool_assert_comparison = "allow"
branches_sharing_code = "allow"
checked_conversions = "warn"
collapsible_else_if = "allow"
create_dir = "warn"
dbg_macro = "warn"
debug_assert_with_mut_call = "warn"
doc_markdown = "warn"
empty_enum = "warn"
enum_glob_use = "warn"
expl_impl_clone_on_copy = "warn"
explicit_deref_methods = "warn"
explicit_into_iter_loop = "warn"
fallible_impl_from = "warn"
filter_map_next = "warn"
flat_map_option = "warn"
float_cmp_const = "warn"
fn_params_excessive_bools = "warn"
from_iter_instead_of_collect = "warn"
if_same_then_else = "allow"
implicit_clone = "warn"
imprecise_flops = "warn"
inconsistent_struct_constructor = "warn"
inefficient_to_string = "warn"
infinite_loop = "warn"
invalid_upcast_comparisons = "warn"
large_digit_groups = "warn"
large_stack_arrays = "warn"
large_types_passed_by_value = "warn"
let_and_return = "allow"
linkedlist = "warn"
lossy_float_literal = "warn"
macro_use_imports = "warn"
mem_forget = "warn"
multiple_bound_locations = "allow"
mutex_integer = "warn"
needless_continue = "warn"
needless_for_each = "warn"
negative_feature_names = "warn"
path_buf_push_overwrite = "warn"
ptr_as_ptr = "warn"
rc_mutex = "warn"
redundant_feature_names = "warn"
ref_option_ref = "warn"
rest_pat_in_fully_bound_structs = "warn"
same_functions_in_if_condition = "warn"
self_named_module_files = "warn"
semicolon_if_nothing_returned = "warn"
string_add_assign = "warn"
string_lit_as_bytes = "warn"
todo = "warn"
trait_duplication_in_bounds = "warn"
verbose_file_reads = "warn"
zero_sized_map_values = "warn"
[lints.rust]
unreachable_pub = "warn"
unsafe_op_in_unsafe_fn = "warn"
unused_lifetimes = "warn"
unused_macro_rules = "warn"
unused_qualifications = "warn"
[lints.rust.rust_2018_idioms]
level = "warn"
priority = -1

2
third_party/rust/clap_builder/README.md поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
# clap_builder
# `clap_builder`
Builder implementation for clap.

Просмотреть файл

@ -194,7 +194,7 @@ pub enum ArgAction {
/// );
/// ```
SetFalse,
/// When encountered, increment a `u8` counter
/// When encountered, increment a `u8` counter starting from `0`.
///
/// If no [`default_value`][super::Arg::default_value] is set, it will be `0`.
///

Просмотреть файл

@ -57,6 +57,7 @@ pub(crate) enum AppSettings {
SubcommandsNegateReqs,
ArgsNegateSubcommands,
SubcommandPrecedenceOverArg,
FlattenHelp,
ArgRequiredElseHelp,
NextLineHelp,
DisableColoredHelp,

Просмотреть файл

@ -11,6 +11,9 @@ use std::{
// Internal
use super::{ArgFlags, ArgSettings};
#[cfg(feature = "unstable-ext")]
use crate::builder::ext::Extension;
use crate::builder::ext::Extensions;
use crate::builder::ArgPredicate;
use crate::builder::IntoResettable;
use crate::builder::OsStr;
@ -85,7 +88,7 @@ pub struct Arg {
pub(crate) terminator: Option<Str>,
pub(crate) index: Option<usize>,
pub(crate) help_heading: Option<Option<Str>>,
pub(crate) value_hint: Option<ValueHint>,
pub(crate) ext: Extensions,
}
/// # Basic API
@ -510,10 +513,10 @@ impl Arg {
self
}
/// This is a "VarArg" and everything that follows should be captured by it, as if the user had
/// This is a "var arg" and everything that follows should be captured by it, as if the user had
/// used a `--`.
///
/// **NOTE:** To start the trailing "VarArg" on unknown flags (and not just a positional
/// **NOTE:** To start the trailing "var arg" on unknown flags (and not just a positional
/// value), set [`allow_hyphen_values`][Arg::allow_hyphen_values]. Either way, users still
/// have the option to explicitly escape ambiguous arguments with `--`.
///
@ -869,13 +872,21 @@ impl Arg {
self.settings.unset(setting);
self
}
/// Extend [`Arg`] with [`ArgExt`] data
#[cfg(feature = "unstable-ext")]
#[allow(clippy::should_implement_trait)]
pub fn add<T: ArgExt + Extension>(mut self, tagged: T) -> Self {
self.ext.set(tagged);
self
}
}
/// # Value Handling
impl Arg {
/// Specify how to react to an argument when parsing it.
///
/// [ArgAction][crate::ArgAction] controls things like
/// [`ArgAction`] controls things like
/// - Overwriting previous values with new ones
/// - Appending new values to all previous ones
/// - Counting how many times a flag occurs
@ -997,7 +1008,7 @@ impl Arg {
/// - It reaches the [`Arg::value_terminator`] if set
///
/// Alternatively,
/// - Use a delimiter between values with [Arg::value_delimiter]
/// - Use a delimiter between values with [`Arg::value_delimiter`]
/// - Require a flag occurrence per value with [`ArgAction::Append`]
/// - Require positional arguments to appear after `--` with [`Arg::last`]
///
@ -1018,7 +1029,7 @@ impl Arg {
/// assert_eq!(m.get_one::<String>("mode").unwrap(), "fast");
/// ```
///
/// Flag/option hybrid (see also [default_missing_value][Arg::default_missing_value])
/// Flag/option hybrid (see also [`default_missing_value`][Arg::default_missing_value])
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
@ -1260,7 +1271,7 @@ impl Arg {
/// Provide the shell a hint about how to complete this argument.
///
/// See [`ValueHint`][crate::ValueHint] for more information.
/// See [`ValueHint`] for more information.
///
/// **NOTE:** implicitly sets [`Arg::action(ArgAction::Set)`].
///
@ -1291,7 +1302,15 @@ impl Arg {
/// ```
#[must_use]
pub fn value_hint(mut self, value_hint: impl IntoResettable<ValueHint>) -> Self {
self.value_hint = value_hint.into_resettable().into_option();
// HACK: we should use `Self::add` and `Self::remove` to type-check that `ArgExt` is used
match value_hint.into_resettable().into_option() {
Some(value_hint) => {
self.ext.set(value_hint);
}
None => {
self.ext.remove::<ValueHint>();
}
}
self
}
@ -1519,11 +1538,8 @@ impl Arg {
/// Allow grouping of multiple values via a delimiter.
///
/// i.e. should `--option=val1,val2,val3` be parsed as three values (`val1`, `val2`,
/// and `val3`) or as a single value (`val1,val2,val3`). Defaults to using `,` (comma) as the
/// value delimiter for all arguments that accept values (options and positional arguments)
///
/// **NOTE:** implicitly sets [`Arg::action(ArgAction::Set)`]
/// i.e. allow values (`val1,val2,val3`) to be parsed as three values (`val1`, `val2`,
/// and `val3`) instead of one value (`val1,val2,val3`).
///
/// # Examples
///
@ -1617,7 +1633,7 @@ impl Arg {
/// ```
///
/// Will result in everything after `--` to be considered one raw argument. This behavior
/// may not be exactly what you are expecting and using [`crate::Command::trailing_var_arg`]
/// may not be exactly what you are expecting and using [`Arg::trailing_var_arg`]
/// may be more appropriate.
///
/// **NOTE:** Implicitly sets [`Arg::action(ArgAction::Set)`] [`Arg::num_args(1..)`],
@ -1741,7 +1757,7 @@ impl Arg {
///
/// This configuration option is often used to give the user a shortcut and allow them to
/// efficiently specify an option argument without requiring an explicitly value. The `--color`
/// argument is a common example. By, supplying an default, such as `default_missing_value("always")`,
/// argument is a common example. By supplying a default, such as `default_missing_value("always")`,
/// the user can quickly just add `--color` to the command line to produce the desired color output.
///
/// **NOTE:** using this configuration option requires the use of the
@ -3641,8 +3657,8 @@ impl Arg {
/// only need to be set for one of the two arguments, they do not need to be set for each.
///
/// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments
/// (i.e. if A conflicts with B, defining A.conflicts_with(B) is sufficient. You do not
/// need to also do B.conflicts_with(A))
/// (i.e. if A conflicts with B, defining `A.conflicts_with(B)` is sufficient. You do not
/// need to also do `B.conflicts_with(A)`)
///
/// **NOTE:** [`Arg::conflicts_with_all(names)`] allows specifying an argument which conflicts with more than one argument.
///
@ -3701,8 +3717,8 @@ impl Arg {
/// only need to be set for one of the two arguments, they do not need to be set for each.
///
/// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments
/// (i.e. if A conflicts with B, defining A.conflicts_with(B) is sufficient. You do not need
/// need to also do B.conflicts_with(A))
/// (i.e. if A conflicts with B, defining `A.conflicts_with(B)` is sufficient. You do not need
/// need to also do `B.conflicts_with(A)`)
///
/// **NOTE:** [`Arg::exclusive(true)`] allows specifying an argument which conflicts with every other argument.
///
@ -3952,6 +3968,21 @@ impl Arg {
Some(longs)
}
/// Get hidden aliases for this argument, if any
#[inline]
pub fn get_aliases(&self) -> Option<Vec<&str>> {
if self.aliases.is_empty() {
None
} else {
Some(
self.aliases
.iter()
.filter_map(|(s, v)| if !*v { Some(s.as_str()) } else { None })
.collect(),
)
}
}
/// Get the names of possible values for this argument. Only useful for user
/// facing applications, such as building help messages or man files
pub fn get_possible_values(&self) -> Vec<PossibleValue> {
@ -3992,7 +4023,7 @@ impl Arg {
self.val_delim
}
/// Get the value terminator for this argument. The value_terminator is a value
/// Get the value terminator for this argument. The `value_terminator` is a value
/// that terminates parsing of multi-valued arguments.
#[inline]
pub fn get_value_terminator(&self) -> Option<&Str> {
@ -4007,7 +4038,8 @@ impl Arg {
/// Get the value hint of this argument
pub fn get_value_hint(&self) -> ValueHint {
self.value_hint.unwrap_or_else(|| {
// HACK: we should use `Self::add` and `Self::remove` to type-check that `ArgExt` is used
self.ext.get::<ValueHint>().copied().unwrap_or_else(|| {
if self.is_takes_value_set() {
let type_id = self.get_value_parser().type_id();
if type_id == AnyValueId::of::<std::path::PathBuf>() {
@ -4078,7 +4110,9 @@ impl Arg {
}
pub(crate) fn is_takes_value_set(&self) -> bool {
self.get_action().takes_values()
self.get_num_args()
.unwrap_or_else(|| 1.into())
.takes_values()
}
/// Report whether [`Arg::allow_hyphen_values`] is set
@ -4092,8 +4126,8 @@ impl Arg {
}
/// Behavior when parsing the argument
pub fn get_action(&self) -> &super::ArgAction {
const DEFAULT: super::ArgAction = super::ArgAction::Set;
pub fn get_action(&self) -> &ArgAction {
const DEFAULT: ArgAction = ArgAction::Set;
self.action.as_ref().unwrap_or(&DEFAULT)
}
@ -4193,6 +4227,18 @@ impl Arg {
pub fn is_ignore_case_set(&self) -> bool {
self.is_set(ArgSettings::IgnoreCase)
}
/// Access an [`ArgExt`]
#[cfg(feature = "unstable-ext")]
pub fn get<T: ArgExt + Extension>(&self) -> Option<&T> {
self.ext.get::<T>()
}
/// Remove an [`ArgExt`]
#[cfg(feature = "unstable-ext")]
pub fn remove<T: ArgExt + Extension>(mut self) -> Option<T> {
self.ext.remove::<T>()
}
}
/// # Internally used only
@ -4200,7 +4246,7 @@ impl Arg {
pub(crate) fn _build(&mut self) {
if self.action.is_none() {
if self.num_vals == Some(ValueRange::EMPTY) {
let action = super::ArgAction::SetTrue;
let action = ArgAction::SetTrue;
self.action = Some(action);
} else {
let action =
@ -4209,9 +4255,9 @@ impl Arg {
//
// Bounded values are probably a group and the user should explicitly opt-in to
// Append
super::ArgAction::Append
ArgAction::Append
} else {
super::ArgAction::Set
ArgAction::Set
};
self.action = Some(action);
}
@ -4430,14 +4476,14 @@ impl Ord for Arg {
impl Eq for Arg {}
impl Display for Arg {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let plain = Styles::plain();
self.stylized(&plain, None).fmt(f)
}
}
impl fmt::Debug for Arg {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
let mut ds = f.debug_struct("Arg");
#[allow(unused_mut)]
@ -4467,8 +4513,8 @@ impl fmt::Debug for Arg {
.field("terminator", &self.terminator)
.field("index", &self.index)
.field("help_heading", &self.help_heading)
.field("value_hint", &self.value_hint)
.field("default_missing_vals", &self.default_missing_vals);
.field("default_missing_vals", &self.default_missing_vals)
.field("ext", &self.ext);
#[cfg(feature = "env")]
{
@ -4479,6 +4525,10 @@ impl fmt::Debug for Arg {
}
}
/// User-provided data that can be attached to an [`Arg`]
#[cfg(feature = "unstable-ext")]
pub trait ArgExt: Extension {}
// Flags
#[cfg(test)]
mod test {
@ -4517,7 +4567,7 @@ mod test {
.action(ArgAction::SetTrue);
f._build();
assert_eq!(f.to_string(), "--flag")
assert_eq!(f.to_string(), "--flag");
}
#[test]
@ -4540,7 +4590,7 @@ mod test {
f.short_aliases = vec![('b', true)];
f._build();
assert_eq!(f.to_string(), "-a")
assert_eq!(f.to_string(), "-a");
}
#[test]

Просмотреть файл

@ -236,7 +236,7 @@ impl ArgGroup {
/// // maybe we don't know which of the two flags was used...
/// assert!(m.contains_id("req_flags"));
/// ```
/// In this next example, we show the default behavior (i.e. `multiple(false)) which will throw
/// In this next example, we show the default behavior (i.e. `multiple(false)`) which will throw
/// an error if more than one of the args in the group was used.
///
/// ```rust
@ -585,7 +585,7 @@ mod test {
#[test]
fn arg_group_send_sync() {
fn foo<T: Send + Sync>(_: T) {}
foo(ArgGroup::new("test"))
foo(ArgGroup::new("test"));
}
#[test]

Просмотреть файл

@ -298,6 +298,45 @@ impl Command {
self
}
/// Allows one to mutate an [`ArgGroup`] after it's been added to a [`Command`].
///
/// # Panics
///
/// If the argument is undefined
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, arg, ArgGroup};
///
/// Command::new("foo")
/// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false))
/// .arg(arg!(--major "auto increase major"))
/// .arg(arg!(--minor "auto increase minor"))
/// .arg(arg!(--patch "auto increase patch"))
/// .group(ArgGroup::new("vers")
/// .args(["set-ver", "major", "minor","patch"])
/// .required(true))
/// .mut_group("vers", |a| a.required(false));
/// ```
#[must_use]
#[cfg_attr(debug_assertions, track_caller)]
pub fn mut_group<F>(mut self, arg_id: impl AsRef<str>, f: F) -> Self
where
F: FnOnce(ArgGroup) -> ArgGroup,
{
let id = arg_id.as_ref();
let index = self
.groups
.iter()
.position(|g| g.get_id() == id)
.unwrap_or_else(|| panic!("Group `{id}` is undefined"));
let a = self.groups.remove(index);
self.groups.push(f(a));
self
}
/// Allows one to mutate a [`Command`] after it's been added as a subcommand.
///
/// This can be useful for modifying auto-generated arguments of nested subcommands with
@ -408,7 +447,7 @@ impl Command {
/// ```
#[must_use]
pub fn groups(mut self, groups: impl IntoIterator<Item = impl Into<ArgGroup>>) -> Self {
for g in groups.into_iter() {
for g in groups {
self = self.group(g.into());
}
self
@ -506,7 +545,7 @@ impl Command {
/// that exhaustively test your CLI to ensure the asserts are evaluated, this will run those
/// asserts in a way convenient for running as a test.
///
/// **Note::** This will not help with asserts in [`ArgMatches`], those will need exhaustive
/// **Note:** This will not help with asserts in [`ArgMatches`], those will need exhaustive
/// testing of your CLI.
///
/// # Examples
@ -545,11 +584,11 @@ impl Command {
/// let mut cmd = Command::new("myprog");
/// let err = cmd.error(ErrorKind::InvalidValue, "Some failure case");
/// ```
pub fn error(&mut self, kind: ErrorKind, message: impl std::fmt::Display) -> Error {
pub fn error(&mut self, kind: ErrorKind, message: impl fmt::Display) -> Error {
Error::raw(kind, message).format(self)
}
/// Parse [`env::args_os`], exiting on failure.
/// Parse [`env::args_os`], [exiting][Error::exit] on failure.
///
/// # Panics
///
@ -571,7 +610,7 @@ impl Command {
self.get_matches_from(env::args_os())
}
/// Parse [`env::args_os`], exiting on failure.
/// Parse [`env::args_os`], [exiting][Error::exit] on failure.
///
/// Like [`Command::get_matches`] but doesn't consume the `Command`.
///
@ -592,7 +631,7 @@ impl Command {
/// [`env::args_os`]: std::env::args_os()
/// [`Command::get_matches`]: Command::get_matches()
pub fn get_matches_mut(&mut self) -> ArgMatches {
self.try_get_matches_from_mut(&mut env::args_os())
self.try_get_matches_from_mut(env::args_os())
.unwrap_or_else(|e| e.exit())
}
@ -631,7 +670,7 @@ impl Command {
self.try_get_matches_from(env::args_os())
}
/// Parse the specified arguments, exiting on failure.
/// Parse the specified arguments, [exiting][Error::exit] on failure.
///
/// **NOTE:** The first argument will be parsed as the binary name unless
/// [`Command::no_binary_name`] is used.
@ -746,7 +785,7 @@ impl Command {
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let mut raw_args = clap_lex::RawArgs::new(itr.into_iter());
let mut raw_args = clap_lex::RawArgs::new(itr);
let mut cursor = raw_args.cursor();
if self.settings.is_set(AppSettings::Multicall) {
@ -1070,7 +1109,7 @@ impl Command {
/// Replace prior occurrences of arguments rather than error
///
/// For any argument that would conflict with itself by default (e.g.
/// [`ArgAction::Set`][ArgAction::Set], it will now override itself.
/// [`ArgAction::Set`], it will now override itself.
///
/// This is the equivalent to saying the `foo` arg using [`Arg::overrides_with("foo")`] for all
/// defined arguments.
@ -1087,7 +1126,7 @@ impl Command {
}
}
/// Disables the automatic delimiting of values after `--` or when [`Command::trailing_var_arg`]
/// Disables the automatic delimiting of values after `--` or when [`Arg::trailing_var_arg`]
/// was used.
///
/// **NOTE:** The same thing can be done manually by setting the final positional argument to
@ -1118,6 +1157,8 @@ impl Command {
/// Sets when to color output.
///
/// To customize how the output is styled, see [`Command::styles`].
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// **NOTE:** Default behaviour is [`ColorChoice::Auto`].
@ -1158,13 +1199,13 @@ impl Command {
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, ColorChoice, builder::styling};
/// let styles = styling::Styles::styled()
/// .header(styling::AnsiColor::Green.on_default() | styling::Effects::BOLD)
/// .usage(styling::AnsiColor::Green.on_default() | styling::Effects::BOLD)
/// .literal(styling::AnsiColor::Blue.on_default() | styling::Effects::BOLD)
/// const STYLES: styling::Styles = styling::Styles::styled()
/// .header(styling::AnsiColor::Green.on_default().bold())
/// .usage(styling::AnsiColor::Green.on_default().bold())
/// .literal(styling::AnsiColor::Blue.on_default().bold())
/// .placeholder(styling::AnsiColor::Cyan.on_default());
/// Command::new("myprog")
/// .styles(styles)
/// .styles(STYLES)
/// .get_matches();
/// ```
#[cfg(feature = "color")]
@ -1244,12 +1285,41 @@ impl Command {
/// # use clap_builder as clap;
/// # use clap::{Command, error::ErrorKind};
/// let res = Command::new("myprog")
/// .version("1.0.0")
/// .disable_version_flag(true)
/// .try_get_matches_from(vec![
/// "myprog", "--version"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
/// ```
///
/// You can create a custom version flag with [`ArgAction::Version`]
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg, ArgAction, error::ErrorKind};
/// let mut cmd = Command::new("myprog")
/// .version("1.0.0")
/// // Remove the `-V` short flag
/// .disable_version_flag(true)
/// .arg(
/// Arg::new("version")
/// .long("version")
/// .action(ArgAction::Version)
/// .help("Print version")
/// );
///
/// let res = cmd.try_get_matches_from_mut(vec![
/// "myprog", "-V"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
///
/// let res = cmd.try_get_matches_from_mut(vec![
/// "myprog", "--version"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::DisplayVersion);
/// ```
#[inline]
pub fn disable_version_flag(self, yes: bool) -> Self {
@ -1329,6 +1399,35 @@ impl Command {
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
/// ```
///
/// You can create a custom help flag with [`ArgAction::Help`], [`ArgAction::HelpShort`], or
/// [`ArgAction::HelpLong`]
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg, ArgAction, error::ErrorKind};
/// let mut cmd = Command::new("myprog")
/// // Change help short flag to `?`
/// .disable_help_flag(true)
/// .arg(
/// Arg::new("help")
/// .short('?')
/// .long("help")
/// .action(ArgAction::Help)
/// .help("Print help")
/// );
///
/// let res = cmd.try_get_matches_from_mut(vec![
/// "myprog", "-h"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
///
/// let res = cmd.try_get_matches_from_mut(vec![
/// "myprog", "-?"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::DisplayHelp);
/// ```
#[inline]
pub fn disable_help_flag(self, yes: bool) -> Self {
if yes {
@ -1643,7 +1742,8 @@ impl Command {
/// Sets the program's description for the long help (`--help`).
///
/// If [`Command::about`] is not specified, this message will be displayed for `-h`.
/// If not set, [`Command::about`] will be used for long help in addition to short help
/// (`-h`).
///
/// **NOTE:** Only [`Command::about`] (short format) is used in completion
/// script generation in order to be concise.
@ -1695,7 +1795,8 @@ impl Command {
/// This is often used to describe how to use the arguments, caveats to be noted, or license
/// and contact information.
///
/// If [`Command::after_help`] is not specified, this message will be displayed for `-h`.
/// If not set, [`Command::after_help`] will be used for long help in addition to short help
/// (`-h`).
///
/// # Examples
///
@ -1738,7 +1839,8 @@ impl Command {
///
/// This is often used for header, copyright, or license information.
///
/// If [`Command::before_help`] is not specified, this message will be displayed for `-h`.
/// If not set, [`Command::before_help`] will be used for long help in addition to short help
/// (`-h`).
///
/// # Examples
///
@ -1991,6 +2093,21 @@ impl Command {
self
}
/// Flatten subcommand help into the current command's help
///
/// This shows a summary of subcommands within the usage and help for the current command, similar to
/// `git stash --help` showing information on `push`, `pop`, etc.
/// To see more information, a user can still pass `--help` to the individual subcommands.
#[inline]
#[must_use]
pub fn flatten_help(self, yes: bool) -> Self {
if yes {
self.setting(AppSettings::FlattenHelp)
} else {
self.unset_setting(AppSettings::FlattenHelp)
}
}
/// Set the default section heading for future args.
///
/// This will be used for any arg that hasn't had [`Arg::help_heading`] called.
@ -2105,7 +2222,7 @@ impl Command {
/// For example, imagine a CLI which has three positional arguments `[foo] [bar] [baz]...` where
/// `baz` accepts multiple values (similar to man `ARGS...` style training arguments).
///
/// With this setting the following invocations are posisble:
/// With this setting the following invocations are possible:
///
/// * `$ prog foo bar baz1 baz2 baz3`
/// * `$ prog foo -- baz1 baz2 baz3`
@ -2455,7 +2572,7 @@ impl Command {
#[must_use]
pub fn long_flag_aliases(mut self, names: impl IntoIterator<Item = impl Into<Str>>) -> Self {
for s in names {
self = self.long_flag_alias(s)
self = self.long_flag_alias(s);
}
self
}
@ -3277,6 +3394,20 @@ impl Command {
self.usage_name.as_deref()
}
#[inline]
#[cfg(feature = "usage")]
pub(crate) fn get_usage_name_fallback(&self) -> &str {
self.get_usage_name()
.unwrap_or_else(|| self.get_bin_name_fallback())
}
#[inline]
#[cfg(not(feature = "usage"))]
#[allow(dead_code)]
pub(crate) fn get_usage_name_fallback(&self) -> &str {
self.get_bin_name_fallback()
}
/// Get the name of the binary.
#[inline]
pub fn get_display_name(&self) -> Option<&str> {
@ -3289,6 +3420,12 @@ impl Command {
self.bin_name.as_deref()
}
/// Get the name of the binary.
#[inline]
pub(crate) fn get_bin_name_fallback(&self) -> &str {
self.bin_name.as_deref().unwrap_or_else(|| self.get_name())
}
/// Set binary name. Uses `&mut self` instead of `self`.
pub fn set_bin_name(&mut self, name: impl Into<String>) {
self.bin_name = Some(name.into());
@ -3306,6 +3443,13 @@ impl Command {
&self.name
}
/// Get all known names of the cmd (i.e. primary name and visible aliases).
pub fn get_name_and_visible_aliases(&self) -> Vec<&str> {
let mut names = vec![self.name.as_str()];
names.extend(self.get_visible_aliases());
names
}
/// Get the version of the cmd.
#[inline]
pub fn get_version(&self) -> Option<&str> {
@ -3352,6 +3496,12 @@ impl Command {
self.long_about.as_ref()
}
/// Get the custom section heading specified via [`Command::flatten_help`].
#[inline]
pub fn is_flatten_help_set(&self) -> bool {
self.is_set(AppSettings::FlattenHelp)
}
/// Get the custom section heading specified via [`Command::next_help_heading`].
///
/// [`Command::help_heading`]: Command::help_heading()
@ -3405,6 +3555,15 @@ impl Command {
self.long_flag_aliases.iter().map(|a| a.0.as_str())
}
/// Iterate through the *hidden* aliases for this subcommand.
#[inline]
pub fn get_aliases(&self) -> impl Iterator<Item = &str> + '_ {
self.aliases
.iter()
.filter(|(_, vis)| !*vis)
.map(|a| a.0.as_str())
}
#[inline]
pub(crate) fn is_set(&self, s: AppSettings) -> bool {
self.settings.is_set(s) || self.g_settings.is_set(s)
@ -3612,7 +3771,7 @@ impl Command {
// Subcommand_1.1.1 (contains Arg)
//
fn get_subcommands_containing(&self, arg: &Arg) -> Vec<&Self> {
let mut vec = std::vec::Vec::new();
let mut vec = Vec::new();
for idx in 0..self.subcommands.len() {
if self.subcommands[idx]
.args
@ -4454,7 +4613,7 @@ impl Command {
#[inline]
pub(crate) fn set(&mut self, s: AppSettings) {
self.settings.set(s)
self.settings.set(s);
}
#[inline]
@ -4518,7 +4677,7 @@ impl Command {
/// Iterate through all the names of all subcommands (not recursively), including aliases.
/// Used for suggestions.
pub(crate) fn all_subcommand_names(&self) -> impl Iterator<Item = &str> + Captures {
pub(crate) fn all_subcommand_names(&self) -> impl Iterator<Item = &str> + Captures<'_> {
self.get_subcommands().flat_map(|sc| {
let name = sc.get_name();
let aliases = sc.get_all_aliases();
@ -4561,7 +4720,7 @@ impl Command {
if !args.contains(n) {
if self.find(n).is_some() {
debug!("Command::unroll_args_in_group:iter: this is an arg");
args.push(n.clone())
args.push(n.clone());
} else {
debug!("Command::unroll_args_in_group:iter: this is a group");
g_vec.push(n);
@ -4592,7 +4751,7 @@ impl Command {
for r in arg.requires.iter().filter_map(&func) {
if let Some(req) = self.find(&r) {
if !req.requires.is_empty() {
r_vec.push(req.get_id())
r_vec.push(req.get_id());
}
}
args.push(r);
@ -4742,18 +4901,21 @@ impl From<&'_ Command> for Command {
}
impl fmt::Display for Command {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name)
}
}
#[allow(dead_code)] // atm dependent on features enabled
pub(crate) trait AppTag: crate::builder::ext::Extension {}
#[allow(dead_code)] // atm dependent on features enabled
#[derive(Default, Copy, Clone, Debug)]
struct TermWidth(usize);
impl AppTag for TermWidth {}
#[allow(dead_code)] // atm dependent on features enabled
#[derive(Default, Copy, Clone, Debug)]
struct MaxTermWidth(usize);

Просмотреть файл

@ -370,7 +370,7 @@ pub(crate) fn assert_app(cmd: &Command) {
"Command {}: {}",
cmd.get_name(),
"`{bin}` template variable was removed in clap5, use `{name}` instead"
)
);
}
cmd._panic_on_missing_help(cmd.is_help_expected_set());
@ -398,50 +398,46 @@ enum Flag<'a> {
}
impl PartialEq for Flag<'_> {
fn eq(&self, other: &Flag) -> bool {
fn eq(&self, other: &Flag<'_>) -> bool {
self.cmp(other) == Ordering::Equal
}
}
impl PartialOrd for Flag<'_> {
fn partial_cmp(&self, other: &Flag) -> Option<Ordering> {
use Flag::*;
fn partial_cmp(&self, other: &Flag<'_>) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Flag<'_> {
fn cmp(&self, other: &Self) -> Ordering {
match (self, other) {
(Command(s1, _), Command(s2, _))
| (Arg(s1, _), Arg(s2, _))
| (Command(s1, _), Arg(s2, _))
| (Arg(s1, _), Command(s2, _)) => {
(Flag::Command(s1, _), Flag::Command(s2, _))
| (Flag::Arg(s1, _), Flag::Arg(s2, _))
| (Flag::Command(s1, _), Flag::Arg(s2, _))
| (Flag::Arg(s1, _), Flag::Command(s2, _)) => {
if s1 == s2 {
Some(Ordering::Equal)
Ordering::Equal
} else {
s1.partial_cmp(s2)
s1.cmp(s2)
}
}
}
}
}
impl Ord for Flag<'_> {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(other).unwrap()
}
}
fn detect_duplicate_flags(flags: &[Flag], short_or_long: &str) {
use Flag::*;
fn detect_duplicate_flags(flags: &[Flag<'_>], short_or_long: &str) {
for (one, two) in find_duplicates(flags) {
match (one, two) {
(Command(flag, one), Command(_, another)) if one != another => panic!(
(Flag::Command(flag, one), Flag::Command(_, another)) if one != another => panic!(
"the '{flag}' {short_or_long} flag is specified for both '{one}' and '{another}' subcommands"
),
(Arg(flag, one), Arg(_, another)) if one != another => panic!(
(Flag::Arg(flag, one), Flag::Arg(_, another)) if one != another => panic!(
"{short_or_long} option names must be unique, but '{flag}' is in use by both '{one}' and '{another}'"
),
(Arg(flag, arg), Command(_, sub)) | (Command(flag, sub), Arg(_, arg)) => panic!(
(Flag::Arg(flag, arg), Flag::Command(_, sub)) | (Flag::Command(flag, sub), Flag::Arg(_, arg)) => panic!(
"the '{flag}' {short_or_long} flag for the '{arg}' argument conflicts with the short flag \
for '{sub}' subcommand"
),
@ -467,22 +463,6 @@ fn find_duplicates<T: PartialEq>(slice: &[T]) -> impl Iterator<Item = (&T, &T)>
fn assert_app_flags(cmd: &Command) {
macro_rules! checker {
($a:ident requires $($b:ident)|+) => {
if cmd.$a() {
let mut s = String::new();
$(
if !cmd.$b() {
use std::fmt::Write;
write!(&mut s, " AppSettings::{} is required when AppSettings::{} is set.\n", std::stringify!($b), std::stringify!($a)).unwrap();
}
)+
if !s.is_empty() {
panic!("{s}")
}
}
};
($a:ident conflicts $($b:ident)|+) => {
if cmd.$a() {
let mut s = String::new();
@ -704,13 +684,14 @@ fn assert_arg(arg: &Arg) {
arg.get_id(),
);
assert_eq!(
arg.get_action().takes_values(),
arg.is_takes_value_set(),
"Argument `{}`'s selected action {:?} contradicts `takes_value`",
arg.get_id(),
arg.get_action()
);
if arg.is_takes_value_set() {
assert!(
arg.get_action().takes_values(),
"Argument `{}`'s selected action {:?} contradicts `takes_value`",
arg.get_id(),
arg.get_action()
);
}
if let Some(action_type_id) = arg.get_action().value_type_id() {
assert_eq!(
action_type_id,
@ -734,7 +715,7 @@ fn assert_arg(arg: &Arg) {
arg.is_multiple_values_set(),
"Argument '{}' uses hint CommandWithArguments and must accept multiple values",
arg.get_id()
)
);
}
}
@ -774,13 +755,6 @@ fn assert_arg(arg: &Arg) {
}
}
assert_eq!(
num_vals.takes_values(),
arg.is_takes_value_set(),
"Argument {}: mismatch between `num_args` ({}) and `takes_value`",
arg.get_id(),
num_vals,
);
assert_eq!(
num_vals.is_multiple(),
arg.is_multiple_values_set(),

Просмотреть файл

@ -1,43 +1,36 @@
use crate::util::AnyValue;
use crate::util::AnyValueId;
use crate::util::FlatMap;
#[derive(Default, Clone, Debug)]
pub(crate) struct Extensions {
extensions: FlatMap<AnyValueId, BoxedExtension>,
extensions: FlatMap<AnyValueId, AnyValue>,
}
impl Extensions {
#[allow(dead_code)]
pub(crate) fn get<T: Extension>(&self) -> Option<&T> {
let id = AnyValueId::of::<T>();
self.extensions.get(&id).map(|e| e.as_ref::<T>())
self.extensions.get(&id).map(|e| {
e.downcast_ref::<T>()
.expect("`Extensions` tracks values by type")
})
}
#[allow(dead_code)]
pub(crate) fn get_mut<T: Extension>(&mut self) -> Option<&mut T> {
let id = AnyValueId::of::<T>();
self.extensions.get_mut(&id).map(|e| e.as_mut::<T>())
}
#[allow(dead_code)]
pub(crate) fn get_or_insert_default<T: Extension + Default>(&mut self) -> &mut T {
let id = AnyValueId::of::<T>();
self.extensions
.entry(id)
.or_insert_with(|| BoxedExtension::new(T::default()))
.as_mut::<T>()
}
#[allow(dead_code)]
pub(crate) fn set<T: Extension + Into<BoxedEntry>>(&mut self, tagged: T) -> bool {
let BoxedEntry { id, value } = tagged.into();
pub(crate) fn set<T: Extension>(&mut self, tagged: T) -> bool {
let value = AnyValue::new(tagged);
let id = value.type_id();
self.extensions.insert(id, value).is_some()
}
#[allow(dead_code)]
pub(crate) fn remove<T: Extension>(&mut self) -> Option<Box<dyn Extension>> {
pub(crate) fn remove<T: Extension>(&mut self) -> Option<T> {
let id = AnyValueId::of::<T>();
self.extensions.remove(&id).map(BoxedExtension::into_inner)
self.extensions.remove(&id).map(|e| {
e.downcast_into::<T>()
.expect("`Extensions` tracks values by type")
})
}
pub(crate) fn update(&mut self, other: &Self) {
@ -47,170 +40,7 @@ impl Extensions {
}
}
/// Supports conversion to `Any`. Traits to be extended by `impl_downcast!` must extend `Extension`.
pub(crate) trait Extension: std::fmt::Debug + Send + Sync + 'static {
/// Convert `Box<dyn Trait>` (where `Trait: Extension`) to `Box<dyn Any>`.
///
/// `Box<dyn Any>` can /// then be further `downcast` into
/// `Box<ConcreteType>` where `ConcreteType` implements `Trait`.
fn into_any(self: Box<Self>) -> Box<dyn std::any::Any>;
/// Clone `&Box<dyn Trait>` (where `Trait: Extension`) to `Box<dyn Extension>`.
///
/// `Box<dyn Any>` can /// then be further `downcast` into
// `Box<ConcreteType>` where `ConcreteType` implements `Trait`.
fn clone_extension(&self) -> Box<dyn Extension>;
/// Convert `&Trait` (where `Trait: Extension`) to `&Any`.
///
/// This is needed since Rust cannot /// generate `&Any`'s vtable from
/// `&Trait`'s.
fn as_any(&self) -> &dyn std::any::Any;
/// Convert `&mut Trait` (where `Trait: Extension`) to `&Any`.
///
/// This is needed since Rust cannot /// generate `&mut Any`'s vtable from
/// `&mut Trait`'s.
fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
}
#[allow(unreachable_pub)]
pub trait Extension: std::fmt::Debug + Clone + std::any::Any + Send + Sync + 'static {}
impl<T> Extension for T
where
T: Clone + std::fmt::Debug + Send + Sync + 'static,
{
fn into_any(self: Box<Self>) -> Box<dyn std::any::Any> {
self
}
fn clone_extension(&self) -> Box<dyn Extension> {
Box::new(self.clone())
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
}
impl Clone for Box<dyn Extension> {
fn clone(&self) -> Self {
self.as_ref().clone_extension()
}
}
#[derive(Clone)]
#[repr(transparent)]
struct BoxedExtension(Box<dyn Extension>);
impl BoxedExtension {
fn new<T: Extension>(inner: T) -> Self {
Self(Box::new(inner))
}
fn into_inner(self) -> Box<dyn Extension> {
self.0
}
fn as_ref<T: Extension>(&self) -> &T {
self.0.as_ref().as_any().downcast_ref::<T>().unwrap()
}
fn as_mut<T: Extension>(&mut self) -> &mut T {
self.0.as_mut().as_any_mut().downcast_mut::<T>().unwrap()
}
}
impl std::fmt::Debug for BoxedExtension {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
self.0.fmt(f)
}
}
#[derive(Clone)]
pub(crate) struct BoxedEntry {
id: AnyValueId,
value: BoxedExtension,
}
impl BoxedEntry {
pub(crate) fn new(r: impl Extension) -> Self {
let id = AnyValueId::from(&r);
let value = BoxedExtension::new(r);
BoxedEntry { id, value }
}
}
impl<R: Extension> From<R> for BoxedEntry {
fn from(inner: R) -> Self {
BoxedEntry::new(inner)
}
}
#[cfg(test)]
mod test {
use super::*;
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
struct Number(usize);
#[test]
fn get() {
let mut ext = Extensions::default();
ext.set(Number(10));
assert_eq!(ext.get::<Number>(), Some(&Number(10)));
}
#[test]
fn get_mut() {
let mut ext = Extensions::default();
ext.set(Number(10));
*ext.get_mut::<Number>().unwrap() = Number(20);
assert_eq!(ext.get::<Number>(), Some(&Number(20)));
}
#[test]
fn get_or_insert_default_empty() {
let mut ext = Extensions::default();
assert_eq!(ext.get_or_insert_default::<Number>(), &Number(0));
}
#[test]
fn get_or_insert_default_full() {
let mut ext = Extensions::default();
ext.set(Number(10));
assert_eq!(ext.get_or_insert_default::<Number>(), &Number(10));
}
#[test]
fn set() {
let mut ext = Extensions::default();
assert!(!ext.set(Number(10)));
assert_eq!(ext.get::<Number>(), Some(&Number(10)));
assert!(ext.set(Number(20)));
assert_eq!(ext.get::<Number>(), Some(&Number(20)));
}
#[test]
fn reset() {
let mut ext = Extensions::default();
assert_eq!(ext.get::<Number>(), None);
assert!(ext.remove::<Number>().is_none());
assert_eq!(ext.get::<Number>(), None);
assert!(!ext.set(Number(10)));
assert_eq!(ext.get::<Number>(), Some(&Number(10)));
assert!(ext.remove::<Number>().is_some());
assert_eq!(ext.get::<Number>(), None);
}
#[test]
fn update() {
let mut ext = Extensions::default();
assert_eq!(ext.get::<Number>(), None);
let mut new = Extensions::default();
assert!(!new.set(Number(10)));
ext.update(&new);
assert_eq!(ext.get::<Number>(), Some(&Number(10)));
}
}
impl<T> Extension for T where T: std::fmt::Debug + Clone + std::any::Any + Send + Sync + 'static {}

Просмотреть файл

@ -28,6 +28,8 @@ pub mod styling;
pub use self::str::Str;
pub use action::ArgAction;
pub use arg::Arg;
#[cfg(feature = "unstable-ext")]
pub use arg::ArgExt;
pub use arg_group::ArgGroup;
pub use arg_predicate::ArgPredicate;
pub use command::Command;

Просмотреть файл

@ -64,16 +64,6 @@ impl From<Str> for OsStr {
}
}
#[cfg(feature = "perf")]
impl From<&'_ Str> for OsStr {
fn from(id: &'_ Str) -> Self {
match id.clone().into_inner() {
crate::builder::StrInner::Static(s) => Self::from_static_ref(std::ffi::OsStr::new(s)),
crate::builder::StrInner::Owned(s) => Self::from_ref(std::ffi::OsStr::new(s.as_ref())),
}
}
}
impl From<&'_ Str> for OsStr {
fn from(id: &'_ Str) -> Self {
id.clone().into()
@ -95,15 +85,15 @@ impl From<&'_ std::ffi::OsString> for OsStr {
}
#[cfg(feature = "string")]
impl From<std::string::String> for OsStr {
fn from(name: std::string::String) -> Self {
impl From<String> for OsStr {
fn from(name: String) -> Self {
Self::from_string(name.into())
}
}
#[cfg(feature = "string")]
impl From<&'_ std::string::String> for OsStr {
fn from(name: &'_ std::string::String) -> Self {
impl From<&'_ String> for OsStr {
fn from(name: &'_ String) -> Self {
Self::from_ref(name.as_str().as_ref())
}
}
@ -220,13 +210,13 @@ impl PartialEq<OsStr> for &'_ std::ffi::OsStr {
}
}
impl PartialEq<std::string::String> for OsStr {
impl PartialEq<String> for OsStr {
#[inline]
fn eq(&self, other: &std::string::String) -> bool {
fn eq(&self, other: &String) -> bool {
PartialEq::eq(self.as_os_str(), other.as_str())
}
}
impl PartialEq<OsStr> for std::string::String {
impl PartialEq<OsStr> for String {
#[inline]
fn eq(&self, other: &OsStr) -> bool {
PartialEq::eq(self.as_str(), other.as_os_str())
@ -316,7 +306,7 @@ impl PartialEq for Inner {
impl PartialOrd for Inner {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.as_os_str().partial_cmp(other.as_os_str())
Some(self.cmp(other))
}
}

Просмотреть файл

@ -168,7 +168,7 @@ impl PossibleValue {
self.hide
}
/// Report if PossibleValue is not hidden and has a help message
/// Report if `PossibleValue` is not hidden and has a help message
pub(crate) fn should_show_help(&self) -> bool {
!self.hide && self.help.is_some()
}

Просмотреть файл

@ -174,7 +174,7 @@ impl From<std::ops::RangeToInclusive<usize>> for ValueRange {
}
impl std::fmt::Display for ValueRange {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ok!(self.start_inclusive.fmt(f));
if !self.is_fixed() {
ok!("..=".fmt(f));
@ -185,7 +185,7 @@ impl std::fmt::Display for ValueRange {
}
impl std::fmt::Debug for ValueRange {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{self}")
}
}

Просмотреть файл

@ -9,7 +9,7 @@ pub struct Str {
impl Str {
#[cfg(feature = "string")]
pub(crate) fn from_string(name: std::string::String) -> Self {
pub(crate) fn from_string(name: String) -> Self {
Self {
name: Inner::from_string(name),
}
@ -45,15 +45,15 @@ impl From<&'_ Str> for Str {
}
#[cfg(feature = "string")]
impl From<std::string::String> for Str {
fn from(name: std::string::String) -> Self {
impl From<String> for Str {
fn from(name: String) -> Self {
Self::from_string(name)
}
}
#[cfg(feature = "string")]
impl From<&'_ std::string::String> for Str {
fn from(name: &'_ std::string::String) -> Self {
impl From<&'_ String> for Str {
fn from(name: &'_ String) -> Self {
Self::from_ref(name.as_str())
}
}
@ -204,13 +204,13 @@ impl PartialEq<Str> for &'_ std::ffi::OsStr {
}
}
impl PartialEq<std::string::String> for Str {
impl PartialEq<String> for Str {
#[inline]
fn eq(&self, other: &std::string::String) -> bool {
fn eq(&self, other: &String) -> bool {
PartialEq::eq(self.as_str(), other.as_str())
}
}
impl PartialEq<Str> for std::string::String {
impl PartialEq<Str> for String {
#[inline]
fn eq(&self, other: &Str) -> bool {
PartialEq::eq(self.as_str(), other.as_str())
@ -226,7 +226,7 @@ pub(crate) mod inner {
}
impl Inner {
pub(crate) fn from_string(name: std::string::String) -> Self {
pub(crate) fn from_string(name: String) -> Self {
Self::Owned(name.into_boxed_str())
}
@ -290,7 +290,7 @@ impl PartialEq for Inner {
impl PartialOrd for Inner {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.as_str().partial_cmp(other.as_str())
Some(self.cmp(other))
}
}

Просмотреть файл

@ -45,21 +45,17 @@ impl StyledStr {
self.0.push_str(msg);
}
pub(crate) fn trim(&mut self) {
self.0 = self.0.trim().to_owned()
}
pub(crate) fn trim_start_lines(&mut self) {
if let Some(pos) = self.0.find('\n') {
let (leading, help) = self.0.split_at(pos + 1);
if leading.trim().is_empty() {
self.0 = help.to_owned()
self.0 = help.to_owned();
}
}
}
pub(crate) fn trim_end(&mut self) {
self.0 = self.0.trim_end().to_owned()
self.0 = self.0.trim_end().to_owned();
}
#[cfg(feature = "help")]
@ -160,14 +156,14 @@ impl Default for &'_ StyledStr {
}
}
impl From<std::string::String> for StyledStr {
fn from(name: std::string::String) -> Self {
impl From<String> for StyledStr {
fn from(name: String) -> Self {
StyledStr(name)
}
}
impl From<&'_ std::string::String> for StyledStr {
fn from(name: &'_ std::string::String) -> Self {
impl From<&'_ String> for StyledStr {
fn from(name: &'_ String) -> Self {
let mut styled = StyledStr::new();
styled.push_str(name);
styled
@ -204,7 +200,7 @@ impl std::fmt::Write for StyledStr {
/// Color-unaware printing. Never uses coloring.
impl std::fmt::Display for StyledStr {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for part in self.iter_text() {
part.fmt(f)?;
}

Просмотреть файл

@ -21,26 +21,26 @@ pub use anstyle::*;
#[derive(Clone, Debug)]
#[allow(missing_copy_implementations)] // Large enough type that I want an explicit `clone()` for now
pub struct Styles {
header: anstyle::Style,
error: anstyle::Style,
usage: anstyle::Style,
literal: anstyle::Style,
placeholder: anstyle::Style,
valid: anstyle::Style,
invalid: anstyle::Style,
header: Style,
error: Style,
usage: Style,
literal: Style,
placeholder: Style,
valid: Style,
invalid: Style,
}
impl Styles {
/// No terminal styling
pub const fn plain() -> Self {
Self {
header: anstyle::Style::new(),
error: anstyle::Style::new(),
usage: anstyle::Style::new(),
literal: anstyle::Style::new(),
placeholder: anstyle::Style::new(),
valid: anstyle::Style::new(),
invalid: anstyle::Style::new(),
header: Style::new(),
error: Style::new(),
usage: Style::new(),
literal: Style::new(),
placeholder: Style::new(),
valid: Style::new(),
invalid: Style::new(),
}
}
@ -49,17 +49,15 @@ impl Styles {
#[cfg(feature = "color")]
{
Self {
header: anstyle::Style::new().bold().underline(),
error: anstyle::Style::new()
.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Red)))
header: Style::new().bold().underline(),
error: Style::new()
.fg_color(Some(Color::Ansi(AnsiColor::Red)))
.bold(),
usage: anstyle::Style::new().bold().underline(),
literal: anstyle::Style::new().bold(),
placeholder: anstyle::Style::new(),
valid: anstyle::Style::new()
.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Green))),
invalid: anstyle::Style::new()
.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Yellow))),
usage: Style::new().bold().underline(),
literal: Style::new().bold(),
placeholder: Style::new(),
valid: Style::new().fg_color(Some(Color::Ansi(AnsiColor::Green))),
invalid: Style::new().fg_color(Some(Color::Ansi(AnsiColor::Yellow))),
}
}
#[cfg(not(feature = "color"))]
@ -70,49 +68,49 @@ impl Styles {
/// General Heading style, e.g. [`help_heading`][crate::Arg::help_heading]
#[inline]
pub const fn header(mut self, style: anstyle::Style) -> Self {
pub const fn header(mut self, style: Style) -> Self {
self.header = style;
self
}
/// Error heading
#[inline]
pub const fn error(mut self, style: anstyle::Style) -> Self {
pub const fn error(mut self, style: Style) -> Self {
self.error = style;
self
}
/// Usage heading
#[inline]
pub const fn usage(mut self, style: anstyle::Style) -> Self {
pub const fn usage(mut self, style: Style) -> Self {
self.usage = style;
self
}
/// Literal command-line syntax, e.g. `--help`
#[inline]
pub const fn literal(mut self, style: anstyle::Style) -> Self {
pub const fn literal(mut self, style: Style) -> Self {
self.literal = style;
self
}
/// Descriptions within command-line syntax, e.g. [`value_name`][crate::Arg::value_name]
#[inline]
pub const fn placeholder(mut self, style: anstyle::Style) -> Self {
pub const fn placeholder(mut self, style: Style) -> Self {
self.placeholder = style;
self
}
/// Highlight suggested usage
#[inline]
pub const fn valid(mut self, style: anstyle::Style) -> Self {
pub const fn valid(mut self, style: Style) -> Self {
self.valid = style;
self
}
/// Highlight invalid usage
#[inline]
pub const fn invalid(mut self, style: anstyle::Style) -> Self {
pub const fn invalid(mut self, style: Style) -> Self {
self.invalid = style;
self
}
@ -122,43 +120,43 @@ impl Styles {
impl Styles {
/// General Heading style, e.g. [`help_heading`][crate::Arg::help_heading]
#[inline(always)]
pub const fn get_header(&self) -> &anstyle::Style {
pub const fn get_header(&self) -> &Style {
&self.header
}
/// Error heading
#[inline(always)]
pub const fn get_error(&self) -> &anstyle::Style {
pub const fn get_error(&self) -> &Style {
&self.error
}
/// Usage heading
#[inline(always)]
pub const fn get_usage(&self) -> &anstyle::Style {
pub const fn get_usage(&self) -> &Style {
&self.usage
}
/// Literal command-line syntax, e.g. `--help`
#[inline(always)]
pub const fn get_literal(&self) -> &anstyle::Style {
pub const fn get_literal(&self) -> &Style {
&self.literal
}
/// Descriptions within command-line syntax, e.g. [`value_name`][crate::Arg::value_name]
#[inline(always)]
pub const fn get_placeholder(&self) -> &anstyle::Style {
pub const fn get_placeholder(&self) -> &Style {
&self.placeholder
}
/// Highlight suggested usage
#[inline(always)]
pub const fn get_valid(&self) -> &anstyle::Style {
pub const fn get_valid(&self) -> &Style {
&self.valid
}
/// Highlight invalid usage
#[inline(always)]
pub const fn get_invalid(&self) -> &anstyle::Style {
pub const fn get_invalid(&self) -> &Style {
&self.invalid
}
}

Просмотреть файл

@ -31,7 +31,7 @@ fn global_setting() {
#[test]
fn app_send_sync() {
fn foo<T: Send + Sync>(_: T) {}
foo(Command::new("test"))
foo(Command::new("test"));
}
#[test]
@ -52,5 +52,5 @@ fn issue_2090() {
#[test]
fn arg_send_sync() {
fn foo<T: Send + Sync>(_: T) {}
foo(Arg::new("test"))
foo(Arg::new("test"));
}

Просмотреть файл

@ -2,25 +2,25 @@ use std::str::FromStr;
/// Provide shell with hint on how to complete an argument.
///
/// See [Arg::value_hint][crate::Arg::value_hint] to set this on an argument.
/// See [`Arg::value_hint`][crate::Arg::value_hint] to set this on an argument.
///
/// See the `clap_complete` crate for completion script generation.
///
/// Overview of which hints are supported by which shell:
///
/// | Hint | zsh | fish[^1]|
/// | ---------------------- | --- | ------- |
/// | `AnyPath` | Yes | Yes |
/// | `FilePath` | Yes | Yes |
/// | `DirPath` | Yes | Yes |
/// | `ExecutablePath` | Yes | Partial |
/// | `CommandName` | Yes | Yes |
/// | `CommandString` | Yes | Partial |
/// | `CommandWithArguments` | Yes | |
/// | `Username` | Yes | Yes |
/// | `Hostname` | Yes | Yes |
/// | `Url` | Yes | |
/// | `EmailAddress` | Yes | |
/// | Hint | zsh | fish[^1] | dynamic |
/// | ---------------------- | --- | ---------|---------|
/// | `AnyPath` | Yes | Yes | Yes |
/// | `FilePath` | Yes | Yes | Yes |
/// | `DirPath` | Yes | Yes | Yes |
/// | `ExecutablePath` | Yes | Partial | Yes |
/// | `CommandName` | Yes | Yes | No |
/// | `CommandString` | Yes | Partial | No |
/// | `CommandWithArguments` | Yes | | No |
/// | `Username` | Yes | Yes | No |
/// | `Hostname` | Yes | Yes | No |
/// | `Url` | Yes | | No |
/// | `EmailAddress` | Yes | | No |
///
/// [^1]: fish completions currently only support named arguments (e.g. -o or --opt), not
/// positional arguments.
@ -67,6 +67,9 @@ pub enum ValueHint {
EmailAddress,
}
#[cfg(feature = "unstable-ext")]
impl crate::builder::ArgExt for ValueHint {}
impl FromStr for ValueHint {
type Err = String;
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {

Просмотреть файл

@ -564,7 +564,7 @@ where
}
impl std::fmt::Debug for ValueParser {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match &self.0 {
ValueParserInner::Bool => f.debug_struct("ValueParser::bool").finish(),
ValueParserInner::String => f.debug_struct("ValueParser::string").finish(),
@ -606,23 +606,6 @@ trait AnyValueParser: Send + Sync + 'static {
self.parse_ref(cmd, arg, value)
}
fn parse(
&self,
cmd: &crate::Command,
arg: Option<&crate::Arg>,
value: std::ffi::OsString,
) -> Result<AnyValue, crate::Error>;
fn parse_(
&self,
cmd: &crate::Command,
arg: Option<&crate::Arg>,
value: std::ffi::OsString,
_source: ValueSource,
) -> Result<AnyValue, crate::Error> {
self.parse(cmd, arg, value)
}
/// Describes the content of `AnyValue`
fn type_id(&self) -> AnyValueId;
@ -659,27 +642,6 @@ where
Ok(AnyValue::new(value))
}
fn parse(
&self,
cmd: &crate::Command,
arg: Option<&crate::Arg>,
value: std::ffi::OsString,
) -> Result<AnyValue, crate::Error> {
let value = ok!(TypedValueParser::parse(self, cmd, arg, value));
Ok(AnyValue::new(value))
}
fn parse_(
&self,
cmd: &crate::Command,
arg: Option<&crate::Arg>,
value: std::ffi::OsString,
source: ValueSource,
) -> Result<AnyValue, crate::Error> {
let value = ok!(TypedValueParser::parse_(self, cmd, arg, value, source));
Ok(AnyValue::new(value))
}
fn type_id(&self) -> AnyValueId {
AnyValueId::of::<T>()
}
@ -1346,12 +1308,12 @@ where
/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("50")).unwrap(), 50);
/// ```
#[derive(Copy, Clone, Debug)]
pub struct RangedI64ValueParser<T: std::convert::TryFrom<i64> + Clone + Send + Sync = i64> {
pub struct RangedI64ValueParser<T: TryFrom<i64> + Clone + Send + Sync = i64> {
bounds: (std::ops::Bound<i64>, std::ops::Bound<i64>),
target: std::marker::PhantomData<T>,
}
impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync> RangedI64ValueParser<T> {
impl<T: TryFrom<i64> + Clone + Send + Sync> RangedI64ValueParser<T> {
/// Select full range of `i64`
pub fn new() -> Self {
Self::from(..)
@ -1431,10 +1393,9 @@ impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync> RangedI64ValueParser<T
}
}
impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync + 'static> TypedValueParser
for RangedI64ValueParser<T>
impl<T: TryFrom<i64> + Clone + Send + Sync + 'static> TypedValueParser for RangedI64ValueParser<T>
where
<T as std::convert::TryFrom<i64>>::Error: Send + Sync + 'static + std::error::Error + ToString,
<T as TryFrom<i64>>::Error: Send + Sync + 'static + std::error::Error + ToString,
{
type Value = T;
@ -1490,7 +1451,7 @@ where
}
}
impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync, B: RangeBounds<i64>> From<B>
impl<T: TryFrom<i64> + Clone + Send + Sync, B: RangeBounds<i64>> From<B>
for RangedI64ValueParser<T>
{
fn from(range: B) -> Self {
@ -1501,7 +1462,7 @@ impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync, B: RangeBounds<i64>> F
}
}
impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync> Default for RangedI64ValueParser<T> {
impl<T: TryFrom<i64> + Clone + Send + Sync> Default for RangedI64ValueParser<T> {
fn default() -> Self {
Self::new()
}
@ -1546,12 +1507,12 @@ impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync> Default for RangedI64V
/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("50")).unwrap(), 50);
/// ```
#[derive(Copy, Clone, Debug)]
pub struct RangedU64ValueParser<T: std::convert::TryFrom<u64> = u64> {
pub struct RangedU64ValueParser<T: TryFrom<u64> = u64> {
bounds: (std::ops::Bound<u64>, std::ops::Bound<u64>),
target: std::marker::PhantomData<T>,
}
impl<T: std::convert::TryFrom<u64>> RangedU64ValueParser<T> {
impl<T: TryFrom<u64>> RangedU64ValueParser<T> {
/// Select full range of `u64`
pub fn new() -> Self {
Self::from(..)
@ -1631,10 +1592,9 @@ impl<T: std::convert::TryFrom<u64>> RangedU64ValueParser<T> {
}
}
impl<T: std::convert::TryFrom<u64> + Clone + Send + Sync + 'static> TypedValueParser
for RangedU64ValueParser<T>
impl<T: TryFrom<u64> + Clone + Send + Sync + 'static> TypedValueParser for RangedU64ValueParser<T>
where
<T as std::convert::TryFrom<u64>>::Error: Send + Sync + 'static + std::error::Error + ToString,
<T as TryFrom<u64>>::Error: Send + Sync + 'static + std::error::Error + ToString,
{
type Value = T;
@ -1690,7 +1650,7 @@ where
}
}
impl<T: std::convert::TryFrom<u64>, B: RangeBounds<u64>> From<B> for RangedU64ValueParser<T> {
impl<T: TryFrom<u64>, B: RangeBounds<u64>> From<B> for RangedU64ValueParser<T> {
fn from(range: B) -> Self {
Self {
bounds: (range.start_bound().cloned(), range.end_bound().cloned()),
@ -1699,7 +1659,7 @@ impl<T: std::convert::TryFrom<u64>, B: RangeBounds<u64>> From<B> for RangedU64Va
}
}
impl<T: std::convert::TryFrom<u64>> Default for RangedU64ValueParser<T> {
impl<T: TryFrom<u64>> Default for RangedU64ValueParser<T> {
fn default() -> Self {
Self::new()
}
@ -1913,7 +1873,7 @@ impl Default for FalseyValueParser {
pub struct BoolishValueParser {}
impl BoolishValueParser {
/// Parse bool-like string values, everything else is `true`
/// Parse bool-like string values, everything else is an error.
pub fn new() -> Self {
Self {}
}
@ -2158,7 +2118,7 @@ where
}
}
/// When encountered, report [ErrorKind::UnknownArgument][crate::error::ErrorKind::UnknownArgument]
/// When encountered, report [`ErrorKind::UnknownArgument`][crate::error::ErrorKind::UnknownArgument]
///
/// Useful to help users migrate, either from old versions or similar tools.
///
@ -2274,7 +2234,7 @@ impl TypedValueParser for UnknownArgumentValueParser {
}
}
/// Register a type with [value_parser!][crate::value_parser!]
/// Register a type with [`value_parser!`][crate::value_parser!]
///
/// # Example
///
@ -2650,10 +2610,6 @@ macro_rules! value_parser {
mod private {
use super::*;
// Prefer these so `clap_derive` defaults to optimized implementations
pub trait _ValueParserViaSelfSealed {}
impl<P: Into<ValueParser>> _ValueParserViaSelfSealed for &&&&&&&_AutoValueParser<P> {}
pub trait _ValueParserViaFactorySealed {}
impl<P: ValueParserFactory> _ValueParserViaFactorySealed for &&&&&&_AutoValueParser<P> {}

12
third_party/rust/clap_builder/src/derive.rs поставляемый
Просмотреть файл

@ -22,7 +22,7 @@ use std::ffi::OsString;
///
/// **NOTE:** Deriving requires the `derive` feature flag
pub trait Parser: FromArgMatches + CommandFactory + Sized {
/// Parse from `std::env::args_os()`, exit on error
/// Parse from `std::env::args_os()`, [exit][Error::exit] on error.
fn parse() -> Self {
let mut matches = <Self as CommandFactory>::command().get_matches();
let res = <Self as FromArgMatches>::from_arg_matches_mut(&mut matches)
@ -43,7 +43,7 @@ pub trait Parser: FromArgMatches + CommandFactory + Sized {
<Self as FromArgMatches>::from_arg_matches_mut(&mut matches).map_err(format_error::<Self>)
}
/// Parse from iterator, exit on error
/// Parse from iterator, [exit][Error::exit] on error.
fn parse_from<I, T>(itr: I) -> Self
where
I: IntoIterator<Item = T>,
@ -72,7 +72,7 @@ pub trait Parser: FromArgMatches + CommandFactory + Sized {
<Self as FromArgMatches>::from_arg_matches_mut(&mut matches).map_err(format_error::<Self>)
}
/// Update from iterator, exit on error
/// Update from iterator, [exit][Error::exit] on error.
fn update_from<I, T>(&mut self, itr: I)
where
I: IntoIterator<Item = T>,
@ -311,10 +311,10 @@ impl<T: Parser> Parser for Box<T> {
}
impl<T: CommandFactory> CommandFactory for Box<T> {
fn command<'help>() -> Command {
fn command() -> Command {
<T as CommandFactory>::command()
}
fn command_for_update<'help>() -> Command {
fn command_for_update() -> Command {
<T as CommandFactory>::command_for_update()
}
}
@ -355,7 +355,7 @@ impl<T: Subcommand> Subcommand for Box<T> {
}
}
fn format_error<I: CommandFactory>(err: crate::Error) -> crate::Error {
fn format_error<I: CommandFactory>(err: Error) -> Error {
let mut cmd = I::command();
err.format(&mut cmd)
}

Просмотреть файл

@ -3,6 +3,8 @@
#![cfg_attr(not(feature = "error-context"), allow(dead_code))]
#![cfg_attr(not(feature = "error-context"), allow(unused_imports))]
use std::borrow::Cow;
use crate::builder::Command;
use crate::builder::StyledStr;
use crate::builder::Styles;
@ -12,6 +14,7 @@ use crate::error::ContextKind;
use crate::error::ContextValue;
use crate::error::ErrorKind;
use crate::output::TAB;
use crate::ArgAction;
/// Defines how to format an error for displaying to the user
pub trait ErrorFormatter: Sized {
@ -120,7 +123,7 @@ impl ErrorFormatter for RichFormatter {
put_usage(&mut styled, usage);
}
try_help(&mut styled, styles, error.inner.help_flag);
try_help(&mut styled, styles, error.inner.help_flag.as_deref());
styled
}
@ -146,12 +149,10 @@ fn write_dynamic_context(
match error.kind() {
ErrorKind::ArgumentConflict => {
let invalid_arg = error.get(ContextKind::InvalidArg);
let prior_arg = error.get(ContextKind::PriorArg);
if let (Some(ContextValue::String(invalid_arg)), Some(prior_arg)) =
(invalid_arg, prior_arg)
{
if ContextValue::String(invalid_arg.clone()) == *prior_arg {
let mut prior_arg = error.get(ContextKind::PriorArg);
if let Some(ContextValue::String(invalid_arg)) = error.get(ContextKind::InvalidArg) {
if Some(&ContextValue::String(invalid_arg.clone())) == prior_arg {
prior_arg = None;
let _ = write!(
styled,
"the argument '{}{invalid_arg}{}' cannot be used multiple times",
@ -165,36 +166,48 @@ fn write_dynamic_context(
invalid.render(),
invalid.render_reset()
);
}
} else if let Some(ContextValue::String(invalid_arg)) =
error.get(ContextKind::InvalidSubcommand)
{
let _ = write!(
styled,
"the subcommand '{}{invalid_arg}{}' cannot be used with",
invalid.render(),
invalid.render_reset()
);
} else {
styled.push_str(error.kind().as_str().unwrap());
}
match prior_arg {
ContextValue::Strings(values) => {
styled.push_str(":");
for v in values {
let _ = write!(
styled,
"\n{TAB}{}{v}{}",
invalid.render(),
invalid.render_reset()
);
}
}
ContextValue::String(value) => {
if let Some(prior_arg) = prior_arg {
match prior_arg {
ContextValue::Strings(values) => {
styled.push_str(":");
for v in values {
let _ = write!(
styled,
" '{}{value}{}'",
"\n{TAB}{}{v}{}",
invalid.render(),
invalid.render_reset()
);
}
_ => {
styled.push_str(" one or more of the other specified arguments");
}
}
ContextValue::String(value) => {
let _ = write!(
styled,
" '{}{value}{}'",
invalid.render(),
invalid.render_reset()
);
}
_ => {
styled.push_str(" one or more of the other specified arguments");
}
}
true
} else {
false
}
true
}
ErrorKind::NoEquals => {
let invalid_arg = error.get(ContextKind::InvalidArg);
@ -327,7 +340,7 @@ fn write_dynamic_context(
let were_provided = singular_or_plural(*actual_num_values as usize);
let _ = write!(
styled,
"{}{min_values}{} more values required by '{}{invalid_arg}{}'; only {}{actual_num_values}{}{were_provided}",
"{}{min_values}{} values required by '{}{invalid_arg}{}'; only {}{actual_num_values}{}{were_provided}",
valid.render(),
valid.render_reset(),
literal.render(),
@ -451,7 +464,7 @@ pub(crate) fn format_error_message(
put_usage(&mut styled, usage);
}
if let Some(cmd) = cmd {
try_help(&mut styled, styles, get_help_flag(cmd));
try_help(&mut styled, styles, get_help_flag(cmd).as_deref());
}
styled
}
@ -470,16 +483,34 @@ fn put_usage(styled: &mut StyledStr, usage: &StyledStr) {
styled.push_styled(usage);
}
pub(crate) fn get_help_flag(cmd: &Command) -> Option<&'static str> {
pub(crate) fn get_help_flag(cmd: &Command) -> Option<Cow<'static, str>> {
if !cmd.is_disable_help_flag_set() {
Some("--help")
Some(Cow::Borrowed("--help"))
} else if let Some(flag) = get_user_help_flag(cmd) {
Some(Cow::Owned(flag))
} else if cmd.has_subcommands() && !cmd.is_disable_help_subcommand_set() {
Some("help")
Some(Cow::Borrowed("help"))
} else {
None
}
}
fn get_user_help_flag(cmd: &Command) -> Option<String> {
let arg = cmd.get_arguments().find(|arg| match arg.get_action() {
ArgAction::Help | ArgAction::HelpShort | ArgAction::HelpLong => true,
ArgAction::Append
| ArgAction::Count
| ArgAction::SetTrue
| ArgAction::SetFalse
| ArgAction::Set
| ArgAction::Version => false,
})?;
arg.get_long()
.map(|long| format!("--{long}"))
.or_else(|| arg.get_short().map(|short| format!("-{short}")))
}
fn try_help(styled: &mut StyledStr, styles: &Styles, help: Option<&str>) {
if let Some(help) = help {
use std::fmt::Write as _;
@ -535,7 +566,7 @@ fn did_you_mean(styled: &mut StyledStr, styles: &Styles, context: &str, valid: &
struct Escape<'s>(&'s str);
impl<'s> std::fmt::Display for Escape<'s> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.0.contains(char::is_whitespace) {
std::fmt::Debug::fmt(self.0, f)
} else {

Просмотреть файл

@ -12,7 +12,7 @@ use std::{
convert::From,
error,
fmt::{self, Debug, Display, Formatter},
io::{self},
io,
result::Result as StdResult,
};
@ -23,7 +23,7 @@ use crate::output::fmt::Colorizer;
use crate::output::fmt::Stream;
use crate::parser::features::suggestions;
use crate::util::FlatMap;
use crate::util::{color::ColorChoice, safe_exit, SUCCESS_CODE, USAGE_CODE};
use crate::util::{color::ColorChoice, SUCCESS_CODE, USAGE_CODE};
use crate::Command;
#[cfg(feature = "error-context")]
@ -69,7 +69,7 @@ struct ErrorInner {
context: FlatMap<ContextKind, ContextValue>,
message: Option<Message>,
source: Option<Box<dyn error::Error + Send + Sync>>,
help_flag: Option<&'static str>,
help_flag: Option<Cow<'static, str>>,
styles: Styles,
color_when: ColorChoice,
color_help_when: ColorChoice,
@ -85,7 +85,7 @@ impl<F: ErrorFormatter> Error<F> {
/// Prefer [`Command::error`] for generating errors.
///
/// [`Command::error`]: crate::Command::error
pub fn raw(kind: ErrorKind, message: impl std::fmt::Display) -> Self {
pub fn raw(kind: ErrorKind, message: impl Display) -> Self {
Self::new(kind).set_message(message.to_string())
}
@ -233,7 +233,7 @@ impl<F: ErrorFormatter> Error<F> {
pub fn exit(&self) -> ! {
// Swallow broken pipe errors
let _ = self.print();
safe_exit(self.exit_code())
std::process::exit(self.exit_code());
}
/// Prints formatted and colored error to `stdout` or `stderr` according to its error kind
@ -319,7 +319,7 @@ impl<F: ErrorFormatter> Error<F> {
self
}
pub(crate) fn set_help_flag(mut self, help_flag: Option<&'static str>) -> Self {
pub(crate) fn set_help_flag(mut self, help_flag: Option<Cow<'static, str>>) -> Self {
self.inner.help_flag = help_flag;
self
}
@ -391,6 +391,34 @@ impl<F: ErrorFormatter> Error<F> {
err
}
pub(crate) fn subcommand_conflict(
cmd: &Command,
sub: String,
mut others: Vec<String>,
usage: Option<StyledStr>,
) -> Self {
let mut err = Self::new(ErrorKind::ArgumentConflict).with_cmd(cmd);
#[cfg(feature = "error-context")]
{
let others = match others.len() {
0 => ContextValue::None,
1 => ContextValue::String(others.pop().unwrap()),
_ => ContextValue::Strings(others),
};
err = err.extend_context_unchecked([
(ContextKind::InvalidSubcommand, ContextValue::String(sub)),
(ContextKind::PriorArg, others),
]);
if let Some(usage) = usage {
err = err
.insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
}
}
err
}
pub(crate) fn empty_value(cmd: &Command, good_vals: &[String], arg: String) -> Self {
Self::invalid_value(cmd, "".to_owned(), good_vals, arg)
}
@ -427,7 +455,7 @@ impl<F: ErrorFormatter> Error<F> {
(ContextKind::InvalidValue, ContextValue::String(bad_val)),
(
ContextKind::ValidValue,
ContextValue::Strings(good_vals.iter().map(|s| (*s).to_owned()).collect()),
ContextValue::Strings(good_vals.iter().map(|s| (*s).clone()).collect()),
),
]);
if let Some(suggestion) = suggestion {
@ -804,8 +832,8 @@ impl<F: ErrorFormatter> From<fmt::Error> for Error<F> {
}
}
impl<F: ErrorFormatter> std::fmt::Debug for Error<F> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
impl<F: ErrorFormatter> Debug for Error<F> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
self.inner.fmt(f)
}
}
@ -818,7 +846,7 @@ impl<F: ErrorFormatter> error::Error for Error<F> {
}
impl<F: ErrorFormatter> Display for Error<F> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
// Assuming `self.message` already has a trailing newline, from `try_help` or similar
ok!(write!(f, "{}", self.formatted()));
if let Some(backtrace) = self.inner.backtrace.as_ref() {
@ -856,7 +884,7 @@ impl Message {
}
}
fn formatted(&self, styles: &Styles) -> Cow<StyledStr> {
fn formatted(&self, styles: &Styles) -> Cow<'_, StyledStr> {
match self {
Message::Raw(s) => {
let styled = format::format_error_message(s, styles, None, None);
@ -893,7 +921,7 @@ impl Backtrace {
#[cfg(feature = "debug")]
impl Display for Backtrace {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
// `backtrace::Backtrace` uses `Debug` instead of `Display`
write!(f, "{:?}", self.0)
}
@ -912,7 +940,7 @@ impl Backtrace {
#[cfg(not(feature = "debug"))]
impl Display for Backtrace {
fn fmt(&self, _: &mut Formatter) -> fmt::Result {
fn fmt(&self, _: &mut Formatter<'_>) -> fmt::Result {
Ok(())
}
}

27
third_party/rust/clap_builder/src/lib.rs поставляемый
Просмотреть файл

@ -3,30 +3,13 @@
// (see LICENSE or <http://opensource.org/licenses/MIT>) All files in the project carrying such
// notice may not be copied, modified, or distributed except according to those terms.
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
#![doc(html_logo_url = "https://raw.githubusercontent.com/clap-rs/clap/master/assets/clap.png")]
#![warn(
missing_docs,
missing_debug_implementations,
missing_copy_implementations,
trivial_casts,
unused_allocation,
trivial_numeric_casts,
clippy::single_char_pattern
)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![forbid(unsafe_code)]
// Wanting consistency in our calls
#![allow(clippy::write_with_newline)]
// Gets in the way of logging
#![allow(clippy::let_and_return)]
// HACK https://github.com/rust-lang/rust-clippy/issues/7290
#![allow(clippy::single_component_path_imports)]
#![allow(clippy::branches_sharing_code)]
// Doesn't allow for debug statements, etc to be unique
#![allow(clippy::if_same_then_else)]
// Breaks up parallelism that clarifies intent
#![allow(clippy::collapsible_else_if)]
#![warn(missing_docs)]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
#[cfg(not(feature = "std"))]
compile_error!("`std` feature is currently required to build `clap`");
@ -44,7 +27,7 @@ pub use crate::util::Id;
/// See [`Command::error`] to create an error.
///
/// [`Command::error`]: crate::Command::error
pub type Error = crate::error::Error<crate::error::DefaultFormatter>;
pub type Error = error::Error<error::DefaultFormatter>;
pub use crate::derive::{Args, CommandFactory, FromArgMatches, Parser, Subcommand, ValueEnum};

8
third_party/rust/clap_builder/src/macros.rs поставляемый
Просмотреть файл

@ -42,14 +42,14 @@ macro_rules! crate_version {
#[macro_export]
macro_rules! crate_authors {
($sep:expr) => {{
static authors: &str = env!("CARGO_PKG_AUTHORS");
if authors.contains(':') {
static AUTHORS: &str = env!("CARGO_PKG_AUTHORS");
if AUTHORS.contains(':') {
static CACHED: std::sync::OnceLock<String> = std::sync::OnceLock::new();
let s = CACHED.get_or_init(|| authors.replace(':', $sep));
let s = CACHED.get_or_init(|| AUTHORS.replace(':', $sep));
let s: &'static str = &*s;
s
} else {
authors
AUTHORS
}
}};
() => {

Просмотреть файл

@ -81,7 +81,7 @@ impl PartialEq<char> for KeyType {
impl MKeyMap {
/// If any arg has corresponding key in this map, we can search the key with
/// u64(for positional argument), char(for short flag), &str and OsString
/// `u64` (for positional argument), `char` (for short flag), `&str` and `OsString`
/// (for long flag)
pub(crate) fn contains<K>(&self, key: K) -> bool
where
@ -96,8 +96,8 @@ impl MKeyMap {
}
/// Find the arg have corresponding key in this map, we can search the key
/// with u64(for positional argument), char(for short flag), &str and
/// OsString (for long flag)
/// with `u64` (for positional argument), `char` (for short flag), `&str` and
/// `OsString` (for long flag)
pub(crate) fn get<K: ?Sized>(&self, key: &K) -> Option<&Arg>
where
KeyType: PartialEq<K>,

Просмотреть файл

@ -77,7 +77,7 @@ impl Colorizer {
/// Color-unaware printing. Never uses coloring.
impl std::fmt::Display for Colorizer {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.content.fmt(f)
}
}

Просмотреть файл

@ -6,7 +6,6 @@
// Std
use std::borrow::Cow;
use std::cmp;
use std::usize;
// Internal
use crate::builder::PossibleValue;
@ -74,7 +73,7 @@ const DEFAULT_NO_ARGS_TEMPLATE: &str = "\
{usage-heading} {usage}{after-help}\
";
/// `clap` HelpTemplate Writer.
/// Help template writer
///
/// Wraps a writer stream providing different methods to generate help for `clap` objects.
pub(crate) struct HelpTemplate<'cmd, 'writer> {
@ -393,9 +392,11 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
.filter_map(|arg| arg.get_help_heading())
.collect::<FlatSet<_>>();
let flatten = self.cmd.is_flatten_help_set();
let mut first = true;
if subcmds {
if subcmds && !flatten {
if !first {
self.writer.push_str("\n\n");
}
@ -474,6 +475,11 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
}
}
}
if subcmds && flatten {
let mut cmd = self.cmd.clone();
cmd.build();
self.write_flat_subcommands(&cmd, &mut first);
}
}
/// Sorts arguments by length and display order and write their help to the wrapped stream.
@ -644,7 +650,7 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
let spaces = if next_line_help {
TAB.len() + NEXT_LINE_INDENT.len()
} else if let Some(true) = arg.map(|a| a.is_positional()) {
} else if arg.map(|a| a.is_positional()).unwrap_or(true) {
longest + TAB_WIDTH * 2
} else {
longest + TAB_WIDTH * 2 + 4 // See `fn short` for the 4
@ -677,57 +683,56 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
let help_is_empty = help.is_empty();
self.writer.push_styled(&help);
if let Some(arg) = arg {
const DASH_SPACE: usize = "- ".len();
let possible_vals = arg.get_possible_values();
if !possible_vals.is_empty()
&& !arg.is_hide_possible_values_set()
&& self.use_long_pv(arg)
{
debug!("HelpTemplate::help: Found possible vals...{possible_vals:?}");
let longest = possible_vals
.iter()
.filter(|f| !f.is_hide_set())
.map(|f| display_width(f.get_name()))
.max()
.expect("Only called with possible value");
if !arg.is_hide_possible_values_set() && self.use_long_pv(arg) {
const DASH_SPACE: usize = "- ".len();
let possible_vals = arg.get_possible_values();
if !possible_vals.is_empty() {
debug!("HelpTemplate::help: Found possible vals...{possible_vals:?}");
let longest = possible_vals
.iter()
.filter(|f| !f.is_hide_set())
.map(|f| display_width(f.get_name()))
.max()
.expect("Only called with possible value");
let spaces = spaces + TAB_WIDTH - DASH_SPACE;
let trailing_indent = spaces + DASH_SPACE;
let trailing_indent = self.get_spaces(trailing_indent);
let spaces = spaces + TAB_WIDTH - DASH_SPACE;
let trailing_indent = spaces + DASH_SPACE;
let trailing_indent = self.get_spaces(trailing_indent);
if !help_is_empty {
let _ = write!(self.writer, "\n\n{:spaces$}", "");
}
self.writer.push_str("Possible values:");
for pv in possible_vals.iter().filter(|pv| !pv.is_hide_set()) {
let name = pv.get_name();
let mut descr = StyledStr::new();
let _ = write!(
&mut descr,
"{}{name}{}",
literal.render(),
literal.render_reset()
);
if let Some(help) = pv.get_help() {
debug!("HelpTemplate::help: Possible Value help");
// To align help messages
let padding = longest - display_width(name);
let _ = write!(&mut descr, ": {:padding$}", "");
descr.push_styled(help);
if !help_is_empty {
let _ = write!(self.writer, "\n\n{:spaces$}", "");
}
self.writer.push_str("Possible values:");
for pv in possible_vals.iter().filter(|pv| !pv.is_hide_set()) {
let name = pv.get_name();
let avail_chars = if self.term_w > trailing_indent.len() {
self.term_w - trailing_indent.len()
} else {
usize::MAX
};
descr.replace_newline_var();
descr.wrap(avail_chars);
descr.indent("", &trailing_indent);
let mut descr = StyledStr::new();
let _ = write!(
&mut descr,
"{}{name}{}",
literal.render(),
literal.render_reset()
);
if let Some(help) = pv.get_help() {
debug!("HelpTemplate::help: Possible Value help");
// To align help messages
let padding = longest - display_width(name);
let _ = write!(&mut descr, ": {:padding$}", "");
descr.push_styled(help);
}
let _ = write!(self.writer, "\n{:spaces$}- ", "",);
self.writer.push_styled(&descr);
let avail_chars = if self.term_w > trailing_indent.len() {
self.term_w - trailing_indent.len()
} else {
usize::MAX
};
descr.replace_newline_var();
descr.wrap(avail_chars);
descr.indent("", &trailing_indent);
let _ = write!(self.writer, "\n{:spaces$}- ", "",);
self.writer.push_styled(&descr);
}
}
}
}
@ -749,7 +754,10 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
true
} else {
// force_next_line
let h = arg.get_help().unwrap_or_default();
let h = arg
.get_help()
.or_else(|| arg.get_long_help())
.unwrap_or_default();
let h_w = h.display_width() + display_width(spec_vals);
let taken = if arg.is_positional() {
longest + TAB_WIDTH * 2
@ -837,17 +845,19 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
spec_vals.push(format!("[short aliases: {als}]"));
}
let possible_vals = a.get_possible_values();
if !possible_vals.is_empty() && !a.is_hide_possible_values_set() && !self.use_long_pv(a) {
debug!("HelpTemplate::spec_vals: Found possible vals...{possible_vals:?}");
if !a.is_hide_possible_values_set() && !self.use_long_pv(a) {
let possible_vals = a.get_possible_values();
if !possible_vals.is_empty() {
debug!("HelpTemplate::spec_vals: Found possible vals...{possible_vals:?}");
let pvs = possible_vals
.iter()
.filter_map(PossibleValue::get_visible_quoted_name)
.collect::<Vec<_>>()
.join(", ");
let pvs = possible_vals
.iter()
.filter_map(PossibleValue::get_visible_quoted_name)
.collect::<Vec<_>>()
.join(", ");
spec_vals.push(format!("[possible values: {pvs}]"));
spec_vals.push(format!("[possible values: {pvs}]"));
}
}
let connector = if self.use_long { "\n" } else { " " };
spec_vals.join(connector)
@ -873,6 +883,70 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
/// Subcommand handling
impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
/// Writes help for subcommands of a Parser Object to the wrapped stream.
fn write_flat_subcommands(&mut self, cmd: &Command, first: &mut bool) {
debug!(
"HelpTemplate::write_flat_subcommands, cmd={}, first={}",
cmd.get_name(),
*first
);
use std::fmt::Write as _;
let header = &self.styles.get_header();
let mut ord_v = Vec::new();
for subcommand in cmd
.get_subcommands()
.filter(|subcommand| should_show_subcommand(subcommand))
{
ord_v.push((
subcommand.get_display_order(),
subcommand.get_name(),
subcommand,
));
}
ord_v.sort_by(|a, b| (a.0, &a.1).cmp(&(b.0, &b.1)));
for (_, _, subcommand) in ord_v {
if !*first {
self.writer.push_str("\n\n");
}
*first = false;
let heading = subcommand.get_usage_name_fallback();
let about = subcommand
.get_about()
.or_else(|| subcommand.get_long_about())
.unwrap_or_default();
let _ = write!(
self.writer,
"{}{heading}:{}\n",
header.render(),
header.render_reset()
);
if !about.is_empty() {
let _ = write!(self.writer, "{about}\n",);
}
let mut sub_help = HelpTemplate {
writer: self.writer,
cmd: subcommand,
styles: self.styles,
usage: self.usage,
next_line_help: self.next_line_help,
term_w: self.term_w,
use_long: self.use_long,
};
let args = subcommand
.get_arguments()
.filter(|arg| should_show_arg(self.use_long, arg) && !arg.is_global_set())
.collect::<Vec<_>>();
sub_help.write_args(&args, heading, option_sort_key);
if subcommand.is_flatten_help_set() {
sub_help.write_flat_subcommands(subcommand, first);
}
}
}
/// Writes help for subcommands of a Parser Object to the wrapped stream.
fn write_subcommands(&mut self, cmd: &Command) {
debug!("HelpTemplate::write_subcommands");
@ -959,7 +1033,7 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
.unwrap_or_default();
self.subcmd(sc_str, next_line_help, longest);
self.help(None, about, spec_vals, next_line_help, longest)
self.help(None, about, spec_vals, next_line_help, longest);
}
fn sc_spec_vals(&self, a: &Command) -> String {
@ -995,7 +1069,10 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
true
} else {
// force_next_line
let h = cmd.get_about().unwrap_or_default();
let h = cmd
.get_about()
.or_else(|| cmd.get_long_about())
.unwrap_or_default();
let h_w = h.display_width() + display_width(spec_vals);
let taken = longest + TAB_WIDTH * 2;
self.term_w >= taken

Просмотреть файл

@ -2,7 +2,7 @@
//!
//! Benefits of forking:
//! - Pull in only what we need rather than relying on the compiler to remove what we don't need
//! - `LineWrapper` is able to incrementally wrap which will help with `StyledStr
//! - `LineWrapper` is able to incrementally wrap which will help with `StyledStr`
pub(crate) mod core;
#[cfg(feature = "wrap_help")]

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше