mirror of
https://github.com/clap-rs/clap
synced 2024-11-10 06:44:16 +00:00
chore: Update from template
This commit is contained in:
commit
800d7cb8ad
142 changed files with 853 additions and 852 deletions
|
@ -1,5 +1,4 @@
|
|||
msrv = "1.74" # MSRV
|
||||
warn-on-all-wildcard-imports = true
|
||||
allow-print-in-tests = true
|
||||
allow-expect-in-tests = true
|
||||
allow-unwrap-in-tests = true
|
||||
allow-dbg-in-tests = true
|
||||
|
|
16
.github/renovate.json5
vendored
16
.github/renovate.json5
vendored
|
@ -3,6 +3,7 @@
|
|||
'before 5am on the first day of the month',
|
||||
],
|
||||
semanticCommits: 'enabled',
|
||||
commitMessageLowerCase: 'never',
|
||||
configMigration: true,
|
||||
dependencyDashboard: true,
|
||||
customManagers: [
|
||||
|
@ -19,29 +20,28 @@
|
|||
'^\\.github/workflows/rust-next.yml$',
|
||||
],
|
||||
matchStrings: [
|
||||
'MSRV.*?(?<currentValue>\\d+\\.\\d+(\\.\\d+)?)',
|
||||
'(?<currentValue>\\d+\\.\\d+(\\.\\d+)?).*?MSRV',
|
||||
'STABLE.*?(?<currentValue>\\d+\\.\\d+(\\.\\d+)?)',
|
||||
'(?<currentValue>\\d+\\.\\d+(\\.\\d+)?).*?STABLE',
|
||||
],
|
||||
depNameTemplate: 'rust',
|
||||
depNameTemplate: 'STABLE',
|
||||
packageNameTemplate: 'rust-lang/rust',
|
||||
datasourceTemplate: 'github-releases',
|
||||
},
|
||||
],
|
||||
packageRules: [
|
||||
{
|
||||
commitMessageTopic: 'MSRV',
|
||||
commitMessageTopic: 'Rust Stable',
|
||||
matchManagers: [
|
||||
'custom.regex',
|
||||
],
|
||||
matchPackageNames: [
|
||||
'rust',
|
||||
'STABLE',
|
||||
],
|
||||
minimumReleaseAge: '252 days', // 6 releases * 6 weeks per release * 7 days per week
|
||||
internalChecksFilter: 'strict',
|
||||
extractVersion: '^(?<version>\\d+\\.\\d+)', // Drop the patch version
|
||||
schedule: [
|
||||
'* * * * *',
|
||||
],
|
||||
automerge: true,
|
||||
},
|
||||
// Goals:
|
||||
// - Keep version reqs low, ignoring compatible normal/build dependencies
|
||||
|
@ -74,6 +74,7 @@
|
|||
matchCurrentVersion: '>=1.0.0',
|
||||
matchUpdateTypes: [
|
||||
'minor',
|
||||
'patch',
|
||||
],
|
||||
enabled: false,
|
||||
},
|
||||
|
@ -101,6 +102,7 @@
|
|||
matchCurrentVersion: '>=1.0.0',
|
||||
matchUpdateTypes: [
|
||||
'minor',
|
||||
'patch',
|
||||
],
|
||||
automerge: true,
|
||||
groupName: 'compatible (dev)',
|
||||
|
|
46
.github/settings.yml
vendored
46
.github/settings.yml
vendored
|
@ -101,34 +101,18 @@ repository:
|
|||
# description: "Meta: Request for post-merge review."
|
||||
# color: '#E10C02'
|
||||
|
||||
branches:
|
||||
- name: master
|
||||
protection:
|
||||
required_pull_request_reviews: null
|
||||
required_conversation_resolution: true
|
||||
required_status_checks:
|
||||
# Required. Require branches to be up to date before merging.
|
||||
strict: false
|
||||
contexts: ["CI", "Lint Commits", "Spell Check with Typos"]
|
||||
enforce_admins: false
|
||||
restrictions: null
|
||||
- name: v2-master
|
||||
protection:
|
||||
required_pull_request_reviews: null
|
||||
required_conversation_resolution: true
|
||||
required_status_checks:
|
||||
# Required. Require branches to be up to date before merging.
|
||||
strict: false
|
||||
contexts: ["CI", "Lint Commits", "Spell Check with Typos"]
|
||||
enforce_admins: false
|
||||
restrictions: null
|
||||
- name: v3-master
|
||||
protection:
|
||||
required_pull_request_reviews: null
|
||||
required_conversation_resolution: true
|
||||
required_status_checks:
|
||||
# Required. Require branches to be up to date before merging.
|
||||
strict: false
|
||||
contexts: ["CI", "Lint Commits", "Spell Check with Typos"]
|
||||
enforce_admins: false
|
||||
restrictions: null
|
||||
# This serves more as documentation.
|
||||
# Branch protection API was replaced by rulesets but settings isn't updated.
|
||||
# See https://github.com/repository-settings/app/issues/825
|
||||
#
|
||||
# branches:
|
||||
# - name: master
|
||||
# protection:
|
||||
# required_pull_request_reviews: null
|
||||
# required_conversation_resolution: true
|
||||
# required_status_checks:
|
||||
# # Required. Require branches to be up to date before merging.
|
||||
# strict: false
|
||||
# contexts: ["CI", "Spell Check with Typos"]
|
||||
# enforce_admins: false
|
||||
# restrictions: null
|
||||
|
|
4
.github/workflows/audit.yml
vendored
4
.github/workflows/audit.yml
vendored
|
@ -17,6 +17,10 @@ env:
|
|||
CARGO_TERM_COLOR: always
|
||||
CLICOLOR: 1
|
||||
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
security_audit:
|
||||
permissions:
|
||||
|
|
25
.github/workflows/ci.yml
vendored
25
.github/workflows/ci.yml
vendored
|
@ -14,16 +14,22 @@ env:
|
|||
CARGO_TERM_COLOR: always
|
||||
CLICOLOR: 1
|
||||
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
permissions:
|
||||
contents: none
|
||||
name: CI
|
||||
needs: [test, check, docs, rustfmt, clippy, cffconvert]
|
||||
needs: [test, check, lockfile, docs, rustfmt, clippy, cffconvert]
|
||||
runs-on: ubuntu-latest
|
||||
if: "always()"
|
||||
steps:
|
||||
- name: Done
|
||||
run: exit 0
|
||||
- name: Failed
|
||||
run: exit 1
|
||||
if: "contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped')"
|
||||
test:
|
||||
name: Test
|
||||
strategy:
|
||||
|
@ -39,7 +45,7 @@ jobs:
|
|||
rust: "stable"
|
||||
features: "full"
|
||||
- build: mac
|
||||
os: macos-latest
|
||||
os: macos-14
|
||||
rust: "stable"
|
||||
features: "full"
|
||||
- build: minimal
|
||||
|
@ -64,6 +70,7 @@ jobs:
|
|||
with:
|
||||
toolchain: ${{ matrix.rust }}
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: taiki-e/install-action@cargo-hack
|
||||
- name: Build
|
||||
run: make build-${{matrix.features}}
|
||||
- name: Test
|
||||
|
@ -144,7 +151,7 @@ jobs:
|
|||
toolchain: stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: "Is lockfile updated?"
|
||||
run: cargo fetch --locked
|
||||
run: cargo update --workspace --locked
|
||||
docs:
|
||||
name: Docs
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -154,7 +161,7 @@ jobs:
|
|||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: "1.74" # MSRV
|
||||
toolchain: "1.76" # STABLE
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: Check documentation
|
||||
env:
|
||||
|
@ -169,9 +176,7 @@ jobs:
|
|||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
# Not MSRV because its harder to jump between versions and people are
|
||||
# more likely to have stable
|
||||
toolchain: stable
|
||||
toolchain: "1.76" # STABLE
|
||||
components: rustfmt
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: Check formatting
|
||||
|
@ -185,7 +190,7 @@ jobs:
|
|||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: "1.74" # MSRV
|
||||
toolchain: "1.76" # STABLE
|
||||
components: clippy
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: Lint (ultra-minimal)
|
||||
|
|
4
.github/workflows/committed.yml
vendored
4
.github/workflows/committed.yml
vendored
|
@ -11,6 +11,10 @@ env:
|
|||
CARGO_TERM_COLOR: always
|
||||
CLICOLOR: 1
|
||||
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
committed:
|
||||
name: Lint Commits
|
||||
|
|
4
.github/workflows/pre-commit.yml
vendored
4
.github/workflows/pre-commit.yml
vendored
|
@ -12,6 +12,10 @@ env:
|
|||
CARGO_TERM_COLOR: always
|
||||
CLICOLOR: 1
|
||||
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
permissions:
|
||||
|
|
7
.github/workflows/rust-next.yml
vendored
7
.github/workflows/rust-next.yml
vendored
|
@ -12,6 +12,10 @@ env:
|
|||
CARGO_TERM_COLOR: always
|
||||
CLICOLOR: 1
|
||||
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
|
@ -32,7 +36,7 @@ jobs:
|
|||
rust: "beta"
|
||||
features: "full"
|
||||
- build: mac
|
||||
os: macos-latest
|
||||
os: macos-14
|
||||
rust: "beta"
|
||||
features: "full"
|
||||
- build: nightly
|
||||
|
@ -91,6 +95,7 @@ jobs:
|
|||
with:
|
||||
toolchain: stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: taiki-e/install-action@cargo-hack
|
||||
- name: Update dependencues
|
||||
run: cargo update
|
||||
- name: Build
|
||||
|
|
4
.github/workflows/spelling.yml
vendored
4
.github/workflows/spelling.yml
vendored
|
@ -10,6 +10,10 @@ env:
|
|||
CARGO_TERM_COLOR: always
|
||||
CLICOLOR: 1
|
||||
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
spelling:
|
||||
name: Spell Check with Typos
|
||||
|
|
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -160,6 +160,17 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "automod"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edf3ee19dbc0a46d740f6f0926bde8c50f02bdbc7b536842da28f6ac56513a8b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.67"
|
||||
|
@ -401,6 +412,7 @@ dependencies = [
|
|||
name = "clap"
|
||||
version = "4.5.4"
|
||||
dependencies = [
|
||||
"automod",
|
||||
"clap_builder 4.5.2",
|
||||
"clap_derive",
|
||||
"humantime",
|
||||
|
@ -454,6 +466,7 @@ dependencies = [
|
|||
name = "clap_complete"
|
||||
version = "4.5.2"
|
||||
dependencies = [
|
||||
"automod",
|
||||
"clap 4.5.4",
|
||||
"clap_lex 0.7.0",
|
||||
"completest",
|
||||
|
@ -505,11 +518,15 @@ checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
|
|||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"automod",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_mangen"
|
||||
version = "0.2.20"
|
||||
dependencies = [
|
||||
"automod",
|
||||
"clap 4.5.4",
|
||||
"roff",
|
||||
"snapbox",
|
||||
|
|
77
Cargo.toml
77
Cargo.toml
|
@ -25,6 +25,79 @@ include = [
|
|||
"examples/**/*"
|
||||
]
|
||||
|
||||
[workspace.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"
|
||||
|
||||
[workspace.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"
|
||||
large_digit_groups = "warn"
|
||||
large_stack_arrays = "warn"
|
||||
large_types_passed_by_value = "warn"
|
||||
let_and_return = "allow" # sometimes good to name what you are returning
|
||||
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"
|
||||
# Fix later:
|
||||
multiple_bound_locations = "allow"
|
||||
assigning_clones = "allow"
|
||||
blocks_in_conditions = "allow"
|
||||
|
||||
[package]
|
||||
name = "clap"
|
||||
version = "4.5.4"
|
||||
|
@ -113,6 +186,7 @@ trycmd = { version = "0.15.1", default-features = false, features = ["color-auto
|
|||
humantime = "2.1.0"
|
||||
snapbox = "0.5.9"
|
||||
shlex = "1.3.0"
|
||||
automod = "1.0.14"
|
||||
|
||||
[[example]]
|
||||
name = "demo"
|
||||
|
@ -381,3 +455,6 @@ opt-level = 1
|
|||
[profile.bench]
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -35,3 +35,6 @@ name = "rustup"
|
|||
[[bench]]
|
||||
harness = false
|
||||
name = "ripgrep"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(elided_lifetimes_in_paths)] // needed for divan
|
||||
|
||||
use clap::{arg, ArgMatches, Command};
|
||||
|
||||
macro_rules! create_app {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(elided_lifetimes_in_paths)] // needed for divan
|
||||
|
||||
use clap::ArgMatches;
|
||||
use clap::Command;
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
// Used to simulate a fairly large number of options/flags and parsing with thousands of positional
|
||||
// args
|
||||
//
|
||||
// CLI used is adapted from ripgrep 48a8a3a691220f9e5b2b08f4051abe8655ea7e8a
|
||||
//! Used to simulate a fairly large number of options/flags and parsing with thousands of positional
|
||||
//! args
|
||||
//!
|
||||
//! CLI used is adapted from ripgrep 48a8a3a691220f9e5b2b08f4051abe8655ea7e8a
|
||||
|
||||
#![allow(elided_lifetimes_in_paths)] // needed for divan
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
@ -9,7 +11,7 @@ use clap::{value_parser, Arg, ArgAction, ArgMatches, Command};
|
|||
use lazy_static::lazy_static;
|
||||
|
||||
mod build {
|
||||
use super::*;
|
||||
use super::{app_long, app_short, Command};
|
||||
|
||||
#[divan::bench]
|
||||
fn short_help() -> Command {
|
||||
|
@ -23,7 +25,7 @@ mod build {
|
|||
}
|
||||
|
||||
mod render_help {
|
||||
use super::*;
|
||||
use super::{app_long, app_short, build_help};
|
||||
|
||||
#[divan::bench]
|
||||
fn short_help(bencher: divan::Bencher) {
|
||||
|
@ -39,7 +41,7 @@ mod render_help {
|
|||
}
|
||||
|
||||
mod startup {
|
||||
use super::*;
|
||||
use super::{app_short, ArgMatches};
|
||||
|
||||
#[divan::bench]
|
||||
fn simple() -> ArgMatches {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Used to simulate a fairly large number of subcommands
|
||||
//
|
||||
// CLI used is from rustup 408ed84f0e50511ed44a405dd91365e5da588790
|
||||
//! Used to simulate a fairly large number of subcommands
|
||||
//!
|
||||
//! CLI used is from rustup 408ed84f0e50511ed44a405dd91365e5da588790
|
||||
|
||||
#![allow(elided_lifetimes_in_paths)] // needed for divan
|
||||
|
||||
use clap::{Arg, ArgAction, ArgGroup, ArgMatches, Command};
|
||||
|
||||
|
@ -10,7 +12,7 @@ fn build() -> Command {
|
|||
}
|
||||
|
||||
mod startup {
|
||||
use super::*;
|
||||
use super::{build_cli, ArgMatches};
|
||||
|
||||
#[divan::bench]
|
||||
fn empty() -> ArgMatches {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(elided_lifetimes_in_paths)] // needed for divan
|
||||
|
||||
use clap::{arg, ArgMatches, Command};
|
||||
|
||||
macro_rules! create_app {
|
||||
|
@ -18,7 +20,7 @@ fn build() -> Command {
|
|||
}
|
||||
|
||||
mod startup {
|
||||
use super::*;
|
||||
use super::{arg, ArgMatches, Command};
|
||||
|
||||
#[divan::bench]
|
||||
fn flag() -> ArgMatches {
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(clippy::print_stderr)]
|
||||
#![warn(clippy::print_stdout)]
|
||||
|
|
|
@ -71,3 +71,6 @@ unicode-width = { version = "0.1.9", optional = true }
|
|||
static_assertions = "1.1.0"
|
||||
unic-emoji-char = "0.9.0"
|
||||
color-print = "0.3.6"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -510,10 +510,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 `--`.
|
||||
///
|
||||
|
@ -875,7 +875,7 @@ impl Arg {
|
|||
impl Arg {
|
||||
/// Specify how to react to an argument when parsing it.
|
||||
///
|
||||
/// [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 +997,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 +1018,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};
|
||||
|
@ -3641,8 +3641,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 +3701,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.
|
||||
///
|
||||
|
@ -3992,7 +3992,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> {
|
||||
|
@ -4094,8 +4094,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)
|
||||
}
|
||||
|
||||
|
@ -4202,7 +4202,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 =
|
||||
|
@ -4211,9 +4211,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);
|
||||
}
|
||||
|
@ -4432,14 +4432,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)]
|
||||
|
@ -4519,7 +4519,7 @@ mod test {
|
|||
.action(ArgAction::SetTrue);
|
||||
f._build();
|
||||
|
||||
assert_eq!(f.to_string(), "--flag")
|
||||
assert_eq!(f.to_string(), "--flag");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -4542,7 +4542,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]
|
||||
|
|
|
@ -447,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
|
||||
|
@ -545,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
|
||||
|
@ -584,7 +584,7 @@ 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)
|
||||
}
|
||||
|
||||
|
@ -2567,7 +2567,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
|
||||
}
|
||||
|
@ -3750,7 +3750,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
|
||||
|
@ -4592,7 +4592,7 @@ impl Command {
|
|||
|
||||
#[inline]
|
||||
pub(crate) fn set(&mut self, s: AppSettings) {
|
||||
self.settings.set(s)
|
||||
self.settings.set(s);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -4656,7 +4656,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();
|
||||
|
@ -4699,7 +4699,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);
|
||||
|
@ -4730,7 +4730,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);
|
||||
|
@ -4880,11 +4880,12 @@ 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 {}
|
||||
|
||||
#[derive(Default, Copy, Clone, Debug)]
|
||||
|
|
|
@ -398,26 +398,24 @@ 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> {
|
||||
fn partial_cmp(&self, other: &Flag<'_>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Flag<'_> {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
use Flag::*;
|
||||
|
||||
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 {
|
||||
Ordering::Equal
|
||||
} else {
|
||||
|
@ -428,20 +426,18 @@ impl Ord for Flag<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
@ -735,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()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,11 +49,6 @@ 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
|
||||
|
@ -75,9 +70,6 @@ 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())
|
||||
}
|
||||
|
|
|
@ -85,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())
|
||||
}
|
||||
}
|
||||
|
@ -210,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())
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -49,13 +49,13 @@ impl StyledStr {
|
|||
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")]
|
||||
|
@ -156,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
|
||||
|
@ -200,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,7 +2,7 @@ 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.
|
||||
///
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
@ -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> {}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -545,7 +545,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,
|
||||
};
|
||||
|
||||
|
@ -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())
|
||||
}
|
||||
|
||||
|
@ -455,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 {
|
||||
|
@ -832,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)
|
||||
}
|
||||
}
|
||||
|
@ -846,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() {
|
||||
|
@ -884,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);
|
||||
|
@ -921,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)
|
||||
}
|
||||
|
@ -940,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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,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> {
|
||||
|
@ -1031,7 +1031,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 {
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -114,7 +114,7 @@ impl ArgMatcher {
|
|||
self.matches.args.iter()
|
||||
}
|
||||
|
||||
pub(crate) fn entry(&mut self, arg: Id) -> crate::util::Entry<Id, MatchedArg> {
|
||||
pub(crate) fn entry(&mut self, arg: Id) -> crate::util::Entry<'_, Id, MatchedArg> {
|
||||
self.matches.args.entry(arg)
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ impl ArgMatcher {
|
|||
ma.new_val_group();
|
||||
}
|
||||
|
||||
pub(crate) fn start_occurrence_of_external(&mut self, cmd: &crate::Command) {
|
||||
pub(crate) fn start_occurrence_of_external(&mut self, cmd: &Command) {
|
||||
let id = Id::from_static_ref(Id::EXTERNAL);
|
||||
debug!("ArgMatcher::start_occurrence_of_external: id={id:?}");
|
||||
let ma = self.entry(id).or_insert(MatchedArg::new_external(cmd));
|
||||
|
|
|
@ -36,7 +36,7 @@ impl MatchesError {
|
|||
impl std::error::Error for MatchesError {}
|
||||
|
||||
impl std::fmt::Display for MatchesError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Downcast { actual, expected } => {
|
||||
writeln!(
|
||||
|
|
|
@ -221,7 +221,7 @@ impl ArgMatches {
|
|||
pub fn get_many<T: Any + Clone + Send + Sync + 'static>(
|
||||
&self,
|
||||
id: &str,
|
||||
) -> Option<ValuesRef<T>> {
|
||||
) -> Option<ValuesRef<'_, T>> {
|
||||
MatchesError::unwrap(id, self.try_get_many(id))
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ impl ArgMatches {
|
|||
pub fn get_occurrences<T: Any + Clone + Send + Sync + 'static>(
|
||||
&self,
|
||||
id: &str,
|
||||
) -> Option<OccurrencesRef<T>> {
|
||||
) -> Option<OccurrencesRef<'_, T>> {
|
||||
MatchesError::unwrap(id, self.try_get_occurrences(id))
|
||||
}
|
||||
|
||||
|
@ -1077,7 +1077,7 @@ impl ArgMatches {
|
|||
pub fn try_get_many<T: Any + Clone + Send + Sync + 'static>(
|
||||
&self,
|
||||
id: &str,
|
||||
) -> Result<Option<ValuesRef<T>>, MatchesError> {
|
||||
) -> Result<Option<ValuesRef<'_, T>>, MatchesError> {
|
||||
let arg = match ok!(self.try_get_arg_t::<T>(id)) {
|
||||
Some(arg) => arg,
|
||||
None => return Ok(None),
|
||||
|
@ -1096,7 +1096,7 @@ impl ArgMatches {
|
|||
pub fn try_get_occurrences<T: Any + Clone + Send + Sync + 'static>(
|
||||
&self,
|
||||
id: &str,
|
||||
) -> Result<Option<OccurrencesRef<T>>, MatchesError> {
|
||||
) -> Result<Option<OccurrencesRef<'_, T>>, MatchesError> {
|
||||
let arg = match ok!(self.try_get_arg_t::<T>(id)) {
|
||||
Some(arg) => arg,
|
||||
None => return Ok(None),
|
||||
|
@ -1348,7 +1348,7 @@ pub(crate) struct SubCommand {
|
|||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IdsRef<'a> {
|
||||
iter: std::slice::Iter<'a, Id>,
|
||||
iter: Iter<'a, Id>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for IdsRef<'a> {
|
||||
|
@ -1585,7 +1585,7 @@ impl Default for RawValues<'_> {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
#[deprecated(since = "4.1.0", note = "Use Occurrences instead")]
|
||||
pub struct GroupedValues<'a> {
|
||||
pub(crate) struct GroupedValues<'a> {
|
||||
#[allow(clippy::type_complexity)]
|
||||
iter: Map<Iter<'a, Vec<AnyValue>>, fn(&Vec<AnyValue>) -> Vec<&str>>,
|
||||
len: usize,
|
||||
|
@ -1926,13 +1926,13 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_default_raw_values() {
|
||||
let mut values: RawValues = Default::default();
|
||||
let mut values: RawValues<'_> = Default::default();
|
||||
assert_eq!(values.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_indices() {
|
||||
let mut indices: Indices = Indices::default();
|
||||
let mut indices: Indices<'_> = Indices::default();
|
||||
assert_eq!(indices.next(), None);
|
||||
}
|
||||
|
||||
|
@ -1972,7 +1972,7 @@ mod tests {
|
|||
)
|
||||
.try_get_matches_from(["test", "one"])
|
||||
.unwrap()
|
||||
.get_many::<std::ffi::OsString>("POTATO")
|
||||
.get_many::<OsString>("POTATO")
|
||||
.expect("present")
|
||||
.count();
|
||||
assert_eq!(l, 1);
|
||||
|
|
|
@ -72,10 +72,10 @@ impl MatchedArg {
|
|||
}
|
||||
|
||||
pub(crate) fn push_index(&mut self, index: usize) {
|
||||
self.indices.push(index)
|
||||
self.indices.push(index);
|
||||
}
|
||||
|
||||
pub(crate) fn vals(&self) -> Iter<Vec<AnyValue>> {
|
||||
pub(crate) fn vals(&self) -> Iter<'_, Vec<AnyValue>> {
|
||||
self.vals.iter()
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ impl MatchedArg {
|
|||
self.vals
|
||||
}
|
||||
|
||||
pub(crate) fn vals_flatten(&self) -> Flatten<Iter<Vec<AnyValue>>> {
|
||||
pub(crate) fn vals_flatten(&self) -> Flatten<Iter<'_, Vec<AnyValue>>> {
|
||||
self.vals.iter().flatten()
|
||||
}
|
||||
|
||||
|
@ -91,11 +91,11 @@ impl MatchedArg {
|
|||
self.vals.into_iter().flatten()
|
||||
}
|
||||
|
||||
pub(crate) fn raw_vals(&self) -> Iter<Vec<OsString>> {
|
||||
pub(crate) fn raw_vals(&self) -> Iter<'_, Vec<OsString>> {
|
||||
self.raw_vals.iter()
|
||||
}
|
||||
|
||||
pub(crate) fn raw_vals_flatten(&self) -> Flatten<Iter<Vec<OsString>>> {
|
||||
pub(crate) fn raw_vals_flatten(&self) -> Flatten<Iter<'_, Vec<OsString>>> {
|
||||
self.raw_vals.iter().flatten()
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ impl MatchedArg {
|
|||
if let Some(existing) = self.source {
|
||||
self.source = Some(existing.max(source));
|
||||
} else {
|
||||
self.source = Some(source)
|
||||
self.source = Some(source);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -745,7 +745,7 @@ impl<'cmd> Parser<'cmd> {
|
|||
// maybe here lifetime should be 'a
|
||||
debug!("Parser::parse_long_arg");
|
||||
|
||||
#[allow(clippy::blocks_in_if_conditions)]
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if
|
||||
self.cmd[opt].is_allow_hyphen_values_set())
|
||||
{
|
||||
|
@ -863,7 +863,7 @@ impl<'cmd> Parser<'cmd> {
|
|||
) -> ClapResult<ParseResult> {
|
||||
debug!("Parser::parse_short_arg: short_arg={short_arg:?}");
|
||||
|
||||
#[allow(clippy::blocks_in_if_conditions)]
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt)
|
||||
if self.cmd[opt].is_allow_hyphen_values_set() || (self.cmd[opt].is_allow_negative_numbers_set() && short_arg.is_negative_number()))
|
||||
{
|
||||
|
@ -1165,7 +1165,7 @@ impl<'cmd> Parser<'cmd> {
|
|||
split_raw_vals.extend(raw_val.split(val_delim).map(|x| x.to_owned()));
|
||||
}
|
||||
}
|
||||
raw_vals = split_raw_vals
|
||||
raw_vals = split_raw_vals;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ impl<'cmd> Validator<'cmd> {
|
|||
let args_count = matcher
|
||||
.args()
|
||||
.filter(|(arg_id, matched)| {
|
||||
matched.check_explicit(&crate::builder::ArgPredicate::IsPresent)
|
||||
matched.check_explicit(&ArgPredicate::IsPresent)
|
||||
// Avoid including our own groups by checking none of them. If a group is present, the
|
||||
// args for the group will be.
|
||||
&& self.cmd.find(arg_id).is_some()
|
||||
|
@ -125,15 +125,14 @@ impl<'cmd> Validator<'cmd> {
|
|||
|
||||
matcher
|
||||
.args()
|
||||
.filter(|(_, matched)| matched.check_explicit(&crate::builder::ArgPredicate::IsPresent))
|
||||
.filter_map(|(id, _)| {
|
||||
.filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
|
||||
.find_map(|(id, _)| {
|
||||
debug!("Validator::validate_exclusive:iter:{id:?}");
|
||||
self.cmd
|
||||
.find(id)
|
||||
// Find `arg`s which are exclusive but also appear with other args.
|
||||
.filter(|&arg| arg.is_exclusive_set() && args_count > 1)
|
||||
})
|
||||
.next()
|
||||
.map(|arg| {
|
||||
// Throw an error for the first conflict found.
|
||||
Err(Error::argument_conflict(
|
||||
|
|
|
@ -39,7 +39,7 @@ impl<K: PartialEq + Eq, V> FlatMap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
|
||||
pub(crate) fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Eq,
|
||||
|
@ -52,7 +52,7 @@ impl<K: PartialEq + Eq, V> FlatMap<K, V> {
|
|||
false
|
||||
}
|
||||
|
||||
pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
|
||||
pub(crate) fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: std::hash::Hash + Eq,
|
||||
|
@ -60,7 +60,7 @@ impl<K: PartialEq + Eq, V> FlatMap<K, V> {
|
|||
self.remove_entry(key).map(|(_, v)| v)
|
||||
}
|
||||
|
||||
pub fn remove_entry<Q: ?Sized>(&mut self, key: &Q) -> Option<(K, V)>
|
||||
pub(crate) fn remove_entry<Q: ?Sized>(&mut self, key: &Q) -> Option<(K, V)>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: std::hash::Hash + Eq,
|
||||
|
@ -79,7 +79,7 @@ impl<K: PartialEq + Eq, V> FlatMap<K, V> {
|
|||
self.keys.is_empty()
|
||||
}
|
||||
|
||||
pub fn entry(&mut self, key: K) -> Entry<K, V> {
|
||||
pub(crate) fn entry(&mut self, key: K) -> Entry<'_, K, V> {
|
||||
for (index, existing) in self.keys.iter().enumerate() {
|
||||
if *existing == key {
|
||||
return Entry::Occupied(OccupiedEntry { v: self, index });
|
||||
|
@ -88,7 +88,7 @@ impl<K: PartialEq + Eq, V> FlatMap<K, V> {
|
|||
Entry::Vacant(VacantEntry { v: self, key })
|
||||
}
|
||||
|
||||
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
|
||||
pub(crate) fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Eq,
|
||||
|
@ -101,7 +101,7 @@ impl<K: PartialEq + Eq, V> FlatMap<K, V> {
|
|||
None
|
||||
}
|
||||
|
||||
pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
|
||||
pub(crate) fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Eq,
|
||||
|
@ -114,18 +114,18 @@ impl<K: PartialEq + Eq, V> FlatMap<K, V> {
|
|||
None
|
||||
}
|
||||
|
||||
pub fn keys(&self) -> std::slice::Iter<'_, K> {
|
||||
pub(crate) fn keys(&self) -> std::slice::Iter<'_, K> {
|
||||
self.keys.iter()
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> Iter<K, V> {
|
||||
pub(crate) fn iter(&self) -> Iter<'_, K, V> {
|
||||
Iter {
|
||||
keys: self.keys.iter(),
|
||||
values: self.values.iter(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter_mut(&mut self) -> IterMut<K, V> {
|
||||
pub(crate) fn iter_mut(&mut self) -> IterMut<'_, K, V> {
|
||||
IterMut {
|
||||
keys: self.keys.iter_mut(),
|
||||
values: self.values.iter_mut(),
|
||||
|
@ -142,13 +142,13 @@ impl<K: PartialEq + Eq, V> Default for FlatMap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum Entry<'a, K: 'a, V: 'a> {
|
||||
pub(crate) enum Entry<'a, K, V> {
|
||||
Vacant(VacantEntry<'a, K, V>),
|
||||
Occupied(OccupiedEntry<'a, K, V>),
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a> Entry<'a, K, V> {
|
||||
pub fn or_insert(self, default: V) -> &'a mut V {
|
||||
pub(crate) fn or_insert(self, default: V) -> &'a mut V {
|
||||
match self {
|
||||
Entry::Occupied(entry) => &mut entry.v.values[entry.index],
|
||||
Entry::Vacant(entry) => {
|
||||
|
@ -159,7 +159,7 @@ impl<'a, K: 'a, V: 'a> Entry<'a, K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
|
||||
pub(crate) fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
|
||||
match self {
|
||||
Entry::Occupied(entry) => &mut entry.v.values[entry.index],
|
||||
Entry::Vacant(entry) => {
|
||||
|
@ -171,17 +171,17 @@ impl<'a, K: 'a, V: 'a> Entry<'a, K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct VacantEntry<'a, K: 'a, V: 'a> {
|
||||
pub(crate) struct VacantEntry<'a, K, V> {
|
||||
v: &'a mut FlatMap<K, V>,
|
||||
key: K,
|
||||
}
|
||||
|
||||
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
|
||||
pub(crate) struct OccupiedEntry<'a, K, V> {
|
||||
v: &'a mut FlatMap<K, V>,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
pub struct Iter<'a, K: 'a, V: 'a> {
|
||||
pub(crate) struct Iter<'a, K, V> {
|
||||
keys: std::slice::Iter<'a, K>,
|
||||
values: std::slice::Iter<'a, V>,
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
|
|||
|
||||
impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {}
|
||||
|
||||
pub struct IterMut<'a, K: 'a, V: 'a> {
|
||||
pub(crate) struct IterMut<'a, K, V> {
|
||||
keys: std::slice::IterMut<'a, K>,
|
||||
values: std::slice::IterMut<'a, V>,
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ impl<T: PartialEq + Eq> FlatSet<T> {
|
|||
true
|
||||
}
|
||||
|
||||
pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
|
||||
pub(crate) fn contains<Q: ?Sized>(&self, value: &Q) -> bool
|
||||
where
|
||||
T: Borrow<Q>,
|
||||
Q: Eq,
|
||||
|
@ -38,7 +38,7 @@ impl<T: PartialEq + Eq> FlatSet<T> {
|
|||
false
|
||||
}
|
||||
|
||||
pub fn retain<F>(&mut self, f: F)
|
||||
pub(crate) fn retain<F>(&mut self, f: F)
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ impl<T: PartialEq + Eq> FlatSet<T> {
|
|||
self.inner.iter()
|
||||
}
|
||||
|
||||
pub fn sort_by_key<K, F>(&mut self, f: F)
|
||||
pub(crate) fn sort_by_key<K, F>(&mut self, f: F)
|
||||
where
|
||||
F: FnMut(&T) -> K,
|
||||
K: Ord,
|
||||
|
|
|
@ -46,15 +46,15 @@ impl From<&'_ Str> for Id {
|
|||
}
|
||||
|
||||
#[cfg(feature = "string")]
|
||||
impl From<std::string::String> for Id {
|
||||
fn from(name: std::string::String) -> Self {
|
||||
impl From<String> for Id {
|
||||
fn from(name: String) -> Self {
|
||||
Self(name.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "string")]
|
||||
impl From<&'_ std::string::String> for Id {
|
||||
fn from(name: &'_ std::string::String) -> Self {
|
||||
impl From<&'_ String> for Id {
|
||||
fn from(name: &'_ String) -> Self {
|
||||
Self(name.into())
|
||||
}
|
||||
}
|
||||
|
@ -150,13 +150,13 @@ impl PartialEq<Id> for Str {
|
|||
}
|
||||
}
|
||||
|
||||
impl PartialEq<std::string::String> for Id {
|
||||
impl PartialEq<String> for Id {
|
||||
#[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<Id> for std::string::String {
|
||||
impl PartialEq<Id> for String {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Id) -> bool {
|
||||
PartialEq::eq(other, self)
|
||||
|
|
|
@ -48,6 +48,7 @@ trycmd = { version = "0.15.1", default-features = false, features = ["color-auto
|
|||
completest = "0.4.0"
|
||||
completest-pty = "0.5.0"
|
||||
clap = { path = "../", version = "4.0.0", default-features = false, features = ["std", "derive", "help"] }
|
||||
automod = "1.0.14"
|
||||
|
||||
[[example]]
|
||||
name = "dynamic"
|
||||
|
@ -58,3 +59,6 @@ default = []
|
|||
unstable-doc = ["unstable-dynamic"] # for docs.rs
|
||||
unstable-dynamic = ["dep:clap_lex", "dep:shlex", "dep:unicode-xid", "clap/derive", "dep:is_executable", "dep:pathdiff"]
|
||||
debug = ["clap/debug"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! Example to test arguments with different ValueHint values.
|
||||
//! Example to test arguments with different `ValueHint` values.
|
||||
//!
|
||||
//! Usage with zsh:
|
||||
//! ```console
|
||||
|
|
|
@ -20,7 +20,7 @@ pub trait Completer {
|
|||
fn write_complete(
|
||||
&self,
|
||||
cmd: &mut clap::Command,
|
||||
args: Vec<std::ffi::OsString>,
|
||||
args: Vec<OsString>,
|
||||
current_dir: Option<&std::path::Path>,
|
||||
buf: &mut dyn std::io::Write,
|
||||
) -> Result<(), std::io::Error>;
|
||||
|
@ -29,10 +29,10 @@ pub trait Completer {
|
|||
/// Complete the given command
|
||||
pub fn complete(
|
||||
cmd: &mut clap::Command,
|
||||
args: Vec<std::ffi::OsString>,
|
||||
args: Vec<OsString>,
|
||||
arg_index: usize,
|
||||
current_dir: Option<&std::path::Path>,
|
||||
) -> Result<Vec<(std::ffi::OsString, Option<StyledStr>)>, std::io::Error> {
|
||||
) -> Result<Vec<(OsString, Option<StyledStr>)>, std::io::Error> {
|
||||
cmd.build();
|
||||
|
||||
let raw_args = clap_lex::RawArgs::new(args);
|
||||
|
@ -91,7 +91,7 @@ fn complete_arg(
|
|||
current_dir: Option<&std::path::Path>,
|
||||
pos_index: usize,
|
||||
is_escaped: bool,
|
||||
) -> Result<Vec<(std::ffi::OsString, Option<StyledStr>)>, std::io::Error> {
|
||||
) -> Result<Vec<(OsString, Option<StyledStr>)>, std::io::Error> {
|
||||
debug!(
|
||||
"complete_arg: arg={:?}, cmd={:?}, current_dir={:?}, pos_index={}, is_escaped={}",
|
||||
arg,
|
||||
|
@ -114,7 +114,7 @@ fn complete_arg(
|
|||
// HACK: Need better `OsStr` manipulation
|
||||
(format!("--{}={}", flag, os.to_string_lossy()).into(), help)
|
||||
}),
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
completions.extend(longs_and_visible_aliases(cmd).into_iter().filter_map(
|
||||
|
|
|
@ -8,9 +8,9 @@ use clap::ValueEnum;
|
|||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
pub enum Shell {
|
||||
/// Bourne Again SHell (bash)
|
||||
/// Bourne Again `SHell` (bash)
|
||||
Bash,
|
||||
/// Friendly Interactive SHell (fish)
|
||||
/// Friendly Interactive `SHell` (fish)
|
||||
Fish,
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ impl ValueEnum for Shell {
|
|||
&[Shell::Bash, Shell::Fish]
|
||||
}
|
||||
|
||||
fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
|
||||
fn to_possible_value(&self) -> Option<PossibleValue> {
|
||||
Some(match self {
|
||||
Shell::Bash => PossibleValue::new("bash"),
|
||||
Shell::Fish => PossibleValue::new("fish"),
|
||||
|
|
|
@ -252,10 +252,10 @@ where
|
|||
S: Into<String>,
|
||||
{
|
||||
cmd.set_bin_name(bin_name);
|
||||
_generate::<G>(gen, cmd, buf)
|
||||
_generate::<G>(gen, cmd, buf);
|
||||
}
|
||||
|
||||
fn _generate<G: Generator>(gen: G, cmd: &mut Command, buf: &mut dyn Write) {
|
||||
cmd.build();
|
||||
gen.generate(cmd, buf)
|
||||
gen.generate(cmd, buf);
|
||||
}
|
||||
|
|
|
@ -56,6 +56,11 @@
|
|||
//! }
|
||||
//! ```
|
||||
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![warn(missing_docs)]
|
||||
#![warn(clippy::print_stderr)]
|
||||
#![warn(clippy::print_stdout)]
|
||||
|
||||
const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \
|
||||
report at https://github.com/clap-rs/clap/issues";
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{fmt::Write as _, io::Write};
|
||||
|
||||
use clap::*;
|
||||
use clap::{Arg, Command, ValueHint};
|
||||
|
||||
use crate::generator::{utils, Generator};
|
||||
|
||||
|
@ -204,7 +204,7 @@ fn option_details_for_path(cmd: &Command, path: &str) -> String {
|
|||
]);
|
||||
}
|
||||
|
||||
v.extend(["return 0", ";;"].iter().map(|s| s.to_string()));
|
||||
v.extend(["return 0", ";;"].iter().map(|s| (*s).to_string()));
|
||||
v.join("\n ")
|
||||
}));
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ fn option_details_for_path(cmd: &Command, path: &str) -> String {
|
|||
]);
|
||||
}
|
||||
|
||||
v.extend(["return 0", ";;"].iter().map(|s| s.to_string()));
|
||||
v.extend(["return 0", ";;"].iter().map(|s| (*s).to_string()));
|
||||
v.join("\n ")
|
||||
}));
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ fn option_details_for_path(cmd: &Command, path: &str) -> String {
|
|||
fn vals_for(o: &Arg) -> String {
|
||||
debug!("vals_for: o={}", o.get_id());
|
||||
|
||||
if let Some(vals) = crate::generator::utils::possible_values(o) {
|
||||
if let Some(vals) = utils::possible_values(o) {
|
||||
format!(
|
||||
"$(compgen -W \"{}\" -- \"${{cur}}\")",
|
||||
vals.iter()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::io::Write;
|
||||
|
||||
use clap::builder::StyledStr;
|
||||
use clap::*;
|
||||
use clap::Command;
|
||||
|
||||
use crate::generator::{utils, Generator};
|
||||
use crate::INTERNAL_ERROR_MSG;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::io::Write;
|
||||
|
||||
use clap::*;
|
||||
use clap::{builder, Arg, Command, ValueHint};
|
||||
|
||||
use crate::generator::{utils, Generator};
|
||||
|
||||
|
@ -36,7 +36,7 @@ fn escape_string(string: &str, escape_comma: bool) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
fn escape_help(help: &clap::builder::StyledStr) -> String {
|
||||
fn escape_help(help: &builder::StyledStr) -> String {
|
||||
escape_string(&help.to_string().replace('\n', " "), false)
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ fn gen_fish_inner(
|
|||
template.push_str(format!(" -a \"{}\"", &subcommand.get_name()).as_str());
|
||||
|
||||
if let Some(data) = subcommand.get_about() {
|
||||
template.push_str(format!(" -d '{}'", escape_help(data)).as_str())
|
||||
template.push_str(format!(" -d '{}'", escape_help(data)).as_str());
|
||||
}
|
||||
|
||||
buffer.push_str(template.as_str());
|
||||
|
@ -161,7 +161,7 @@ fn value_completion(option: &Arg) -> String {
|
|||
return "".to_string();
|
||||
}
|
||||
|
||||
if let Some(data) = crate::generator::utils::possible_values(option) {
|
||||
if let Some(data) = utils::possible_values(option) {
|
||||
// We return the possible values with their own empty description e.g. {a\t,b\t}
|
||||
// this makes sure that a and b don't get the description of the option or argument
|
||||
format!(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::io::Write;
|
||||
|
||||
use clap::builder::StyledStr;
|
||||
use clap::*;
|
||||
use clap::{Arg, Command};
|
||||
|
||||
use crate::generator::{utils, Generator};
|
||||
use crate::INTERNAL_ERROR_MSG;
|
||||
|
|
|
@ -12,15 +12,15 @@ use crate::Generator;
|
|||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
pub enum Shell {
|
||||
/// Bourne Again SHell (bash)
|
||||
/// Bourne Again `SHell` (bash)
|
||||
Bash,
|
||||
/// Elvish shell
|
||||
Elvish,
|
||||
/// Friendly Interactive SHell (fish)
|
||||
/// Friendly Interactive `SHell` (fish)
|
||||
Fish,
|
||||
/// PowerShell
|
||||
/// `PowerShell`
|
||||
PowerShell,
|
||||
/// Z SHell (zsh)
|
||||
/// Z `SHell` (zsh)
|
||||
Zsh,
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ impl ValueEnum for Shell {
|
|||
]
|
||||
}
|
||||
|
||||
fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
|
||||
fn to_possible_value(&self) -> Option<PossibleValue> {
|
||||
Some(match self {
|
||||
Shell::Bash => PossibleValue::new("bash"),
|
||||
Shell::Elvish => PossibleValue::new("elvish"),
|
||||
|
@ -113,7 +113,7 @@ impl Shell {
|
|||
/// from that.
|
||||
///
|
||||
/// If SHELL is not set, then on windows, it will default to powershell, and on
|
||||
/// other OSes it will return `None`.
|
||||
/// other operating systems it will return `None`.
|
||||
///
|
||||
/// If SHELL is set, but contains a value that doesn't correspond to one of the supported shell
|
||||
/// types, then return `None`.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::io::Write;
|
||||
|
||||
use clap::*;
|
||||
use clap::{Arg, ArgAction, Command, ValueHint};
|
||||
|
||||
use crate::generator::{utils, Generator};
|
||||
use crate::INTERNAL_ERROR_MSG;
|
||||
|
@ -356,7 +356,7 @@ fn get_args_of(parent: &Command, p_global: Option<&Command>) -> String {
|
|||
|
||||
// Uses either `possible_vals` or `value_hint` to give hints about possible argument values
|
||||
fn value_completion(arg: &Arg) -> Option<String> {
|
||||
if let Some(values) = crate::generator::utils::possible_values(arg) {
|
||||
if let Some(values) = utils::possible_values(arg) {
|
||||
if values
|
||||
.iter()
|
||||
.any(|value| !value.is_hide_set() && value.get_help().is_some())
|
||||
|
@ -678,7 +678,7 @@ mod tests {
|
|||
assert_eq!(
|
||||
escape_value(raw_string),
|
||||
"\\\\\\ \\[foo\\]\\(\\)\\ \\`bar\\ https\\://\\$PATH"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -687,6 +687,6 @@ mod tests {
|
|||
assert_eq!(
|
||||
escape_help(raw_string),
|
||||
"\\\\ \\[foo\\]() \\`bar https\\://\\$PATH"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,8 +190,8 @@ fn complete() {
|
|||
|
||||
File::create(Path::new(testdir_path).join("a_file")).unwrap();
|
||||
File::create(Path::new(testdir_path).join("b_file")).unwrap();
|
||||
std::fs::create_dir(Path::new(testdir_path).join("c_dir")).unwrap();
|
||||
std::fs::create_dir(Path::new(testdir_path).join("d_dir")).unwrap();
|
||||
std::fs::create_dir_all(Path::new(testdir_path).join("c_dir")).unwrap();
|
||||
std::fs::create_dir_all(Path::new(testdir_path).join("d_dir")).unwrap();
|
||||
|
||||
let input = format!(
|
||||
"exhaustive hint --file {}/\t\t",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use clap::builder::PossibleValue;
|
||||
|
||||
pub fn basic_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn basic_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.arg(
|
||||
clap::Arg::new("config")
|
||||
|
@ -25,7 +25,7 @@ pub fn basic_command(name: &'static str) -> clap::Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn feature_sample_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn feature_sample_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.version("3.0")
|
||||
.propagate_version(true)
|
||||
|
@ -55,7 +55,7 @@ pub fn feature_sample_command(name: &'static str) -> clap::Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn special_commands_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn special_commands_command(name: &'static str) -> clap::Command {
|
||||
feature_sample_command(name)
|
||||
.subcommand(
|
||||
clap::Command::new("some_cmd")
|
||||
|
@ -74,7 +74,7 @@ pub fn special_commands_command(name: &'static str) -> clap::Command {
|
|||
.subcommand(clap::Command::new("some-hidden-cmd").hide(true))
|
||||
}
|
||||
|
||||
pub fn quoting_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn quoting_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.version("3.0")
|
||||
.arg(
|
||||
|
@ -124,7 +124,7 @@ pub fn quoting_command(name: &'static str) -> clap::Command {
|
|||
])
|
||||
}
|
||||
|
||||
pub fn aliases_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn aliases_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.version("3.0")
|
||||
.about("testing bash completions")
|
||||
|
@ -149,7 +149,7 @@ pub fn aliases_command(name: &'static str) -> clap::Command {
|
|||
.arg(clap::Arg::new("positional"))
|
||||
}
|
||||
|
||||
pub fn sub_subcommands_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn sub_subcommands_command(name: &'static str) -> clap::Command {
|
||||
feature_sample_command(name).subcommand(
|
||||
clap::Command::new("some_cmd")
|
||||
.about("top level subcommand")
|
||||
|
@ -170,7 +170,7 @@ pub fn sub_subcommands_command(name: &'static str) -> clap::Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn value_hint_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn value_hint_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.arg(
|
||||
clap::Arg::new("choice")
|
||||
|
@ -254,7 +254,7 @@ pub fn value_hint_command(name: &'static str) -> clap::Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn value_terminator_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn value_terminator_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name).arg(
|
||||
clap::Arg::new("arguments")
|
||||
.help("multi-valued argument with a value terminator")
|
||||
|
@ -263,7 +263,7 @@ pub fn value_terminator_command(name: &'static str) -> clap::Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn two_multi_valued_arguments_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn two_multi_valued_arguments_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.arg(
|
||||
clap::Arg::new("first")
|
||||
|
@ -277,13 +277,13 @@ pub fn two_multi_valued_arguments_command(name: &'static str) -> clap::Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn subcommand_last(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn subcommand_last(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.arg(clap::Arg::new("free").last(true))
|
||||
.subcommands([clap::Command::new("foo"), clap::Command::new("bar")])
|
||||
}
|
||||
|
||||
pub fn assert_matches(
|
||||
pub(crate) fn assert_matches(
|
||||
expected: impl Into<snapbox::Data>,
|
||||
gen: impl clap_complete::Generator,
|
||||
mut cmd: clap::Command,
|
||||
|
@ -298,7 +298,7 @@ pub fn assert_matches(
|
|||
.matches(expected, buf);
|
||||
}
|
||||
|
||||
pub fn register_example<R: completest::RuntimeBuilder>(context: &str, name: &str) {
|
||||
pub(crate) fn register_example<R: completest::RuntimeBuilder>(context: &str, name: &str) {
|
||||
use completest::Runtime as _;
|
||||
|
||||
let scratch = snapbox::path::PathFixture::mutable_temp().unwrap();
|
||||
|
@ -354,7 +354,7 @@ pub fn register_example<R: completest::RuntimeBuilder>(context: &str, name: &str
|
|||
scratch.close().unwrap();
|
||||
}
|
||||
|
||||
pub fn load_runtime<R: completest::RuntimeBuilder>(
|
||||
pub(crate) fn load_runtime<R: completest::RuntimeBuilder>(
|
||||
context: &str,
|
||||
name: &str,
|
||||
) -> Box<dyn completest::Runtime>
|
||||
|
@ -421,7 +421,7 @@ impl completest::Runtime for ScratchRuntime {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn has_command(command: &str) -> bool {
|
||||
pub(crate) fn has_command(command: &str) -> bool {
|
||||
let output = match std::process::Command::new(command)
|
||||
.arg("--version")
|
||||
.output()
|
||||
|
|
|
@ -139,7 +139,7 @@ fn complete(cmd: &mut Command, args: impl AsRef<str>, current_dir: Option<&Path>
|
|||
if let Some((prior, after)) = input.split_once("[TAB]") {
|
||||
args.extend(prior.split_whitespace().map(From::from));
|
||||
if prior.ends_with(char::is_whitespace) {
|
||||
args.push(std::ffi::OsString::default())
|
||||
args.push(std::ffi::OsString::default());
|
||||
}
|
||||
arg_index = args.len() - 1;
|
||||
// HACK: this cannot handle in-word '[TAB]'
|
||||
|
@ -147,7 +147,7 @@ fn complete(cmd: &mut Command, args: impl AsRef<str>, current_dir: Option<&Path>
|
|||
} else {
|
||||
args.extend(input.split_whitespace().map(From::from));
|
||||
if input.ends_with(char::is_whitespace) {
|
||||
args.push(std::ffi::OsString::default())
|
||||
args.push(std::ffi::OsString::default());
|
||||
}
|
||||
arg_index = args.len() - 1;
|
||||
}
|
||||
|
|
|
@ -1,8 +1 @@
|
|||
mod bash;
|
||||
mod common;
|
||||
mod dynamic;
|
||||
mod elvish;
|
||||
mod fish;
|
||||
mod general;
|
||||
mod powershell;
|
||||
mod zsh;
|
||||
automod::dir!("tests/testsuite");
|
||||
|
|
|
@ -37,3 +37,6 @@ clap_complete = { path = "../clap_complete", version = "4.0.0" }
|
|||
[dev-dependencies]
|
||||
snapbox = { version = "0.5.9", features = ["diff"] }
|
||||
clap = { path = "../", version = "4.0.0", default-features = false, features = ["std", "help"] }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
// Internal
|
||||
use clap::*;
|
||||
use clap_complete::*;
|
||||
use clap::{builder, Arg, ArgAction, Command, ValueHint};
|
||||
use clap_complete::{generator, Generator};
|
||||
|
||||
/// Generate fig completion file
|
||||
pub struct Fig;
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
//! Generates [Fig](https://github.com/withfig/autocomplete) completions for [`clap`](https://github.com/clap-rs/clap) based CLIs
|
||||
|
||||
#![doc(html_logo_url = "https://raw.githubusercontent.com/clap-rs/clap/master/assets/clap.png")]
|
||||
#![warn(missing_docs, trivial_casts, unused_allocation, trivial_numeric_casts)]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![forbid(unsafe_code)]
|
||||
#![allow(clippy::needless_doctest_main)]
|
||||
#![warn(missing_docs)]
|
||||
#![warn(clippy::print_stderr)]
|
||||
#![warn(clippy::print_stdout)]
|
||||
|
||||
mod fig;
|
||||
pub use fig::Fig;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
pub fn basic_command(name: &'static str) -> clap::Command {
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub(crate) fn basic_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.arg(
|
||||
clap::Arg::new("config")
|
||||
|
@ -23,7 +25,7 @@ pub fn basic_command(name: &'static str) -> clap::Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn feature_sample_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn feature_sample_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.version("3.0")
|
||||
.propagate_version(true)
|
||||
|
@ -53,7 +55,7 @@ pub fn feature_sample_command(name: &'static str) -> clap::Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn special_commands_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn special_commands_command(name: &'static str) -> clap::Command {
|
||||
feature_sample_command(name)
|
||||
.subcommand(
|
||||
clap::Command::new("some_cmd")
|
||||
|
@ -72,7 +74,7 @@ pub fn special_commands_command(name: &'static str) -> clap::Command {
|
|||
.subcommand(clap::Command::new("some-hidden-cmd").hide(true))
|
||||
}
|
||||
|
||||
pub fn quoting_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn quoting_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.version("3.0")
|
||||
.arg(
|
||||
|
@ -122,7 +124,7 @@ pub fn quoting_command(name: &'static str) -> clap::Command {
|
|||
])
|
||||
}
|
||||
|
||||
pub fn aliases_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn aliases_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.version("3.0")
|
||||
.about("testing bash completions")
|
||||
|
@ -147,7 +149,7 @@ pub fn aliases_command(name: &'static str) -> clap::Command {
|
|||
.arg(clap::Arg::new("positional"))
|
||||
}
|
||||
|
||||
pub fn sub_subcommands_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn sub_subcommands_command(name: &'static str) -> clap::Command {
|
||||
feature_sample_command(name).subcommand(
|
||||
clap::Command::new("some_cmd")
|
||||
.about("top level subcommand")
|
||||
|
@ -165,7 +167,7 @@ pub fn sub_subcommands_command(name: &'static str) -> clap::Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn value_hint_command(name: &'static str) -> clap::Command {
|
||||
pub(crate) fn value_hint_command(name: &'static str) -> clap::Command {
|
||||
clap::Command::new(name)
|
||||
.arg(
|
||||
clap::Arg::new("choice")
|
||||
|
@ -249,7 +251,7 @@ pub fn value_hint_command(name: &'static str) -> clap::Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn assert_matches(
|
||||
pub(crate) fn assert_matches(
|
||||
expected: impl Into<snapbox::Data>,
|
||||
gen: impl clap_complete::Generator,
|
||||
mut cmd: clap::Command,
|
||||
|
|
|
@ -39,3 +39,6 @@ snapbox = { version = "0.5.9", features = ["diff", "examples", "path"] }
|
|||
clap = { path = "../", version = "4.0.0", default-features = false, features = ["std", "help"] }
|
||||
completest = "0.4.0"
|
||||
completest-nu = "0.4.0"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -16,8 +16,11 @@
|
|||
//! ```
|
||||
|
||||
#![doc(html_logo_url = "https://raw.githubusercontent.com/clap-rs/clap/master/assets/clap.png")]
|
||||
#![warn(missing_docs, trivial_casts, unused_allocation, trivial_numeric_casts)]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(missing_docs)]
|
||||
#![warn(clippy::print_stderr)]
|
||||
#![warn(clippy::print_stdout)]
|
||||
|
||||
use clap::builder::StyledStr;
|
||||
use clap::{builder::PossibleValue, Arg, ArgAction, Command};
|
||||
|
@ -46,14 +49,14 @@ impl Generator for Nushell {
|
|||
completions.push_str("export use completions *\n");
|
||||
|
||||
buf.write_all(completions.as_bytes())
|
||||
.expect("Failed to write to generated file")
|
||||
.expect("Failed to write to generated file");
|
||||
}
|
||||
}
|
||||
|
||||
fn append_value_completion_and_help(
|
||||
arg: &Arg,
|
||||
name: &str,
|
||||
possible_values: &Vec<PossibleValue>,
|
||||
possible_values: &[PossibleValue],
|
||||
s: &mut String,
|
||||
) {
|
||||
let takes_values = arg
|
||||
|
@ -65,7 +68,7 @@ fn append_value_completion_and_help(
|
|||
s.push_str(": string");
|
||||
|
||||
if !possible_values.is_empty() {
|
||||
s.push_str(format!(r#"@"nu-complete {} {}""#, name, arg.get_id()).as_str())
|
||||
s.push_str(format!(r#"@"nu-complete {} {}""#, name, arg.get_id()).as_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use clap::{builder::PossibleValue, Arg, ArgAction, Command, ValueHint};
|
||||
|
||||
pub fn basic_command(name: &'static str) -> Command {
|
||||
pub(crate) fn basic_command(name: &'static str) -> Command {
|
||||
Command::new(name)
|
||||
.arg(
|
||||
Arg::new("config")
|
||||
|
@ -23,7 +23,7 @@ pub fn basic_command(name: &'static str) -> Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn feature_sample_command(name: &'static str) -> Command {
|
||||
pub(crate) fn feature_sample_command(name: &'static str) -> Command {
|
||||
Command::new(name)
|
||||
.version("3.0")
|
||||
.propagate_version(true)
|
||||
|
@ -53,7 +53,7 @@ pub fn feature_sample_command(name: &'static str) -> Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn special_commands_command(name: &'static str) -> Command {
|
||||
pub(crate) fn special_commands_command(name: &'static str) -> Command {
|
||||
feature_sample_command(name)
|
||||
.subcommand(
|
||||
Command::new("some_cmd")
|
||||
|
@ -72,7 +72,7 @@ pub fn special_commands_command(name: &'static str) -> Command {
|
|||
.subcommand(Command::new("some-hidden-cmd").hide(true))
|
||||
}
|
||||
|
||||
pub fn quoting_command(name: &'static str) -> Command {
|
||||
pub(crate) fn quoting_command(name: &'static str) -> Command {
|
||||
Command::new(name)
|
||||
.version("3.0")
|
||||
.arg(
|
||||
|
@ -121,7 +121,7 @@ pub fn quoting_command(name: &'static str) -> Command {
|
|||
])
|
||||
}
|
||||
|
||||
pub fn aliases_command(name: &'static str) -> Command {
|
||||
pub(crate) fn aliases_command(name: &'static str) -> Command {
|
||||
Command::new(name)
|
||||
.version("3.0")
|
||||
.about("testing nushell completions")
|
||||
|
@ -146,7 +146,7 @@ pub fn aliases_command(name: &'static str) -> Command {
|
|||
.arg(Arg::new("positional"))
|
||||
}
|
||||
|
||||
pub fn sub_subcommands_command(name: &'static str) -> Command {
|
||||
pub(crate) fn sub_subcommands_command(name: &'static str) -> Command {
|
||||
feature_sample_command(name).subcommand(
|
||||
Command::new("some_cmd")
|
||||
.about("top level subcommand")
|
||||
|
@ -167,7 +167,7 @@ pub fn sub_subcommands_command(name: &'static str) -> Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn value_hint_command(name: &'static str) -> Command {
|
||||
pub(crate) fn value_hint_command(name: &'static str) -> Command {
|
||||
Command::new(name)
|
||||
.arg(
|
||||
Arg::new("choice")
|
||||
|
@ -243,10 +243,10 @@ pub fn value_hint_command(name: &'static str) -> Command {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn assert_matches(
|
||||
pub(crate) fn assert_matches(
|
||||
expected: impl Into<snapbox::Data>,
|
||||
gen: impl clap_complete::Generator,
|
||||
mut cmd: clap::Command,
|
||||
mut cmd: Command,
|
||||
name: &'static str,
|
||||
) {
|
||||
let mut buf = vec![];
|
||||
|
@ -258,7 +258,7 @@ pub fn assert_matches(
|
|||
.matches(expected, buf);
|
||||
}
|
||||
|
||||
pub fn register_example<R: completest::RuntimeBuilder>(context: &str, name: &str) {
|
||||
pub(crate) fn register_example<R: completest::RuntimeBuilder>(context: &str, name: &str) {
|
||||
use completest::Runtime as _;
|
||||
|
||||
let scratch = snapbox::path::PathFixture::mutable_temp().unwrap();
|
||||
|
@ -306,7 +306,7 @@ pub fn register_example<R: completest::RuntimeBuilder>(context: &str, name: &str
|
|||
scratch.close().unwrap();
|
||||
}
|
||||
|
||||
pub fn load_runtime<R: completest::RuntimeBuilder>(
|
||||
pub(crate) fn load_runtime<R: completest::RuntimeBuilder>(
|
||||
context: &str,
|
||||
name: &str,
|
||||
) -> Box<dyn completest::Runtime>
|
||||
|
@ -365,7 +365,7 @@ impl completest::Runtime for ScratchRuntime {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn has_command(command: &str) -> bool {
|
||||
pub(crate) fn has_command(command: &str) -> bool {
|
||||
let output = match std::process::Command::new(command)
|
||||
.arg("--version")
|
||||
.output()
|
||||
|
|
|
@ -40,3 +40,6 @@ debug = []
|
|||
unstable-v5 = ["deprecated"]
|
||||
deprecated = []
|
||||
raw-deprecated = ["deprecated"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -14,15 +14,15 @@ use syn::{
|
|||
use crate::utils::Sp;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ClapAttr {
|
||||
pub kind: Sp<AttrKind>,
|
||||
pub name: Ident,
|
||||
pub magic: Option<MagicAttrName>,
|
||||
pub value: Option<AttrValue>,
|
||||
pub(crate) struct ClapAttr {
|
||||
pub(crate) kind: Sp<AttrKind>,
|
||||
pub(crate) name: Ident,
|
||||
pub(crate) magic: Option<MagicAttrName>,
|
||||
pub(crate) value: Option<AttrValue>,
|
||||
}
|
||||
|
||||
impl ClapAttr {
|
||||
pub fn parse_all(all_attrs: &[Attribute]) -> Result<Vec<Self>, syn::Error> {
|
||||
pub(crate) fn parse_all(all_attrs: &[Attribute]) -> Result<Vec<Self>, syn::Error> {
|
||||
let mut parsed = Vec::new();
|
||||
for attr in all_attrs {
|
||||
let kind = if attr.path().is_ident("clap") {
|
||||
|
@ -50,13 +50,13 @@ impl ClapAttr {
|
|||
Ok(parsed)
|
||||
}
|
||||
|
||||
pub fn value_or_abort(&self) -> Result<&AttrValue, syn::Error> {
|
||||
pub(crate) fn value_or_abort(&self) -> Result<&AttrValue, syn::Error> {
|
||||
self.value
|
||||
.as_ref()
|
||||
.ok_or_else(|| format_err!(self.name, "attribute `{}` requires a value", self.name))
|
||||
}
|
||||
|
||||
pub fn lit_str_or_abort(&self) -> Result<&LitStr, syn::Error> {
|
||||
pub(crate) fn lit_str_or_abort(&self) -> Result<&LitStr, syn::Error> {
|
||||
let value = self.value_or_abort()?;
|
||||
match value {
|
||||
AttrValue::LitStr(tokens) => Ok(tokens),
|
||||
|
@ -72,7 +72,7 @@ impl ClapAttr {
|
|||
}
|
||||
|
||||
impl Parse for ClapAttr {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
|
||||
let name: Ident = input.parse()?;
|
||||
let name_str = name.to_string();
|
||||
|
||||
|
@ -142,7 +142,7 @@ impl Parse for ClapAttr {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum MagicAttrName {
|
||||
pub(crate) enum MagicAttrName {
|
||||
Short,
|
||||
Long,
|
||||
ValueParser,
|
||||
|
@ -172,7 +172,7 @@ pub enum MagicAttrName {
|
|||
|
||||
#[derive(Clone)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum AttrValue {
|
||||
pub(crate) enum AttrValue {
|
||||
LitStr(LitStr),
|
||||
Expr(Expr),
|
||||
Call(Vec<Expr>),
|
||||
|
@ -185,14 +185,14 @@ impl ToTokens for AttrValue {
|
|||
Self::Expr(t) => t.to_tokens(tokens),
|
||||
Self::Call(t) => {
|
||||
let t = quote!(#(#t),*);
|
||||
t.to_tokens(tokens)
|
||||
t.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum AttrKind {
|
||||
pub(crate) enum AttrKind {
|
||||
Clap,
|
||||
StructOpt,
|
||||
Command,
|
||||
|
@ -202,7 +202,7 @@ pub enum AttrKind {
|
|||
}
|
||||
|
||||
impl AttrKind {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
pub(crate) fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Clap => "clap",
|
||||
Self::StructOpt => "structopt",
|
||||
|
|
|
@ -22,7 +22,7 @@ use syn::{
|
|||
use crate::item::{Item, Kind, Name};
|
||||
use crate::utils::{inner_type, sub_type, Sp, Ty};
|
||||
|
||||
pub fn derive_args(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
pub(crate) fn derive_args(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
let ident = &input.ident;
|
||||
|
||||
match input.data {
|
||||
|
@ -55,7 +55,7 @@ pub fn derive_args(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn gen_for_struct(
|
||||
pub(crate) fn gen_for_struct(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
generics: &Generics,
|
||||
|
@ -166,7 +166,7 @@ pub fn gen_for_struct(
|
|||
|
||||
/// Generate a block of code to add arguments/subcommands corresponding to
|
||||
/// the `fields` to an cmd.
|
||||
pub fn gen_augment(
|
||||
pub(crate) fn gen_augment(
|
||||
fields: &[(&Field, Item)],
|
||||
app_var: &Ident,
|
||||
parent_item: &Item,
|
||||
|
@ -431,7 +431,7 @@ pub fn gen_augment(
|
|||
}})
|
||||
}
|
||||
|
||||
pub fn gen_constructor(fields: &[(&Field, Item)]) -> Result<TokenStream, syn::Error> {
|
||||
pub(crate) fn gen_constructor(fields: &[(&Field, Item)]) -> Result<TokenStream, syn::Error> {
|
||||
let fields = fields.iter().map(|(field, item)| {
|
||||
let field_name = field.ident.as_ref().unwrap();
|
||||
let kind = item.kind();
|
||||
|
@ -542,7 +542,10 @@ pub fn gen_constructor(fields: &[(&Field, Item)]) -> Result<TokenStream, syn::Er
|
|||
}})
|
||||
}
|
||||
|
||||
pub fn gen_updater(fields: &[(&Field, Item)], use_self: bool) -> Result<TokenStream, syn::Error> {
|
||||
pub(crate) fn gen_updater(
|
||||
fields: &[(&Field, Item)],
|
||||
use_self: bool,
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
let mut genned_fields = Vec::new();
|
||||
for (field, item) in fields {
|
||||
let field_name = field.ident.as_ref().unwrap();
|
||||
|
@ -750,19 +753,19 @@ fn gen_parsers(
|
|||
}
|
||||
|
||||
#[cfg(feature = "raw-deprecated")]
|
||||
pub fn raw_deprecated() -> TokenStream {
|
||||
pub(crate) fn raw_deprecated() -> TokenStream {
|
||||
quote! {}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "raw-deprecated"))]
|
||||
pub fn raw_deprecated() -> TokenStream {
|
||||
pub(crate) fn raw_deprecated() -> TokenStream {
|
||||
quote! {
|
||||
#![allow(deprecated)] // Assuming any deprecation in here will be related to a deprecation in `Args`
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub fn collect_args_fields<'a>(
|
||||
pub(crate) fn collect_args_fields<'a>(
|
||||
item: &'a Item,
|
||||
fields: &'a FieldsNamed,
|
||||
) -> Result<Vec<(&'a Field, Item)>, syn::Error> {
|
||||
|
|
|
@ -18,7 +18,7 @@ use syn::{Generics, Ident};
|
|||
|
||||
use crate::item::Item;
|
||||
|
||||
pub fn gen_for_struct(
|
||||
pub(crate) fn gen_for_struct(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
generics: &Generics,
|
||||
|
@ -66,7 +66,7 @@ pub fn gen_for_struct(
|
|||
Ok(tokens)
|
||||
}
|
||||
|
||||
pub fn gen_for_enum(
|
||||
pub(crate) fn gen_for_enum(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
generics: &Generics,
|
||||
|
|
|
@ -17,7 +17,7 @@ mod parser;
|
|||
mod subcommand;
|
||||
mod value_enum;
|
||||
|
||||
pub use self::parser::derive_parser;
|
||||
pub use args::derive_args;
|
||||
pub use subcommand::derive_subcommand;
|
||||
pub use value_enum::derive_value_enum;
|
||||
pub(crate) use self::parser::derive_parser;
|
||||
pub(crate) use args::derive_args;
|
||||
pub(crate) use subcommand::derive_subcommand;
|
||||
pub(crate) use value_enum::derive_value_enum;
|
||||
|
|
|
@ -26,7 +26,7 @@ use crate::derives::{args, into_app, subcommand};
|
|||
use crate::item::Item;
|
||||
use crate::item::Name;
|
||||
|
||||
pub fn derive_parser(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
pub(crate) fn derive_parser(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
let ident = &input.ident;
|
||||
let pkg_name = std::env::var("CARGO_PKG_NAME").ok().unwrap_or_default();
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ use crate::derives::args::collect_args_fields;
|
|||
use crate::item::{Item, Kind, Name};
|
||||
use crate::utils::{is_simple_ty, subty_if_name};
|
||||
|
||||
pub fn derive_subcommand(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
pub(crate) fn derive_subcommand(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
let ident = &input.ident;
|
||||
|
||||
match input.data {
|
||||
|
@ -43,7 +43,7 @@ pub fn derive_subcommand(input: &DeriveInput) -> Result<TokenStream, syn::Error>
|
|||
}
|
||||
}
|
||||
|
||||
pub fn gen_for_enum(
|
||||
pub(crate) fn gen_for_enum(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
generics: &Generics,
|
||||
|
@ -140,7 +140,7 @@ fn gen_augment(
|
|||
parent_item: &Item,
|
||||
override_required: bool,
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
use syn::Fields::*;
|
||||
use syn::Fields::{Named, Unit, Unnamed};
|
||||
|
||||
let app_var = Ident::new("__clap_app", Span::call_site());
|
||||
|
||||
|
@ -357,7 +357,7 @@ fn gen_augment(
|
|||
}
|
||||
|
||||
fn gen_has_subcommand(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error> {
|
||||
use syn::Fields::*;
|
||||
use syn::Fields::Unnamed;
|
||||
|
||||
let mut ext_subcmd = false;
|
||||
|
||||
|
@ -421,7 +421,7 @@ fn gen_has_subcommand(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn:
|
|||
}
|
||||
|
||||
fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error> {
|
||||
use syn::Fields::*;
|
||||
use syn::Fields::{Named, Unit, Unnamed};
|
||||
|
||||
let subcommand_name_var = format_ident!("__clap_name");
|
||||
let sub_arg_matches_var = format_ident!("__clap_arg_matches");
|
||||
|
@ -572,7 +572,7 @@ fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> Result<TokenStream, sy
|
|||
}
|
||||
|
||||
fn gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error> {
|
||||
use syn::Fields::*;
|
||||
use syn::Fields::{Named, Unit, Unnamed};
|
||||
|
||||
let (flatten, variants): (Vec<_>, Vec<_>) = variants
|
||||
.iter()
|
||||
|
|
|
@ -15,7 +15,7 @@ use syn::{spanned::Spanned, Data, DeriveInput, Fields, Ident, Variant};
|
|||
|
||||
use crate::item::{Item, Kind, Name};
|
||||
|
||||
pub fn derive_value_enum(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
pub(crate) fn derive_value_enum(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
let ident = &input.ident;
|
||||
|
||||
match input.data {
|
||||
|
@ -34,7 +34,7 @@ pub fn derive_value_enum(input: &DeriveInput) -> Result<TokenStream, syn::Error>
|
|||
}
|
||||
}
|
||||
|
||||
pub fn gen_for_enum(
|
||||
pub(crate) fn gen_for_enum(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
variants: &[(&Variant, Item)],
|
||||
|
|
|
@ -4,7 +4,7 @@ use proc_macro2::Ident;
|
|||
use quote::quote;
|
||||
|
||||
#[must_use]
|
||||
pub fn parser(name: &Ident) -> proc_macro2::TokenStream {
|
||||
pub(crate) fn parser(name: &Ident) -> proc_macro2::TokenStream {
|
||||
let into_app = into_app(name);
|
||||
quote!(
|
||||
#[automatically_derived]
|
||||
|
@ -14,7 +14,7 @@ pub fn parser(name: &Ident) -> proc_macro2::TokenStream {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn into_app(name: &Ident) -> proc_macro2::TokenStream {
|
||||
pub(crate) fn into_app(name: &Ident) -> proc_macro2::TokenStream {
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl clap::CommandFactory for #name {
|
||||
|
@ -29,7 +29,7 @@ pub fn into_app(name: &Ident) -> proc_macro2::TokenStream {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn from_arg_matches(name: &Ident) -> proc_macro2::TokenStream {
|
||||
pub(crate) fn from_arg_matches(name: &Ident) -> proc_macro2::TokenStream {
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl clap::FromArgMatches for #name {
|
||||
|
@ -44,7 +44,7 @@ pub fn from_arg_matches(name: &Ident) -> proc_macro2::TokenStream {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn subcommand(name: &Ident) -> proc_macro2::TokenStream {
|
||||
pub(crate) fn subcommand(name: &Ident) -> proc_macro2::TokenStream {
|
||||
let from_arg_matches = from_arg_matches(name);
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
|
@ -64,7 +64,7 @@ pub fn subcommand(name: &Ident) -> proc_macro2::TokenStream {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn args(name: &Ident) -> proc_macro2::TokenStream {
|
||||
pub(crate) fn args(name: &Ident) -> proc_macro2::TokenStream {
|
||||
let from_arg_matches = from_arg_matches(name);
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
|
@ -81,7 +81,7 @@ pub fn args(name: &Ident) -> proc_macro2::TokenStream {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn value_enum(name: &Ident) -> proc_macro2::TokenStream {
|
||||
pub(crate) fn value_enum(name: &Ident) -> proc_macro2::TokenStream {
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl clap::ValueEnum for #name {
|
||||
|
|
|
@ -20,17 +20,17 @@ use quote::{format_ident, quote, quote_spanned, ToTokens};
|
|||
use syn::DeriveInput;
|
||||
use syn::{self, ext::IdentExt, spanned::Spanned, Attribute, Field, Ident, LitStr, Type, Variant};
|
||||
|
||||
use crate::attr::*;
|
||||
use crate::attr::{AttrKind, AttrValue, ClapAttr, MagicAttrName};
|
||||
use crate::utils::{extract_doc_comment, format_doc_comment, inner_type, is_simple_ty, Sp, Ty};
|
||||
|
||||
/// Default casing style for generated arguments.
|
||||
pub const DEFAULT_CASING: CasingStyle = CasingStyle::Kebab;
|
||||
pub(crate) const DEFAULT_CASING: CasingStyle = CasingStyle::Kebab;
|
||||
|
||||
/// Default casing style for environment variables
|
||||
pub const DEFAULT_ENV_CASING: CasingStyle = CasingStyle::ScreamingSnake;
|
||||
pub(crate) const DEFAULT_ENV_CASING: CasingStyle = CasingStyle::ScreamingSnake;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Item {
|
||||
pub(crate) struct Item {
|
||||
name: Name,
|
||||
casing: Sp<CasingStyle>,
|
||||
env_casing: Sp<CasingStyle>,
|
||||
|
@ -53,7 +53,7 @@ pub struct Item {
|
|||
}
|
||||
|
||||
impl Item {
|
||||
pub fn from_args_struct(input: &DeriveInput, name: Name) -> Result<Self, syn::Error> {
|
||||
pub(crate) fn from_args_struct(input: &DeriveInput, name: Name) -> Result<Self, syn::Error> {
|
||||
let ident = input.ident.clone();
|
||||
let span = input.ident.span();
|
||||
let attrs = &input.attrs;
|
||||
|
@ -70,7 +70,10 @@ impl Item {
|
|||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn from_subcommand_enum(input: &DeriveInput, name: Name) -> Result<Self, syn::Error> {
|
||||
pub(crate) fn from_subcommand_enum(
|
||||
input: &DeriveInput,
|
||||
name: Name,
|
||||
) -> Result<Self, syn::Error> {
|
||||
let ident = input.ident.clone();
|
||||
let span = input.ident.span();
|
||||
let attrs = &input.attrs;
|
||||
|
@ -87,7 +90,7 @@ impl Item {
|
|||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn from_value_enum(input: &DeriveInput, name: Name) -> Result<Self, syn::Error> {
|
||||
pub(crate) fn from_value_enum(input: &DeriveInput, name: Name) -> Result<Self, syn::Error> {
|
||||
let ident = input.ident.clone();
|
||||
let span = input.ident.span();
|
||||
let attrs = &input.attrs;
|
||||
|
@ -113,7 +116,7 @@ impl Item {
|
|||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn from_subcommand_variant(
|
||||
pub(crate) fn from_subcommand_variant(
|
||||
variant: &Variant,
|
||||
struct_casing: Sp<CasingStyle>,
|
||||
env_casing: Sp<CasingStyle>,
|
||||
|
@ -167,7 +170,7 @@ impl Item {
|
|||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn from_value_enum_variant(
|
||||
pub(crate) fn from_value_enum_variant(
|
||||
variant: &Variant,
|
||||
argument_casing: Sp<CasingStyle>,
|
||||
env_casing: Sp<CasingStyle>,
|
||||
|
@ -193,7 +196,7 @@ impl Item {
|
|||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn from_args_field(
|
||||
pub(crate) fn from_args_field(
|
||||
field: &Field,
|
||||
struct_casing: Sp<CasingStyle>,
|
||||
env_casing: Sp<CasingStyle>,
|
||||
|
@ -501,11 +504,11 @@ impl Item {
|
|||
Some(MagicAttrName::ValueEnum) if attr.value.is_none() => {
|
||||
assert_attr_kind(attr, &[AttrKind::Arg])?;
|
||||
|
||||
self.is_enum = true
|
||||
self.is_enum = true;
|
||||
}
|
||||
|
||||
Some(MagicAttrName::VerbatimDocComment) if attr.value.is_none() => {
|
||||
self.verbatim_doc_comment = true
|
||||
self.verbatim_doc_comment = true;
|
||||
}
|
||||
|
||||
Some(MagicAttrName::About) if attr.value.is_none() => {
|
||||
|
@ -941,14 +944,14 @@ impl Item {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn find_default_method(&self) -> Option<&Method> {
|
||||
pub(crate) fn find_default_method(&self) -> Option<&Method> {
|
||||
self.methods
|
||||
.iter()
|
||||
.find(|m| m.name == "default_value" || m.name == "default_value_os")
|
||||
}
|
||||
|
||||
/// generate methods from attributes on top of struct or enum
|
||||
pub fn initial_top_level_methods(&self) -> TokenStream {
|
||||
pub(crate) fn initial_top_level_methods(&self) -> TokenStream {
|
||||
let next_display_order = self.next_display_order.as_ref().into_iter();
|
||||
let next_help_heading = self.next_help_heading.as_ref().into_iter();
|
||||
quote!(
|
||||
|
@ -957,7 +960,7 @@ impl Item {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn final_top_level_methods(&self) -> TokenStream {
|
||||
pub(crate) fn final_top_level_methods(&self) -> TokenStream {
|
||||
let methods = &self.methods;
|
||||
let doc_comment = &self.doc_comment;
|
||||
|
||||
|
@ -965,49 +968,49 @@ impl Item {
|
|||
}
|
||||
|
||||
/// generate methods on top of a field
|
||||
pub fn field_methods(&self) -> proc_macro2::TokenStream {
|
||||
pub(crate) fn field_methods(&self) -> TokenStream {
|
||||
let methods = &self.methods;
|
||||
let doc_comment = &self.doc_comment;
|
||||
quote!( #(#doc_comment)* #(#methods)* )
|
||||
}
|
||||
|
||||
pub fn group_id(&self) -> &Name {
|
||||
pub(crate) fn group_id(&self) -> &Name {
|
||||
&self.group_id
|
||||
}
|
||||
|
||||
pub fn group_methods(&self) -> TokenStream {
|
||||
pub(crate) fn group_methods(&self) -> TokenStream {
|
||||
let group_methods = &self.group_methods;
|
||||
quote!( #(#group_methods)* )
|
||||
}
|
||||
|
||||
pub fn deprecations(&self) -> proc_macro2::TokenStream {
|
||||
pub(crate) fn deprecations(&self) -> TokenStream {
|
||||
let deprecations = &self.deprecations;
|
||||
quote!( #(#deprecations)* )
|
||||
}
|
||||
|
||||
pub fn next_display_order(&self) -> TokenStream {
|
||||
pub(crate) fn next_display_order(&self) -> TokenStream {
|
||||
let next_display_order = self.next_display_order.as_ref().into_iter();
|
||||
quote!( #(#next_display_order)* )
|
||||
}
|
||||
|
||||
pub fn next_help_heading(&self) -> TokenStream {
|
||||
pub(crate) fn next_help_heading(&self) -> TokenStream {
|
||||
let next_help_heading = self.next_help_heading.as_ref().into_iter();
|
||||
quote!( #(#next_help_heading)* )
|
||||
}
|
||||
|
||||
pub fn id(&self) -> &Name {
|
||||
pub(crate) fn id(&self) -> &Name {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn cased_name(&self) -> TokenStream {
|
||||
pub(crate) fn cased_name(&self) -> TokenStream {
|
||||
self.name.clone().translate(*self.casing)
|
||||
}
|
||||
|
||||
pub fn value_name(&self) -> TokenStream {
|
||||
pub(crate) fn value_name(&self) -> TokenStream {
|
||||
self.name.clone().translate(CasingStyle::ScreamingSnake)
|
||||
}
|
||||
|
||||
pub fn value_parser(&self, field_type: &Type) -> Method {
|
||||
pub(crate) fn value_parser(&self, field_type: &Type) -> Method {
|
||||
self.value_parser
|
||||
.clone()
|
||||
.map(|p| {
|
||||
|
@ -1030,7 +1033,7 @@ impl Item {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn action(&self, field_type: &Type) -> Method {
|
||||
pub(crate) fn action(&self, field_type: &Type) -> Method {
|
||||
self.action
|
||||
.clone()
|
||||
.map(|p| p.resolve(field_type))
|
||||
|
@ -1049,29 +1052,29 @@ impl Item {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> Sp<Kind> {
|
||||
pub(crate) fn kind(&self) -> Sp<Kind> {
|
||||
self.kind.clone()
|
||||
}
|
||||
|
||||
pub fn is_positional(&self) -> bool {
|
||||
pub(crate) fn is_positional(&self) -> bool {
|
||||
self.is_positional
|
||||
}
|
||||
|
||||
pub fn casing(&self) -> Sp<CasingStyle> {
|
||||
pub(crate) fn casing(&self) -> Sp<CasingStyle> {
|
||||
self.casing
|
||||
}
|
||||
|
||||
pub fn env_casing(&self) -> Sp<CasingStyle> {
|
||||
pub(crate) fn env_casing(&self) -> Sp<CasingStyle> {
|
||||
self.env_casing
|
||||
}
|
||||
|
||||
pub fn has_explicit_methods(&self) -> bool {
|
||||
pub(crate) fn has_explicit_methods(&self) -> bool {
|
||||
self.methods
|
||||
.iter()
|
||||
.any(|m| m.name != "help" && m.name != "long_help")
|
||||
}
|
||||
|
||||
pub fn skip_group(&self) -> bool {
|
||||
pub(crate) fn skip_group(&self) -> bool {
|
||||
self.skip_group
|
||||
}
|
||||
}
|
||||
|
@ -1109,20 +1112,20 @@ fn default_value_parser(inner_type: &Type, span: Span) -> Method {
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Action {
|
||||
pub(crate) enum Action {
|
||||
Explicit(Method),
|
||||
Implicit(Ident),
|
||||
}
|
||||
|
||||
impl Action {
|
||||
pub fn resolve(self, _field_type: &Type) -> Method {
|
||||
pub(crate) fn resolve(self, _field_type: &Type) -> Method {
|
||||
match self {
|
||||
Self::Explicit(method) => method,
|
||||
Self::Implicit(ident) => default_action(_field_type, ident.span()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
pub(crate) fn span(&self) -> Span {
|
||||
match self {
|
||||
Self::Explicit(method) => method.name.span(),
|
||||
Self::Implicit(ident) => ident.span(),
|
||||
|
@ -1162,7 +1165,7 @@ fn default_action(field_type: &Type, span: Span) -> Method {
|
|||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Clone)]
|
||||
pub enum Kind {
|
||||
pub(crate) enum Kind {
|
||||
Arg(Sp<Ty>),
|
||||
Command(Sp<Ty>),
|
||||
Value,
|
||||
|
@ -1174,7 +1177,7 @@ pub enum Kind {
|
|||
}
|
||||
|
||||
impl Kind {
|
||||
pub fn name(&self) -> &'static str {
|
||||
pub(crate) fn name(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Arg(_) => "arg",
|
||||
Self::Command(_) => "command",
|
||||
|
@ -1187,7 +1190,7 @@ impl Kind {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn attr_kind(&self) -> AttrKind {
|
||||
pub(crate) fn attr_kind(&self) -> AttrKind {
|
||||
match self {
|
||||
Self::Arg(_) => AttrKind::Arg,
|
||||
Self::Command(_) => AttrKind::Command,
|
||||
|
@ -1200,7 +1203,7 @@ impl Kind {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn ty(&self) -> Option<&Sp<Ty>> {
|
||||
pub(crate) fn ty(&self) -> Option<&Sp<Ty>> {
|
||||
match self {
|
||||
Self::Arg(ty)
|
||||
| Self::Command(ty)
|
||||
|
@ -1213,13 +1216,13 @@ impl Kind {
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Method {
|
||||
pub(crate) struct Method {
|
||||
name: Ident,
|
||||
args: TokenStream,
|
||||
}
|
||||
|
||||
impl Method {
|
||||
pub fn new(name: Ident, args: TokenStream) -> Self {
|
||||
pub(crate) fn new(name: Ident, args: TokenStream) -> Self {
|
||||
Method { name, args }
|
||||
}
|
||||
|
||||
|
@ -1256,7 +1259,7 @@ impl Method {
|
|||
}
|
||||
|
||||
impl ToTokens for Method {
|
||||
fn to_tokens(&self, ts: &mut proc_macro2::TokenStream) {
|
||||
fn to_tokens(&self, ts: &mut TokenStream) {
|
||||
let Method { ref name, ref args } = self;
|
||||
|
||||
let tokens = quote!( .#name(#args) );
|
||||
|
@ -1266,11 +1269,11 @@ impl ToTokens for Method {
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Deprecation {
|
||||
pub span: Span,
|
||||
pub id: &'static str,
|
||||
pub version: &'static str,
|
||||
pub description: String,
|
||||
pub(crate) struct Deprecation {
|
||||
pub(crate) span: Span,
|
||||
pub(crate) id: &'static str,
|
||||
pub(crate) version: &'static str,
|
||||
pub(crate) description: String,
|
||||
}
|
||||
|
||||
impl Deprecation {
|
||||
|
@ -1289,7 +1292,7 @@ impl Deprecation {
|
|||
}
|
||||
|
||||
impl ToTokens for Deprecation {
|
||||
fn to_tokens(&self, ts: &mut proc_macro2::TokenStream) {
|
||||
fn to_tokens(&self, ts: &mut TokenStream) {
|
||||
let tokens = if cfg!(feature = "deprecated") {
|
||||
let Deprecation {
|
||||
span,
|
||||
|
@ -1335,7 +1338,7 @@ fn assert_attr_kind(attr: &ClapAttr, possible_kind: &[AttrKind]) -> Result<(), s
|
|||
/// replace all `:` with `, ` when not inside the `<>`
|
||||
///
|
||||
/// `"author1:author2:author3" => "author1, author2, author3"`
|
||||
/// `"author1 <http://website1.com>:author2" => "author1 <http://website1.com>, author2"
|
||||
/// `"author1 <http://website1.com>:author2" => "author1 <http://website1.com>, author2"`
|
||||
fn process_author_str(author: &str) -> String {
|
||||
let mut res = String::with_capacity(author.len());
|
||||
let mut inside_angle_braces = 0usize;
|
||||
|
@ -1359,7 +1362,7 @@ fn process_author_str(author: &str) -> String {
|
|||
|
||||
/// Defines the casing for the attributes long representation.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum CasingStyle {
|
||||
pub(crate) enum CasingStyle {
|
||||
/// Indicate word boundaries with uppercase letter, excluding the first word.
|
||||
Camel,
|
||||
/// Keep all letters lowercase and indicate word boundaries with hyphens.
|
||||
|
@ -1380,7 +1383,9 @@ pub enum CasingStyle {
|
|||
|
||||
impl CasingStyle {
|
||||
fn from_lit(name: &LitStr) -> Result<Sp<Self>, syn::Error> {
|
||||
use self::CasingStyle::*;
|
||||
use self::CasingStyle::{
|
||||
Camel, Kebab, Lower, Pascal, ScreamingSnake, Snake, Upper, Verbatim,
|
||||
};
|
||||
|
||||
let normalized = name.value().to_upper_camel_case().to_lowercase();
|
||||
let cs = |kind| Sp::new(kind, name.span());
|
||||
|
@ -1401,14 +1406,14 @@ impl CasingStyle {
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Name {
|
||||
pub(crate) enum Name {
|
||||
Derived(Ident),
|
||||
Assigned(TokenStream),
|
||||
}
|
||||
|
||||
impl Name {
|
||||
pub fn translate(self, style: CasingStyle) -> TokenStream {
|
||||
use CasingStyle::*;
|
||||
pub(crate) fn translate(self, style: CasingStyle) -> TokenStream {
|
||||
use CasingStyle::{Camel, Kebab, Lower, Pascal, ScreamingSnake, Snake, Upper, Verbatim};
|
||||
|
||||
match self {
|
||||
Name::Assigned(tokens) => tokens,
|
||||
|
@ -1429,8 +1434,8 @@ impl Name {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn translate_char(self, style: CasingStyle) -> TokenStream {
|
||||
use CasingStyle::*;
|
||||
pub(crate) fn translate_char(self, style: CasingStyle) -> TokenStream {
|
||||
use CasingStyle::{Camel, Kebab, Lower, Pascal, ScreamingSnake, Snake, Upper, Verbatim};
|
||||
|
||||
match self {
|
||||
Name::Assigned(tokens) => quote!( (#tokens).chars().next().unwrap() ),
|
||||
|
@ -1460,7 +1465,7 @@ impl ToTokens for Name {
|
|||
Name::Assigned(t) => t.to_tokens(tokens),
|
||||
Name::Derived(ident) => {
|
||||
let s = ident.unraw().to_string();
|
||||
quote_spanned!(ident.span()=> #s).to_tokens(tokens)
|
||||
quote_spanned!(ident.span()=> #s).to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,13 @@
|
|||
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
|
||||
// MIT/Apache 2.0 license.
|
||||
|
||||
#![doc(html_logo_url = "https://raw.githubusercontent.com/clap-rs/clap/master/assets/clap.png")]
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![doc(html_logo_url = "https://raw.githubusercontent.com/clap-rs/clap/master/assets/clap.png")]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
extern crate proc_macro;
|
||||
#![warn(missing_docs)]
|
||||
#![warn(clippy::print_stderr)]
|
||||
#![warn(clippy::print_stdout)]
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use syn::{parse_macro_input, DeriveInput};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
use std::iter;
|
||||
|
||||
pub fn extract_doc_comment(attrs: &[syn::Attribute]) -> Vec<String> {
|
||||
pub(crate) fn extract_doc_comment(attrs: &[syn::Attribute]) -> Vec<String> {
|
||||
// multiline comments (`/** ... */`) may have LFs (`\n`) in them,
|
||||
// we need to split so we could handle the lines correctly
|
||||
//
|
||||
|
@ -49,7 +49,7 @@ pub fn extract_doc_comment(attrs: &[syn::Attribute]) -> Vec<String> {
|
|||
lines
|
||||
}
|
||||
|
||||
pub fn format_doc_comment(
|
||||
pub(crate) fn format_doc_comment(
|
||||
lines: &[String],
|
||||
preprocess: bool,
|
||||
force_long: bool,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
pub trait SpanError {
|
||||
pub(crate) trait SpanError {
|
||||
#[allow(non_snake_case)]
|
||||
fn EXPECTED_Span_OR_ToTokens<D: std::fmt::Display>(&self, msg: D) -> syn::Error;
|
||||
}
|
||||
|
||||
pub trait ToTokensError {
|
||||
pub(crate) trait ToTokensError {
|
||||
#[allow(non_snake_case)]
|
||||
fn EXPECTED_Span_OR_ToTokens<D: std::fmt::Display>(&self, msg: D) -> syn::Error;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
pub mod error;
|
||||
pub(crate) mod error;
|
||||
|
||||
mod doc_comments;
|
||||
mod spanned;
|
||||
mod ty;
|
||||
|
||||
pub use doc_comments::extract_doc_comment;
|
||||
pub use doc_comments::format_doc_comment;
|
||||
pub(crate) use doc_comments::extract_doc_comment;
|
||||
pub(crate) use doc_comments::format_doc_comment;
|
||||
|
||||
pub use self::{
|
||||
pub(crate) use self::{
|
||||
spanned::Sp,
|
||||
ty::{inner_type, is_simple_ty, sub_type, subty_if_name, Ty},
|
||||
};
|
||||
|
|
|
@ -6,21 +6,21 @@ use std::ops::{Deref, DerefMut};
|
|||
|
||||
/// An entity with a span attached.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Sp<T> {
|
||||
pub(crate) struct Sp<T> {
|
||||
val: T,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl<T> Sp<T> {
|
||||
pub fn new(val: T, span: Span) -> Self {
|
||||
pub(crate) fn new(val: T, span: Span) -> Self {
|
||||
Sp { val, span }
|
||||
}
|
||||
|
||||
pub fn get(&self) -> &T {
|
||||
pub(crate) fn get(&self) -> &T {
|
||||
&self.val
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
pub(crate) fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use syn::{
|
|||
};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Ty {
|
||||
pub(crate) enum Ty {
|
||||
Unit,
|
||||
Vec,
|
||||
VecVec,
|
||||
|
@ -20,8 +20,8 @@ pub enum Ty {
|
|||
}
|
||||
|
||||
impl Ty {
|
||||
pub fn from_syn_ty(ty: &syn::Type) -> Sp<Self> {
|
||||
use self::Ty::*;
|
||||
pub(crate) fn from_syn_ty(ty: &Type) -> Sp<Self> {
|
||||
use self::Ty::{Option, OptionOption, OptionVec, OptionVecVec, Other, Unit, Vec, VecVec};
|
||||
let t = |kind| Sp::new(kind, ty.span());
|
||||
|
||||
if is_unit_ty(ty) {
|
||||
|
@ -41,7 +41,7 @@ impl Ty {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
pub(crate) fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Unit => "()",
|
||||
Self::Vec => "Vec<T>",
|
||||
|
@ -55,7 +55,7 @@ impl Ty {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn inner_type(field_ty: &syn::Type) -> &syn::Type {
|
||||
pub(crate) fn inner_type(field_ty: &Type) -> &Type {
|
||||
let ty = Ty::from_syn_ty(field_ty);
|
||||
match *ty {
|
||||
Ty::Vec | Ty::Option => sub_type(field_ty).unwrap_or(field_ty),
|
||||
|
@ -70,12 +70,12 @@ pub fn inner_type(field_ty: &syn::Type) -> &syn::Type {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn sub_type(ty: &syn::Type) -> Option<&syn::Type> {
|
||||
pub(crate) fn sub_type(ty: &Type) -> Option<&Type> {
|
||||
subty_if(ty, |_| true)
|
||||
}
|
||||
|
||||
fn only_last_segment(mut ty: &syn::Type) -> Option<&PathSegment> {
|
||||
while let syn::Type::Group(syn::TypeGroup { elem, .. }) = ty {
|
||||
fn only_last_segment(mut ty: &Type) -> Option<&PathSegment> {
|
||||
while let Type::Group(syn::TypeGroup { elem, .. }) = ty {
|
||||
ty = elem;
|
||||
}
|
||||
match ty {
|
||||
|
@ -92,7 +92,7 @@ fn only_last_segment(mut ty: &syn::Type) -> Option<&PathSegment> {
|
|||
}
|
||||
}
|
||||
|
||||
fn subty_if<F>(ty: &syn::Type, f: F) -> Option<&syn::Type>
|
||||
fn subty_if<F>(ty: &Type, f: F) -> Option<&Type>
|
||||
where
|
||||
F: FnOnce(&PathSegment) -> bool,
|
||||
{
|
||||
|
@ -113,11 +113,11 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
pub fn subty_if_name<'a>(ty: &'a syn::Type, name: &str) -> Option<&'a syn::Type> {
|
||||
pub(crate) fn subty_if_name<'a>(ty: &'a Type, name: &str) -> Option<&'a Type> {
|
||||
subty_if(ty, |seg| seg.ident == name)
|
||||
}
|
||||
|
||||
pub fn is_simple_ty(ty: &syn::Type, name: &str) -> bool {
|
||||
pub(crate) fn is_simple_ty(ty: &Type, name: &str) -> bool {
|
||||
only_last_segment(ty)
|
||||
.map(|segment| {
|
||||
if let PathArguments::None = segment.arguments {
|
||||
|
@ -129,12 +129,12 @@ pub fn is_simple_ty(ty: &syn::Type, name: &str) -> bool {
|
|||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn is_generic_ty(ty: &syn::Type, name: &str) -> bool {
|
||||
fn is_generic_ty(ty: &Type, name: &str) -> bool {
|
||||
subty_if_name(ty, name).is_some()
|
||||
}
|
||||
|
||||
fn is_unit_ty(ty: &syn::Type) -> bool {
|
||||
if let syn::Type::Tuple(tuple) = ty {
|
||||
fn is_unit_ty(ty: &Type) -> bool {
|
||||
if let Type::Tuple(tuple) = ty {
|
||||
tuple.elems.is_empty()
|
||||
} else {
|
||||
false
|
||||
|
|
|
@ -26,5 +26,11 @@ pre-release-replacements = [
|
|||
{file="README.md", search="github.com/clap-rs/clap/blob/[^/]+/", replace="github.com/clap-rs/clap/blob/{{tag_name}}/", exactly=4, prerelease = true},
|
||||
]
|
||||
|
||||
[dev-dependencies]
|
||||
automod = "1.0.14"
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use std::ffi::OsStr;
|
||||
|
||||
/// String-like methods for [`OsStr`]
|
||||
pub trait OsStrExt: private::Sealed {
|
||||
/// Converts to a string slice.
|
||||
///
|
||||
/// The Utf8Error is guaranteed to have a valid UTF8 boundary
|
||||
/// The `Utf8Error` is guaranteed to have a valid UTF8 boundary
|
||||
/// in its `valid_up_to()`
|
||||
fn try_str(&self) -> Result<&str, std::str::Utf8Error>;
|
||||
/// Returns `true` if the given pattern matches a sub-slice of
|
||||
|
@ -253,18 +254,15 @@ impl<'s, 'n> Iterator for Split<'s, 'n> {
|
|||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let haystack = self.haystack?;
|
||||
match haystack.split_once(self.needle) {
|
||||
Some((first, second)) => {
|
||||
if !haystack.is_empty() {
|
||||
debug_assert_ne!(haystack, second);
|
||||
}
|
||||
self.haystack = Some(second);
|
||||
Some(first)
|
||||
}
|
||||
None => {
|
||||
self.haystack = None;
|
||||
Some(haystack)
|
||||
if let Some((first, second)) = haystack.split_once(self.needle) {
|
||||
if !haystack.is_empty() {
|
||||
debug_assert_ne!(haystack, second);
|
||||
}
|
||||
self.haystack = Some(second);
|
||||
Some(first)
|
||||
} else {
|
||||
self.haystack = None;
|
||||
Some(haystack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -275,10 +273,12 @@ impl<'s, 'n> Iterator for Split<'s, 'n> {
|
|||
///
|
||||
/// `index` must be at a valid UTF-8 boundary
|
||||
pub(crate) unsafe fn split_at(os: &OsStr, index: usize) -> (&OsStr, &OsStr) {
|
||||
let bytes = os.as_encoded_bytes();
|
||||
let (first, second) = bytes.split_at(index);
|
||||
(
|
||||
OsStr::from_encoded_bytes_unchecked(first),
|
||||
OsStr::from_encoded_bytes_unchecked(second),
|
||||
)
|
||||
unsafe {
|
||||
let bytes = os.as_encoded_bytes();
|
||||
let (first, second) = bytes.split_at(index);
|
||||
(
|
||||
OsStr::from_encoded_bytes_unchecked(first),
|
||||
OsStr::from_encoded_bytes_unchecked(second),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,11 @@
|
|||
//! println!("{args:?}");
|
||||
//! ```
|
||||
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![warn(missing_docs)]
|
||||
#![warn(clippy::print_stderr)]
|
||||
#![warn(clippy::print_stdout)]
|
||||
|
||||
mod ext;
|
||||
|
||||
use std::ffi::OsStr;
|
||||
|
@ -158,7 +163,7 @@ impl RawArgs {
|
|||
/// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::<Vec<_>>();
|
||||
/// println!("{paths:?}");
|
||||
/// ```
|
||||
pub fn new(iter: impl IntoIterator<Item = impl Into<std::ffi::OsString>>) -> Self {
|
||||
pub fn new(iter: impl IntoIterator<Item = impl Into<OsString>>) -> Self {
|
||||
let iter = iter.into_iter();
|
||||
Self::from(iter)
|
||||
}
|
||||
|
|
1
clap_lex/tests/testsuite/main.rs
Normal file
1
clap_lex/tests/testsuite/main.rs
Normal file
|
@ -0,0 +1 @@
|
|||
automod::dir!("tests/testsuite");
|
|
@ -6,7 +6,7 @@ use std::ffi::OsStr;
|
|||
fn to_long_stdio() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "-"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(!next.is_long());
|
||||
|
@ -18,7 +18,7 @@ fn to_long_stdio() {
|
|||
fn to_long_no_escape() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "--"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(!next.is_long());
|
||||
|
@ -30,7 +30,7 @@ fn to_long_no_escape() {
|
|||
fn to_long_no_value() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "--long"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(next.is_long());
|
||||
|
@ -44,7 +44,7 @@ fn to_long_no_value() {
|
|||
fn to_long_with_empty_value() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "--long="]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(next.is_long());
|
||||
|
@ -58,7 +58,7 @@ fn to_long_with_empty_value() {
|
|||
fn to_long_with_value() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "--long=hello"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(next.is_long());
|
||||
|
@ -72,7 +72,7 @@ fn to_long_with_value() {
|
|||
fn to_short_stdio() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "-"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(!next.is_short());
|
||||
|
@ -84,7 +84,7 @@ fn to_short_stdio() {
|
|||
fn to_short_escape() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "--"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(!next.is_short());
|
||||
|
@ -96,7 +96,7 @@ fn to_short_escape() {
|
|||
fn to_short_long() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "--long"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(!next.is_short());
|
||||
|
@ -108,7 +108,7 @@ fn to_short_long() {
|
|||
fn to_short() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "-short"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(next.is_short());
|
||||
|
@ -123,7 +123,7 @@ fn is_negative_number() {
|
|||
for number in ["-10.0", "-1", "-100", "-3.5", "-1e10", "-1.3e10"] {
|
||||
let raw = clap_lex::RawArgs::new(["bin", number]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(next.is_negative_number());
|
||||
|
@ -134,7 +134,7 @@ fn is_negative_number() {
|
|||
fn is_positive_number() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "10.0"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(!next.is_negative_number());
|
||||
|
@ -145,7 +145,7 @@ fn is_not_number() {
|
|||
for number in ["--10.0", "-..", "-2..", "-e", "-1e", "-1e10.2", "-.2"] {
|
||||
let raw = clap_lex::RawArgs::new(["bin", number]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(
|
||||
|
@ -159,7 +159,7 @@ fn is_not_number() {
|
|||
fn is_stdio() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "-"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(next.is_stdio());
|
||||
|
@ -169,7 +169,7 @@ fn is_stdio() {
|
|||
fn is_not_stdio() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "--"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(!next.is_stdio());
|
||||
|
@ -179,7 +179,7 @@ fn is_not_stdio() {
|
|||
fn is_escape() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "--"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(next.is_escape());
|
||||
|
@ -189,7 +189,7 @@ fn is_escape() {
|
|||
fn is_not_escape() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "-"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(!next.is_escape());
|
|
@ -38,7 +38,11 @@ clap = { path = "../", version = "4.0.0", default-features = false, features = [
|
|||
[dev-dependencies]
|
||||
snapbox = { version = "0.5.9", features = ["diff"] }
|
||||
clap = { path = "../", version = "4.0.0", default-features = false, features = ["std", "help"] }
|
||||
automod = "1.0.14"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
debug = ["clap/debug"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::io;
|
|||
|
||||
// Run this example as `cargo run --example man | man -l -`.
|
||||
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
fn main() -> Result<(), io::Error> {
|
||||
let cmd = Command::new("myapp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>:Ola Nordmann <old@nordmann.no>")
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#![doc(html_logo_url = "https://raw.githubusercontent.com/clap-rs/clap/master/assets/clap.png")]
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![warn(missing_docs, trivial_casts, unused_allocation, trivial_numeric_casts)]
|
||||
#![doc(html_logo_url = "https://raw.githubusercontent.com/clap-rs/clap/master/assets/clap.png")]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(missing_docs)]
|
||||
#![warn(missing_docs)]
|
||||
#![warn(clippy::print_stderr)]
|
||||
#![warn(clippy::print_stdout)]
|
||||
|
||||
mod render;
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ pub(crate) fn synopsis(roff: &mut Roff, cmd: &clap::Command) {
|
|||
};
|
||||
|
||||
if matches!(opt.get_action(), ArgAction::Count) {
|
||||
line.push(roman("..."))
|
||||
line.push(roman("..."));
|
||||
}
|
||||
line.push(roman(" "));
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) {
|
|||
roff.control("RE", []);
|
||||
}
|
||||
|
||||
possible_options(roff, pos, arg_help_written)
|
||||
possible_options(roff, pos, arg_help_written);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,7 +241,7 @@ fn subcommand_markers(cmd: &clap::Command) -> (&'static str, &'static str) {
|
|||
markers(cmd.is_subcommand_required_set())
|
||||
}
|
||||
|
||||
fn option_markers(opt: &clap::Arg) -> (&'static str, &'static str) {
|
||||
fn option_markers(opt: &Arg) -> (&'static str, &'static str) {
|
||||
markers(opt.is_required_set())
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,7 @@ fn long_option(opt: &str) -> Inline {
|
|||
bold(format!("--{opt}"))
|
||||
}
|
||||
|
||||
fn option_help(opt: &clap::Arg) -> Option<&clap::builder::StyledStr> {
|
||||
fn option_help(opt: &Arg) -> Option<&clap::builder::StyledStr> {
|
||||
if !opt.is_hide_long_help_set() {
|
||||
let long_help = opt.get_long_help();
|
||||
if long_help.is_some() {
|
||||
|
@ -275,7 +275,7 @@ fn option_help(opt: &clap::Arg) -> Option<&clap::builder::StyledStr> {
|
|||
None
|
||||
}
|
||||
|
||||
fn option_environment(opt: &clap::Arg) -> Option<Vec<Inline>> {
|
||||
fn option_environment(opt: &Arg) -> Option<Vec<Inline>> {
|
||||
if opt.is_hide_env_set() {
|
||||
return None;
|
||||
} else if let Some(env) = opt.get_env() {
|
||||
|
@ -289,7 +289,7 @@ fn option_environment(opt: &clap::Arg) -> Option<Vec<Inline>> {
|
|||
None
|
||||
}
|
||||
|
||||
fn option_default_values(opt: &clap::Arg) -> Option<String> {
|
||||
fn option_default_values(opt: &Arg) -> Option<String> {
|
||||
if opt.is_hide_default_value_set() || !opt.get_num_args().expect("built").takes_values() {
|
||||
return None;
|
||||
} else if !opt.get_default_values().is_empty() {
|
||||
|
@ -306,7 +306,7 @@ fn option_default_values(opt: &clap::Arg) -> Option<String> {
|
|||
None
|
||||
}
|
||||
|
||||
fn get_possible_values(arg: &clap::Arg) -> Option<(Vec<String>, bool)> {
|
||||
fn get_possible_values(arg: &Arg) -> Option<(Vec<String>, bool)> {
|
||||
if arg.is_hide_possible_values_set() {
|
||||
return None;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue