chore(vendor): add anyhow crate
This commit was merged in pull request #68.
This commit is contained in:
1
third_party/crates/clap_derive-4.6.7/.cargo-checksum.json
vendored
Normal file
1
third_party/crates/clap_derive-4.6.7/.cargo-checksum.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"$comment":"This file only protects against accidental modifications. It is not a security mechanism and does not protect against malicious changes.","files":{".cargo_vcs_info.json":"98d476fa0ef38d822c751f33bee6f693d821ae676b29a3d28f9156533fca4250","Cargo.lock":"ee882cf89c1d1c0172059f84548ca26a6b8b9e60047fab6b99414ae43347ce88","Cargo.toml":"6055bb6c6476792910d3e50a1edd321fda0bf4ae48e0a2d3cb07e89e4736a676","Cargo.toml.orig":"9d29042b9ecbc3de54af196ef3c8237bfdd8380b17db60fdd08e6f85da2f9aa0","LICENSE-APACHE":"249fdb6694467dd615b259f7ddde07be3f8ae5a72cecebb0e24f6629af4215fe","LICENSE-MIT":"6efb0476a1cc085077ed49357026d8c173bf33017278ef440f222fb9cbcb66e6","README.md":"c7e86ee3235f6db632c6b6666508c0db60f3572a83fe69b2b920bf4e6f98e11e","src/attr.rs":"94861c00bc57d3b063d6042673752b6b708fbfa12f75aa02f2e414fa5da64bbf","src/derives/args.rs":"ef2fe1a4d886b42984c29b59bdeb1c86949c023ac66fa48bef22eb9d2aa00016","src/derives/into_app.rs":"fb1d0708ede65e15ae3ec80ced5a38fa4960c372ceae65c916b48bcc9bd5a9dc","src/derives/mod.rs":"660c5d27942993d7331025ddfc29ee4c1d7f3a7f49ae2ee2293624e6b2abd952","src/derives/parser.rs":"11af0826ebec312d44dfec3d94d8c516e4bf9fdb1bd0712e26fd9207b643fbc0","src/derives/subcommand.rs":"dc86761722cd4b8f781e343cd8e9142aa54fcdd937ec7caff1028605204daff9","src/derives/value_enum.rs":"251a794bfa7e8a267abca8db518175ddfaeb6b68e75591742bae06f986da722a","src/dummies.rs":"f3217ddec1c671e37c6efbc471cda390b0a98092c1bc8b019b02ed3379dca498","src/item.rs":"e62a263bbfece319b5b844d592b2f362f9b9c3f4c5b04759d4d14edb66aca67f","src/lib.rs":"ecb7d751f03cb24ae5ba7c963d2298716d67cae9baa16c7b301b198e810ca893","src/macros.rs":"3f60c5673c005548bbcd47f84e1f0fc6d1fb190d467681c3d9c52014bb4c6d36","src/utils/doc_comments.rs":"1f106617e61102c267f69ab82aadf38174c75e62a065eb751014ec885e349069","src/utils/error.rs":"977fd26c7ec7c33e20b1cf20944ed1e529b52a8f733694e30c211f97c8c32e72","src/utils/mod.rs":"d7fd1c1a8f45816b49d22c224546dcd11939c7c5fe7d38944e76abe1d78e13d6","src/utils/spanned.rs":"4ed8b8d350f7ee3c15a3a108856c6fb011637fa3a583ae128573061bd5291faf","src/utils/ty.rs":"8e9a298c7b990a1d067ad9a883f3ffbf27cd0adb05cc7e348eafb7a4d46dbb79"},"package":"f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0"}
|
||||
6
third_party/crates/clap_derive-4.6.7/.cargo_vcs_info.json
vendored
Normal file
6
third_party/crates/clap_derive-4.6.7/.cargo_vcs_info.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"git": {
|
||||
"sha1": "13f2db5072d600c11d8d6298e4e9ba53ffc6c1ab"
|
||||
},
|
||||
"path_in_vcs": "clap_derive"
|
||||
}
|
||||
119
third_party/crates/clap_derive-4.6.7/BUILD.bazel
vendored
Normal file
119
third_party/crates/clap_derive-4.6.7/BUILD.bazel
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
###############################################################################
|
||||
# @generated
|
||||
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
|
||||
# regenerate this file, run the following:
|
||||
#
|
||||
# bazel run @@//third_party:vendor_crates
|
||||
###############################################################################
|
||||
|
||||
load("@rules_rust//cargo:defs.bzl", "cargo_toml_env_vars")
|
||||
load("@rules_rust//rust:defs.bzl", "rust_proc_macro")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
cargo_toml_env_vars(
|
||||
name = "cargo_toml_env_vars",
|
||||
src = "Cargo.toml",
|
||||
)
|
||||
|
||||
rust_proc_macro(
|
||||
name = "clap_derive",
|
||||
srcs = glob(
|
||||
include = ["**/*.rs"],
|
||||
allow_empty = False,
|
||||
),
|
||||
compile_data = glob(
|
||||
include = ["**"],
|
||||
allow_empty = True,
|
||||
exclude = [
|
||||
"**/* *",
|
||||
".tmp_git_root/**/*",
|
||||
"BUILD",
|
||||
"BUILD.bazel",
|
||||
"WORKSPACE",
|
||||
"WORKSPACE.bazel",
|
||||
],
|
||||
),
|
||||
crate_features = [
|
||||
"default",
|
||||
],
|
||||
crate_root = "src/lib.rs",
|
||||
edition = "2024",
|
||||
rustc_env_files = [
|
||||
":cargo_toml_env_vars",
|
||||
],
|
||||
rustc_flags = [
|
||||
"--cap-lints=allow",
|
||||
],
|
||||
tags = [
|
||||
"cargo-bazel",
|
||||
"crate-name=clap_derive",
|
||||
"manual",
|
||||
"noclippy",
|
||||
"norustfmt",
|
||||
],
|
||||
target_compatible_with = select({
|
||||
"@rules_rust//rust/platform:aarch64-apple-darwin": [],
|
||||
"@rules_rust//rust/platform:aarch64-apple-ios": [],
|
||||
"@rules_rust//rust/platform:aarch64-apple-ios-macabi": [],
|
||||
"@rules_rust//rust/platform:aarch64-apple-ios-sim": [],
|
||||
"@rules_rust//rust/platform:aarch64-linux-android": [],
|
||||
"@rules_rust//rust/platform:aarch64-pc-windows-msvc": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-fuchsia": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-none": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-uefi": [],
|
||||
"@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [],
|
||||
"@rules_rust//rust/platform:arm-unknown-linux-musleabi": [],
|
||||
"@rules_rust//rust/platform:armv7-linux-androideabi": [],
|
||||
"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [],
|
||||
"@rules_rust//rust/platform:i686-apple-darwin": [],
|
||||
"@rules_rust//rust/platform:i686-linux-android": [],
|
||||
"@rules_rust//rust/platform:i686-pc-windows-msvc": [],
|
||||
"@rules_rust//rust/platform:i686-unknown-freebsd": [],
|
||||
"@rules_rust//rust/platform:i686-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:loongarch64-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:mips-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:riscv32imac-unknown-none-elf": [],
|
||||
"@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [],
|
||||
"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [],
|
||||
"@rules_rust//rust/platform:s390x-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:sparc64-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:sparc64-unknown-netbsd": [],
|
||||
"@rules_rust//rust/platform:sparc64-unknown-openbsd": [],
|
||||
"@rules_rust//rust/platform:thumbv6m-none-eabi": [],
|
||||
"@rules_rust//rust/platform:thumbv7em-none-eabi": [],
|
||||
"@rules_rust//rust/platform:thumbv7em-none-eabihf": [],
|
||||
"@rules_rust//rust/platform:thumbv7m-none-eabi": [],
|
||||
"@rules_rust//rust/platform:thumbv8m.main-none-eabi": [],
|
||||
"@rules_rust//rust/platform:thumbv8m.main-none-eabihf": [],
|
||||
"@rules_rust//rust/platform:wasm32-unknown-emscripten": [],
|
||||
"@rules_rust//rust/platform:wasm32-unknown-unknown": [],
|
||||
"@rules_rust//rust/platform:wasm32-wasip1": [],
|
||||
"@rules_rust//rust/platform:wasm32-wasip1-threads": [],
|
||||
"@rules_rust//rust/platform:wasm32-wasip2": [],
|
||||
"@rules_rust//rust/platform:x86_64-apple-darwin": [],
|
||||
"@rules_rust//rust/platform:x86_64-apple-ios": [],
|
||||
"@rules_rust//rust/platform:x86_64-apple-ios-macabi": [],
|
||||
"@rules_rust//rust/platform:x86_64-linux-android": [],
|
||||
"@rules_rust//rust/platform:x86_64-pc-windows-msvc": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-freebsd": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-fuchsia": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-none": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-uefi": [],
|
||||
"//conditions:default": ["@platforms//:incompatible"],
|
||||
}),
|
||||
version = "4.6.7",
|
||||
deps = [
|
||||
"//third_party/crates/heck-0.5.0:heck",
|
||||
"//third_party/crates/proc-macro2-1.0.107:proc_macro2",
|
||||
"//third_party/crates/quote-1.0.47:quote",
|
||||
"//third_party/crates/syn-3.0.6:syn",
|
||||
],
|
||||
)
|
||||
91
third_party/crates/clap_derive-4.6.7/Cargo.lock
generated
vendored
Normal file
91
third_party/crates/clap_derive-4.6.7/Cargo.lock
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.6.7"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"pulldown-cmark",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"memchr",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a207d6d6a2b7fc470b80443726053f18a2481b7e1eee970597051596567987a3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
180
third_party/crates/clap_derive-4.6.7/Cargo.toml
vendored
Normal file
180
third_party/crates/clap_derive-4.6.7/Cargo.toml
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
name = "clap_derive"
|
||||
version = "4.6.7"
|
||||
build = false
|
||||
include = [
|
||||
"/build.rs",
|
||||
"/src/**/*",
|
||||
"/Cargo.toml",
|
||||
"/Cargo.lock",
|
||||
"/LICENSE*",
|
||||
"/README.md",
|
||||
"/examples/**/*",
|
||||
]
|
||||
autolib = false
|
||||
autobins = false
|
||||
autoexamples = false
|
||||
autotests = false
|
||||
autobenches = false
|
||||
description = "Parse command line argument by defining a struct, derive crate."
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"clap",
|
||||
"cli",
|
||||
"parse",
|
||||
"derive",
|
||||
"proc_macro",
|
||||
]
|
||||
categories = [
|
||||
"command-line-interface",
|
||||
"development-tools::procedural-macro-helpers",
|
||||
]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/clap-rs/clap"
|
||||
resolver = "2"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
rustdoc-args = ["--generate-link-to-definition"]
|
||||
|
||||
[package.metadata.release]
|
||||
shared-version = true
|
||||
dependent-version = "upgrade"
|
||||
tag-name = "v{{version}}"
|
||||
|
||||
[features]
|
||||
debug = []
|
||||
default = []
|
||||
deprecated = []
|
||||
raw-deprecated = ["deprecated"]
|
||||
unstable-markdown = [
|
||||
"dep:pulldown-cmark",
|
||||
"dep:anstyle",
|
||||
]
|
||||
unstable-v5 = ["deprecated"]
|
||||
|
||||
[lib]
|
||||
name = "clap_derive"
|
||||
path = "src/lib.rs"
|
||||
bench = false
|
||||
proc-macro = true
|
||||
|
||||
[dependencies.anstyle]
|
||||
version = "1.0.14"
|
||||
optional = true
|
||||
|
||||
[dependencies.heck]
|
||||
version = "0.5.0"
|
||||
|
||||
[dependencies.proc-macro2]
|
||||
version = "1.0.106"
|
||||
|
||||
[dependencies.pulldown-cmark]
|
||||
version = "0.13.3"
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dependencies.quote]
|
||||
version = "1.0.45"
|
||||
|
||||
[dependencies.syn]
|
||||
version = "3.0.2"
|
||||
features = ["full"]
|
||||
|
||||
[lints.clippy]
|
||||
assigning_clones = "allow"
|
||||
blocks_in_conditions = "allow"
|
||||
bool_assert_comparison = "allow"
|
||||
branches_sharing_code = "allow"
|
||||
byte_char_slices = "allow"
|
||||
checked_conversions = "warn"
|
||||
collapsible_else_if = "allow"
|
||||
collapsible_match = "allow"
|
||||
collection_is_never_read = "warn"
|
||||
create_dir = "warn"
|
||||
dbg_macro = "warn"
|
||||
debug_assert_with_mut_call = "warn"
|
||||
doc_markdown = "warn"
|
||||
empty_enums = "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 = "warn"
|
||||
float_cmp_const = "warn"
|
||||
fn_params_excessive_bools = "warn"
|
||||
fn_to_numeric_cast_any = "warn"
|
||||
if_same_then_else = "allow"
|
||||
implicit_clone = "warn"
|
||||
imprecise_flops = "warn"
|
||||
inconsistent_struct_constructor = "warn"
|
||||
inefficient_to_string = "warn"
|
||||
infinite_loop = "warn"
|
||||
invalid_upcast_comparisons = "warn"
|
||||
large_digit_groups = "warn"
|
||||
large_stack_arrays = "warn"
|
||||
large_types_passed_by_value = "warn"
|
||||
let_and_return = "allow"
|
||||
linkedlist = "warn"
|
||||
lossy_float_literal = "warn"
|
||||
macro_use_imports = "warn"
|
||||
mem_forget = "warn"
|
||||
mismatching_type_param_order = "warn"
|
||||
multiple_bound_locations = "allow"
|
||||
mutex_integer = "warn"
|
||||
needless_continue = "allow"
|
||||
needless_for_each = "warn"
|
||||
negative_feature_names = "warn"
|
||||
partial_pub_fields = "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"
|
||||
result_large_err = "allow"
|
||||
same_functions_in_if_condition = "warn"
|
||||
self_named_module_files = "warn"
|
||||
semicolon_if_nothing_returned = "warn"
|
||||
str_to_string = "warn"
|
||||
string_add = "warn"
|
||||
string_add_assign = "warn"
|
||||
string_lit_as_bytes = "warn"
|
||||
todo = "warn"
|
||||
trait_duplication_in_bounds = "warn"
|
||||
uninlined_format_args = "warn"
|
||||
unnecessary_safety_comment = "warn"
|
||||
unnecessary_safety_doc = "warn"
|
||||
unseparated_literal_suffix = "warn"
|
||||
use_self = "warn"
|
||||
verbose_file_reads = "warn"
|
||||
zero_sized_map_values = "warn"
|
||||
|
||||
[lints.rust]
|
||||
non_ascii_idents = "warn"
|
||||
trivial_numeric_casts = "warn"
|
||||
unreachable_pub = "warn"
|
||||
unsafe_op_in_unsafe_fn = "warn"
|
||||
unused_lifetimes = "warn"
|
||||
unused_macro_rules = "warn"
|
||||
unused_qualifications = "warn"
|
||||
|
||||
[lints.rust.rust_2018_idioms]
|
||||
level = "warn"
|
||||
priority = -1
|
||||
49
third_party/crates/clap_derive-4.6.7/Cargo.toml.orig
generated
vendored
Normal file
49
third_party/crates/clap_derive-4.6.7/Cargo.toml.orig
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
[package]
|
||||
name = "clap_derive"
|
||||
version = "4.6.7"
|
||||
description = "Parse command line argument by defining a struct, derive crate."
|
||||
categories = ["command-line-interface", "development-tools::procedural-macro-helpers"]
|
||||
keywords = [
|
||||
"clap",
|
||||
"cli",
|
||||
"parse",
|
||||
"derive",
|
||||
"proc_macro"
|
||||
]
|
||||
repository.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
include.workspace = true
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
rustdoc-args = ["--generate-link-to-definition"]
|
||||
|
||||
[package.metadata.release]
|
||||
shared-version = true
|
||||
dependent-version = "upgrade"
|
||||
tag-name = "v{{version}}"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "3.0.2", features = ["full"] }
|
||||
quote = "1.0.45"
|
||||
proc-macro2 = "1.0.106"
|
||||
heck = "0.5.0"
|
||||
pulldown-cmark = { version = "0.13.3", default-features = false, optional = true}
|
||||
anstyle = {version ="1.0.14", optional = true}
|
||||
|
||||
[features]
|
||||
default = []
|
||||
debug = []
|
||||
unstable-v5 = ["deprecated"]
|
||||
deprecated = []
|
||||
raw-deprecated = ["deprecated"]
|
||||
unstable-markdown = ["dep:pulldown-cmark", "dep:anstyle"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
202
third_party/crates/clap_derive-4.6.7/LICENSE-APACHE
vendored
Normal file
202
third_party/crates/clap_derive-4.6.7/LICENSE-APACHE
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright Individual contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
19
third_party/crates/clap_derive-4.6.7/LICENSE-MIT
vendored
Normal file
19
third_party/crates/clap_derive-4.6.7/LICENSE-MIT
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) Individual contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
25
third_party/crates/clap_derive-4.6.7/README.md
vendored
Normal file
25
third_party/crates/clap_derive-4.6.7/README.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# `clap_derive`
|
||||
|
||||
Macro implementation for clap's derives.
|
||||
|
||||
[docs.rs](https://docs.rs/clap)
|
||||
- [Derive Tutorial](https://docs.rs/clap/latest/clap/_derive/_tutorial/index.html)
|
||||
- [Derive Reference](https://docs.rs/clap/latest/clap/_derive/index.html)
|
||||
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/license/mit>)
|
||||
|
||||
at your option.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally
|
||||
submitted for inclusion in the work by you, as defined in the Apache-2.0
|
||||
license, shall be dual-licensed as above, without any additional terms or
|
||||
conditions.
|
||||
|
||||
See [CONTRIBUTING](CONTRIBUTING.md) for more details.
|
||||
238
third_party/crates/clap_derive-4.6.7/src/attr.rs
vendored
Normal file
238
third_party/crates/clap_derive-4.6.7/src/attr.rs
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::ToTokens;
|
||||
use quote::quote;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{
|
||||
Attribute, Expr, Ident, LitStr, Token, parenthesized,
|
||||
parse::{Parse, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
};
|
||||
|
||||
use crate::utils::Sp;
|
||||
|
||||
#[derive(Clone)]
|
||||
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(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") {
|
||||
Sp::new(AttrKind::Clap, attr.path().span())
|
||||
} else if attr.path().is_ident("structopt") {
|
||||
Sp::new(AttrKind::StructOpt, attr.path().span())
|
||||
} else if attr.path().is_ident("command") {
|
||||
Sp::new(AttrKind::Command, attr.path().span())
|
||||
} else if attr.path().is_ident("group") {
|
||||
Sp::new(AttrKind::Group, attr.path().span())
|
||||
} else if attr.path().is_ident("arg") {
|
||||
Sp::new(AttrKind::Arg, attr.path().span())
|
||||
} else if attr.path().is_ident("value") {
|
||||
Sp::new(AttrKind::Value, attr.path().span())
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
for mut attr in attr.parse_args_with(Punctuated::<Self, Token![,]>::parse_terminated)? {
|
||||
attr.kind = kind;
|
||||
parsed.push(attr);
|
||||
}
|
||||
}
|
||||
Ok(parsed)
|
||||
}
|
||||
|
||||
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(crate) fn lit_str_or_abort(&self) -> Result<&LitStr, syn::Error> {
|
||||
let value = self.value_or_abort()?;
|
||||
match value {
|
||||
AttrValue::Expr(Expr::Lit(expr)) => match &expr.lit {
|
||||
syn::Lit::Str(lit) => Ok(lit),
|
||||
_ => {
|
||||
abort!(
|
||||
expr,
|
||||
"attribute `{}` can only accept string literals",
|
||||
self.name
|
||||
)
|
||||
}
|
||||
},
|
||||
AttrValue::Expr(expr) => {
|
||||
abort!(
|
||||
expr,
|
||||
"attribute `{}` can only accept string literals",
|
||||
self.name
|
||||
)
|
||||
}
|
||||
AttrValue::Call(_) => {
|
||||
abort!(
|
||||
self.name,
|
||||
"attribute `{}` can only accept string literals",
|
||||
self.name
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn lit_bool_or_abort(&self) -> Result<bool, syn::Error> {
|
||||
let value = self.value_or_abort()?;
|
||||
match value {
|
||||
AttrValue::Expr(Expr::Lit(syn::ExprLit {
|
||||
lit: syn::Lit::Bool(lit),
|
||||
..
|
||||
})) => Ok(lit.value()),
|
||||
_ => abort!(
|
||||
self.name,
|
||||
"attribute `{}` can only accept bool literals",
|
||||
self.name
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for ClapAttr {
|
||||
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
|
||||
let name: Ident = input.parse()?;
|
||||
let name_str = name.to_string();
|
||||
|
||||
let magic = match name_str.as_str() {
|
||||
"rename_all" => Some(MagicAttrName::RenameAll),
|
||||
"rename_all_env" => Some(MagicAttrName::RenameAllEnv),
|
||||
"skip" => Some(MagicAttrName::Skip),
|
||||
"next_display_order" => Some(MagicAttrName::NextDisplayOrder),
|
||||
"next_help_heading" => Some(MagicAttrName::NextHelpHeading),
|
||||
"default_value_t" => Some(MagicAttrName::DefaultValueT),
|
||||
"default_values_t" => Some(MagicAttrName::DefaultValuesT),
|
||||
"default_value_os_t" => Some(MagicAttrName::DefaultValueOsT),
|
||||
"default_values_os_t" => Some(MagicAttrName::DefaultValuesOsT),
|
||||
"long" => Some(MagicAttrName::Long),
|
||||
"short" => Some(MagicAttrName::Short),
|
||||
"value_parser" => Some(MagicAttrName::ValueParser),
|
||||
"action" => Some(MagicAttrName::Action),
|
||||
"env" => Some(MagicAttrName::Env),
|
||||
"flatten" => Some(MagicAttrName::Flatten),
|
||||
"value_enum" => Some(MagicAttrName::ValueEnum),
|
||||
"from_global" => Some(MagicAttrName::FromGlobal),
|
||||
"subcommand" => Some(MagicAttrName::Subcommand),
|
||||
"external_subcommand" => Some(MagicAttrName::ExternalSubcommand),
|
||||
"verbatim_doc_comment" => Some(MagicAttrName::VerbatimDocComment),
|
||||
"about" => Some(MagicAttrName::About),
|
||||
"long_about" => Some(MagicAttrName::LongAbout),
|
||||
"long_help" => Some(MagicAttrName::LongHelp),
|
||||
"author" => Some(MagicAttrName::Author),
|
||||
"version" => Some(MagicAttrName::Version),
|
||||
"defer" => Some(MagicAttrName::Defer),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let value = if input.peek(Token![=]) {
|
||||
// `name = value` attributes.
|
||||
let assign_token = input.parse::<Token![=]>()?; // skip '='
|
||||
match input.parse::<Expr>() {
|
||||
Ok(expr) => Some(AttrValue::Expr(expr)),
|
||||
|
||||
Err(_) => abort! {
|
||||
assign_token,
|
||||
"expected `string literal` or `expression` after `=`"
|
||||
},
|
||||
}
|
||||
} else if input.peek(syn::token::Paren) {
|
||||
// `name(...)` attributes.
|
||||
let nested;
|
||||
parenthesized!(nested in input);
|
||||
|
||||
let method_args: Punctuated<_, _> = nested.parse_terminated(Expr::parse, Token![,])?;
|
||||
Some(AttrValue::Call(Vec::from_iter(method_args)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
kind: Sp::new(AttrKind::Clap, name.span()),
|
||||
name,
|
||||
magic,
|
||||
value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub(crate) enum MagicAttrName {
|
||||
Short,
|
||||
Long,
|
||||
ValueParser,
|
||||
Action,
|
||||
Env,
|
||||
Flatten,
|
||||
ValueEnum,
|
||||
FromGlobal,
|
||||
Subcommand,
|
||||
VerbatimDocComment,
|
||||
ExternalSubcommand,
|
||||
About,
|
||||
LongAbout,
|
||||
LongHelp,
|
||||
Author,
|
||||
Version,
|
||||
RenameAllEnv,
|
||||
RenameAll,
|
||||
Skip,
|
||||
DefaultValueT,
|
||||
DefaultValuesT,
|
||||
DefaultValueOsT,
|
||||
DefaultValuesOsT,
|
||||
NextDisplayOrder,
|
||||
NextHelpHeading,
|
||||
Defer,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub(crate) enum AttrValue {
|
||||
Expr(Expr),
|
||||
Call(Vec<Expr>),
|
||||
}
|
||||
|
||||
impl ToTokens for AttrValue {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match self {
|
||||
Self::Expr(t) => t.to_tokens(tokens),
|
||||
Self::Call(t) => {
|
||||
let t = quote!(#(#t),*);
|
||||
t.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub(crate) enum AttrKind {
|
||||
Clap,
|
||||
StructOpt,
|
||||
Command,
|
||||
Group,
|
||||
Arg,
|
||||
Value,
|
||||
}
|
||||
|
||||
impl AttrKind {
|
||||
pub(crate) fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Clap => "clap",
|
||||
Self::StructOpt => "structopt",
|
||||
Self::Command => "command",
|
||||
Self::Group => "group",
|
||||
Self::Arg => "arg",
|
||||
Self::Value => "value",
|
||||
}
|
||||
}
|
||||
}
|
||||
792
third_party/crates/clap_derive-4.6.7/src/derives/args.rs
vendored
Normal file
792
third_party/crates/clap_derive-4.6.7/src/derives/args.rs
vendored
Normal file
@@ -0,0 +1,792 @@
|
||||
// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
|
||||
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
|
||||
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//
|
||||
// This work was derived from Structopt (https://github.com/TeXitoi/structopt)
|
||||
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
|
||||
// MIT/Apache 2.0 license.
|
||||
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use syn::{
|
||||
Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Generics, punctuated::Punctuated,
|
||||
spanned::Spanned, token::Comma,
|
||||
};
|
||||
|
||||
use crate::item::{Item, Kind, Name};
|
||||
use crate::utils::{Sp, Ty, inner_type, sub_type};
|
||||
|
||||
pub(crate) fn derive_args(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
let ident = &input.ident;
|
||||
|
||||
match input.data {
|
||||
Data::Struct(DataStruct {
|
||||
fields: Fields::Named(ref fields),
|
||||
..
|
||||
}) => {
|
||||
let name = Name::Derived(ident.clone());
|
||||
let item = Item::from_args_struct(input, name)?;
|
||||
let fields = collect_args_fields(&item, fields)?;
|
||||
gen_for_struct(&item, ident, &input.generics, &fields)
|
||||
}
|
||||
Data::Struct(DataStruct {
|
||||
fields: Fields::Unit,
|
||||
..
|
||||
}) => {
|
||||
let name = Name::Derived(ident.clone());
|
||||
let item = Item::from_args_struct(input, name)?;
|
||||
let fields = Punctuated::<Field, Comma>::new();
|
||||
let fields = fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let item = Item::from_args_field(field, item.casing(), item.env_casing())?;
|
||||
Ok((field, item))
|
||||
})
|
||||
.collect::<Result<Vec<_>, syn::Error>>()?;
|
||||
gen_for_struct(&item, ident, &input.generics, &fields)
|
||||
}
|
||||
_ => abort_call_site!("`#[derive(Args)]` only supports non-tuple structs"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn gen_for_struct(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
generics: &Generics,
|
||||
fields: &[(&Field, Item)],
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
if !matches!(&*item.kind(), Kind::Command(_)) {
|
||||
abort! { item.kind().span(),
|
||||
"`{}` cannot be used with `#[command]`",
|
||||
item.kind().name(),
|
||||
}
|
||||
}
|
||||
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let constructor = gen_constructor(fields)?;
|
||||
let updater = gen_updater(fields, true)?;
|
||||
let raw_deprecated = raw_deprecated();
|
||||
|
||||
let app_var = Ident::new("__clap_app", Span::call_site());
|
||||
let augmentation = gen_augment(fields, &app_var, item, false)?;
|
||||
let augmentation_update = gen_augment(fields, &app_var, item, true)?;
|
||||
let initial_app_methods = item.initial_top_level_methods();
|
||||
let final_app_methods = item.final_top_level_methods();
|
||||
|
||||
let group_id = if item.skip_group() {
|
||||
quote!(None)
|
||||
} else {
|
||||
let group_id = item.group_id();
|
||||
quote!(Some(clap::Id::from(#group_id)))
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
#[allow(
|
||||
dead_code,
|
||||
unreachable_code,
|
||||
unused_variables,
|
||||
unused_braces,
|
||||
unused_qualifications,
|
||||
)]
|
||||
#[allow(
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::pedantic,
|
||||
clippy::restriction,
|
||||
clippy::perf,
|
||||
clippy::deprecated,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
clippy::suspicious_else_formatting,
|
||||
clippy::almost_swapped,
|
||||
clippy::redundant_locals,
|
||||
)]
|
||||
#[automatically_derived]
|
||||
impl #impl_generics clap::FromArgMatches for #item_name #ty_generics #where_clause {
|
||||
fn from_arg_matches(__clap_arg_matches: &clap::ArgMatches) -> ::std::result::Result<Self, clap::Error> {
|
||||
Self::from_arg_matches_mut(&mut __clap_arg_matches.clone())
|
||||
}
|
||||
|
||||
fn from_arg_matches_mut(__clap_arg_matches: &mut clap::ArgMatches) -> ::std::result::Result<Self, clap::Error> {
|
||||
#raw_deprecated
|
||||
let v = #item_name #constructor;
|
||||
::std::result::Result::Ok(v)
|
||||
}
|
||||
|
||||
fn update_from_arg_matches(&mut self, __clap_arg_matches: &clap::ArgMatches) -> ::std::result::Result<(), clap::Error> {
|
||||
self.update_from_arg_matches_mut(&mut __clap_arg_matches.clone())
|
||||
}
|
||||
|
||||
fn update_from_arg_matches_mut(&mut self, __clap_arg_matches: &mut clap::ArgMatches) -> ::std::result::Result<(), clap::Error> {
|
||||
#raw_deprecated
|
||||
#updater
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(
|
||||
dead_code,
|
||||
unreachable_code,
|
||||
unused_variables,
|
||||
unused_braces,
|
||||
unused_qualifications,
|
||||
)]
|
||||
#[allow(
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::pedantic,
|
||||
clippy::restriction,
|
||||
clippy::perf,
|
||||
clippy::deprecated,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
clippy::suspicious_else_formatting,
|
||||
clippy::almost_swapped,
|
||||
clippy::redundant_locals,
|
||||
)]
|
||||
#[automatically_derived]
|
||||
impl #impl_generics clap::Args for #item_name #ty_generics #where_clause {
|
||||
fn group_id() -> Option<clap::Id> {
|
||||
#group_id
|
||||
}
|
||||
fn augment_args<'b>(#app_var: clap::Command) -> clap::Command {
|
||||
let #app_var = #app_var #initial_app_methods;
|
||||
let #app_var = #augmentation;
|
||||
#app_var #final_app_methods
|
||||
}
|
||||
fn augment_args_for_update<'b>(#app_var: clap::Command) -> clap::Command {
|
||||
let #app_var = #app_var #initial_app_methods;
|
||||
let #app_var = #augmentation_update;
|
||||
#app_var #final_app_methods
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate a block of code to add arguments/subcommands corresponding to
|
||||
/// the `fields` to an cmd.
|
||||
pub(crate) fn gen_augment(
|
||||
fields: &[(&Field, Item)],
|
||||
app_var: &Ident,
|
||||
parent_item: &Item,
|
||||
override_required: bool,
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
let mut subcommand_specified = false;
|
||||
let mut args = Vec::new();
|
||||
for (field, item) in fields {
|
||||
let kind = item.kind();
|
||||
let genned = match &*kind {
|
||||
Kind::Command(_)
|
||||
| Kind::Value
|
||||
| Kind::Skip(_, _)
|
||||
| Kind::FromGlobal(_)
|
||||
| Kind::ExternalSubcommand => None,
|
||||
Kind::Subcommand(ty) => {
|
||||
if subcommand_specified {
|
||||
abort!(
|
||||
field.span(),
|
||||
"`#[command(subcommand)]` can only be used once per container"
|
||||
);
|
||||
}
|
||||
subcommand_specified = true;
|
||||
|
||||
let subcmd_type = match (**ty, sub_type(&field.ty)) {
|
||||
(Ty::Option, Some(sub_type)) => sub_type,
|
||||
_ => &field.ty,
|
||||
};
|
||||
let implicit_methods = if **ty == Ty::Option {
|
||||
quote!()
|
||||
} else {
|
||||
quote_spanned! { kind.span()=>
|
||||
.subcommand_required(true)
|
||||
.arg_required_else_help(true)
|
||||
}
|
||||
};
|
||||
|
||||
let override_methods = if override_required {
|
||||
quote_spanned! { kind.span()=>
|
||||
.subcommand_required(false)
|
||||
.arg_required_else_help(false)
|
||||
}
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
|
||||
Some(quote! {
|
||||
let #app_var = <#subcmd_type as clap::Subcommand>::augment_subcommands( #app_var );
|
||||
let #app_var = #app_var
|
||||
#implicit_methods
|
||||
#override_methods;
|
||||
})
|
||||
}
|
||||
Kind::Flatten(ty) => {
|
||||
let inner_type = match (**ty, sub_type(&field.ty)) {
|
||||
(Ty::Option, Some(sub_type)) => sub_type,
|
||||
_ => &field.ty,
|
||||
};
|
||||
|
||||
let next_help_heading = item.next_help_heading();
|
||||
let next_display_order = item.next_display_order();
|
||||
let flatten_group_assert = if matches!(**ty, Ty::Option) {
|
||||
quote_spanned! { kind.span()=>
|
||||
<#inner_type as clap::Args>::group_id().expect("cannot `#[flatten]` an `Option<Args>` with `#[group(skip)]`");
|
||||
}
|
||||
} else {
|
||||
quote! {}
|
||||
};
|
||||
if override_required {
|
||||
Some(quote_spanned! { kind.span()=>
|
||||
#flatten_group_assert
|
||||
let #app_var = #app_var
|
||||
#next_help_heading
|
||||
#next_display_order;
|
||||
let #app_var = <#inner_type as clap::Args>::augment_args_for_update(#app_var);
|
||||
})
|
||||
} else {
|
||||
Some(quote_spanned! { kind.span()=>
|
||||
#flatten_group_assert
|
||||
let #app_var = #app_var
|
||||
#next_help_heading
|
||||
#next_display_order;
|
||||
let #app_var = <#inner_type as clap::Args>::augment_args(#app_var);
|
||||
})
|
||||
}
|
||||
}
|
||||
Kind::Arg(ty) => {
|
||||
let value_parser = item.value_parser(&field.ty);
|
||||
let action = item.action(&field.ty);
|
||||
let value_name = item.value_name();
|
||||
|
||||
let implicit_methods = match **ty {
|
||||
Ty::Unit => {
|
||||
// Leaving out `value_parser` as it will always fail
|
||||
quote_spanned! { ty.span()=>
|
||||
.value_name(#value_name)
|
||||
#action
|
||||
}
|
||||
}
|
||||
Ty::Option => {
|
||||
quote_spanned! { ty.span()=>
|
||||
.value_name(#value_name)
|
||||
#value_parser
|
||||
#action
|
||||
}
|
||||
}
|
||||
|
||||
Ty::OptionOption => quote_spanned! { ty.span()=>
|
||||
.value_name(#value_name)
|
||||
.num_args(0..=1)
|
||||
#value_parser
|
||||
#action
|
||||
},
|
||||
|
||||
Ty::OptionVec => {
|
||||
if item.is_positional() {
|
||||
quote_spanned! { ty.span()=>
|
||||
.value_name(#value_name)
|
||||
.num_args(1..) // action won't be sufficient for getting multiple
|
||||
#value_parser
|
||||
#action
|
||||
}
|
||||
} else {
|
||||
quote_spanned! { ty.span()=>
|
||||
.value_name(#value_name)
|
||||
#value_parser
|
||||
#action
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ty::Vec => {
|
||||
if item.is_positional() {
|
||||
quote_spanned! { ty.span()=>
|
||||
.value_name(#value_name)
|
||||
.num_args(1..) // action won't be sufficient for getting multiple
|
||||
#value_parser
|
||||
#action
|
||||
}
|
||||
} else {
|
||||
quote_spanned! { ty.span()=>
|
||||
.value_name(#value_name)
|
||||
#value_parser
|
||||
#action
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ty::VecVec | Ty::OptionVecVec => {
|
||||
quote_spanned! { ty.span() =>
|
||||
.value_name(#value_name)
|
||||
#value_parser
|
||||
#action
|
||||
}
|
||||
}
|
||||
|
||||
Ty::Other => {
|
||||
let required = item.find_default_method().is_none();
|
||||
// `ArgAction::takes_values` is assuming `ArgAction::default_value` will be
|
||||
// set though that won't always be true but this should be good enough,
|
||||
// otherwise we'll report an "arg required" error when unwrapping.
|
||||
let action_value = action.args();
|
||||
quote_spanned! { ty.span()=>
|
||||
.value_name(#value_name)
|
||||
.required(#required && #action_value.takes_values())
|
||||
#value_parser
|
||||
#action
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let id = item.id();
|
||||
let explicit_methods = item.field_methods();
|
||||
let deprecations = if !override_required {
|
||||
item.deprecations()
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let override_methods = if override_required {
|
||||
quote_spanned! { kind.span()=>
|
||||
.required(false)
|
||||
}
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
|
||||
Some(quote_spanned! { field.span()=>
|
||||
let #app_var = #app_var.arg({
|
||||
#deprecations
|
||||
|
||||
#[allow(deprecated)]
|
||||
let arg = clap::Arg::new(#id)
|
||||
#implicit_methods;
|
||||
|
||||
let arg = arg
|
||||
#explicit_methods;
|
||||
|
||||
let arg = arg
|
||||
#override_methods;
|
||||
|
||||
arg
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
args.push(genned);
|
||||
}
|
||||
|
||||
let deprecations = if !override_required {
|
||||
parent_item.deprecations()
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let group_app_methods = if parent_item.skip_group() {
|
||||
quote!()
|
||||
} else {
|
||||
let group_id = parent_item.group_id();
|
||||
let literal_group_members = fields
|
||||
.iter()
|
||||
.filter_map(|(_field, item)| {
|
||||
let kind = item.kind();
|
||||
if matches!(*kind, Kind::Arg(_)) {
|
||||
Some(item.id())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let literal_group_members_len = literal_group_members.len();
|
||||
let mut literal_group_members = quote! {{
|
||||
let members: [clap::Id; #literal_group_members_len] = [#( clap::Id::from(#literal_group_members) ),* ];
|
||||
members
|
||||
}};
|
||||
// HACK: Validation isn't ready yet for nested arg groups, so just don't populate the group in
|
||||
// that situation
|
||||
let possible_group_members_len = fields
|
||||
.iter()
|
||||
.filter(|(_field, item)| {
|
||||
let kind = item.kind();
|
||||
matches!(*kind, Kind::Flatten(_))
|
||||
})
|
||||
.count();
|
||||
if 0 < possible_group_members_len {
|
||||
literal_group_members = quote! {{
|
||||
let members: [clap::Id; 0] = [];
|
||||
members
|
||||
}};
|
||||
}
|
||||
|
||||
let group_methods = parent_item.group_methods();
|
||||
|
||||
quote!(
|
||||
.group(
|
||||
clap::ArgGroup::new(#group_id)
|
||||
.multiple(true)
|
||||
#group_methods
|
||||
.args(#literal_group_members)
|
||||
)
|
||||
)
|
||||
};
|
||||
Ok(quote! {{
|
||||
#deprecations
|
||||
let #app_var = #app_var
|
||||
#group_app_methods
|
||||
;
|
||||
#( #args )*
|
||||
#app_var
|
||||
}})
|
||||
}
|
||||
|
||||
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();
|
||||
let arg_matches = format_ident!("__clap_arg_matches");
|
||||
let genned = match &*kind {
|
||||
Kind::Command(_)
|
||||
| Kind::Value
|
||||
| Kind::ExternalSubcommand => {
|
||||
abort! { kind.span(),
|
||||
"`{}` cannot be used with `#[arg]`",
|
||||
kind.name(),
|
||||
}
|
||||
}
|
||||
Kind::Subcommand(ty) => {
|
||||
let subcmd_type = match (**ty, sub_type(&field.ty)) {
|
||||
(Ty::Option, Some(sub_type)) => sub_type,
|
||||
_ => &field.ty,
|
||||
};
|
||||
match **ty {
|
||||
Ty::Option => {
|
||||
quote_spanned! { kind.span()=>
|
||||
#field_name: {
|
||||
if #arg_matches.subcommand_name().map(<#subcmd_type as clap::Subcommand>::has_subcommand).unwrap_or(false) {
|
||||
Some(<#subcmd_type as clap::FromArgMatches>::from_arg_matches_mut(#arg_matches)?)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Ty::Other => {
|
||||
quote_spanned! { kind.span()=>
|
||||
#field_name: {
|
||||
<#subcmd_type as clap::FromArgMatches>::from_arg_matches_mut(#arg_matches)?
|
||||
}
|
||||
}
|
||||
},
|
||||
Ty::Unit |
|
||||
Ty::Vec |
|
||||
Ty::OptionOption |
|
||||
Ty::OptionVec |
|
||||
Ty::VecVec |
|
||||
Ty::OptionVecVec => {
|
||||
abort!(
|
||||
ty.span(),
|
||||
"`{}` is an invalid `#[command(subcommand)]` type",
|
||||
ty.as_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kind::Flatten(ty) => {
|
||||
let inner_type = match (**ty, sub_type(&field.ty)) {
|
||||
(Ty::Option, Some(sub_type)) => sub_type,
|
||||
_ => &field.ty,
|
||||
};
|
||||
match **ty {
|
||||
Ty::Other => {
|
||||
quote_spanned! { kind.span()=>
|
||||
#field_name: <#inner_type as clap::FromArgMatches>::from_arg_matches_mut(#arg_matches)?
|
||||
}
|
||||
},
|
||||
Ty::Option => {
|
||||
quote_spanned! { kind.span()=>
|
||||
#field_name: {
|
||||
let group_id = <#inner_type as clap::Args>::group_id()
|
||||
.expect("asserted during `Arg` creation");
|
||||
if #arg_matches.contains_id(group_id.as_str()) {
|
||||
Some(
|
||||
<#inner_type as clap::FromArgMatches>::from_arg_matches_mut(#arg_matches)?
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Ty::Unit |
|
||||
Ty::Vec |
|
||||
Ty::OptionOption |
|
||||
Ty::OptionVec |
|
||||
Ty::VecVec |
|
||||
Ty::OptionVecVec => {
|
||||
abort!(
|
||||
ty.span(),
|
||||
"`{}` is an invalid `#[command(flatten)]` type",
|
||||
ty.as_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Kind::Skip(val, _) => match val {
|
||||
None => quote_spanned!(kind.span()=> #field_name: Default::default()),
|
||||
Some(val) => quote_spanned!(kind.span()=> #field_name: (#val).into()),
|
||||
},
|
||||
|
||||
Kind::Arg(ty) | Kind::FromGlobal(ty) => {
|
||||
gen_parsers(item, ty, field_name, field, None)?
|
||||
}
|
||||
};
|
||||
Ok(genned)
|
||||
}).collect::<Result<Vec<_>, syn::Error>>()?;
|
||||
|
||||
Ok(quote! {{
|
||||
#( #fields ),*
|
||||
}})
|
||||
}
|
||||
|
||||
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();
|
||||
let kind = item.kind();
|
||||
|
||||
let access = if use_self {
|
||||
quote! {
|
||||
#[allow(non_snake_case)]
|
||||
let #field_name = &mut self.#field_name;
|
||||
}
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let arg_matches = format_ident!("__clap_arg_matches");
|
||||
|
||||
let genned = match &*kind {
|
||||
Kind::Command(_) | Kind::Value | Kind::ExternalSubcommand => {
|
||||
abort! { kind.span(),
|
||||
"`{}` cannot be used with `#[arg]`",
|
||||
kind.name(),
|
||||
}
|
||||
}
|
||||
Kind::Subcommand(ty) => {
|
||||
let subcmd_type = match (**ty, sub_type(&field.ty)) {
|
||||
(Ty::Option, Some(sub_type)) => sub_type,
|
||||
_ => &field.ty,
|
||||
};
|
||||
|
||||
let updater = quote_spanned! { ty.span()=>
|
||||
<#subcmd_type as clap::FromArgMatches>::update_from_arg_matches_mut(#field_name, #arg_matches)?;
|
||||
};
|
||||
|
||||
let updater = match **ty {
|
||||
Ty::Option => quote_spanned! { kind.span()=>
|
||||
if let Some(#field_name) = #field_name.as_mut() {
|
||||
#updater
|
||||
} else {
|
||||
*#field_name = Some(<#subcmd_type as clap::FromArgMatches>::from_arg_matches_mut(
|
||||
#arg_matches
|
||||
)?);
|
||||
}
|
||||
},
|
||||
_ => quote_spanned! { kind.span()=>
|
||||
#updater
|
||||
},
|
||||
};
|
||||
|
||||
quote_spanned! { kind.span()=>
|
||||
{
|
||||
#access
|
||||
#updater
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kind::Flatten(ty) => {
|
||||
let inner_type = match (**ty, sub_type(&field.ty)) {
|
||||
(Ty::Option, Some(sub_type)) => sub_type,
|
||||
_ => &field.ty,
|
||||
};
|
||||
|
||||
let updater = quote_spanned! { ty.span()=>
|
||||
<#inner_type as clap::FromArgMatches>::update_from_arg_matches_mut(#field_name, #arg_matches)?;
|
||||
};
|
||||
|
||||
let updater = match **ty {
|
||||
Ty::Option => quote_spanned! { kind.span()=>
|
||||
if let Some(#field_name) = #field_name.as_mut() {
|
||||
#updater
|
||||
} else {
|
||||
*#field_name = Some(<#inner_type as clap::FromArgMatches>::from_arg_matches_mut(
|
||||
#arg_matches
|
||||
)?);
|
||||
}
|
||||
},
|
||||
_ => quote_spanned! { kind.span()=>
|
||||
#updater
|
||||
},
|
||||
};
|
||||
|
||||
quote_spanned! { kind.span()=>
|
||||
{
|
||||
#access
|
||||
#updater
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kind::Skip(_, _) => quote!(),
|
||||
|
||||
Kind::Arg(ty) | Kind::FromGlobal(ty) => {
|
||||
gen_parsers(item, ty, field_name, field, Some(&access))?
|
||||
}
|
||||
};
|
||||
genned_fields.push(genned);
|
||||
}
|
||||
|
||||
Ok(quote! {
|
||||
#( #genned_fields )*
|
||||
})
|
||||
}
|
||||
|
||||
fn gen_parsers(
|
||||
item: &Item,
|
||||
ty: &Sp<Ty>,
|
||||
field_name: &Ident,
|
||||
field: &Field,
|
||||
update: Option<&TokenStream>,
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
let span = ty.span();
|
||||
let convert_type = inner_type(&field.ty);
|
||||
let id = item.id();
|
||||
let get_one = quote_spanned!(span=> remove_one::<#convert_type>);
|
||||
let get_many = quote_spanned!(span=> remove_many::<#convert_type>);
|
||||
let get_occurrences = quote_spanned!(span=> remove_occurrences::<#convert_type>);
|
||||
|
||||
// Give this identifier the same hygiene
|
||||
// as the `arg_matches` parameter definition. This
|
||||
// allows us to refer to `arg_matches` within a `quote_spanned` block
|
||||
let arg_matches = format_ident!("__clap_arg_matches");
|
||||
|
||||
let field_value = match **ty {
|
||||
Ty::Unit => {
|
||||
quote_spanned! { ty.span()=>
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
Ty::Option => {
|
||||
quote_spanned! { ty.span()=>
|
||||
#arg_matches.#get_one(#id)
|
||||
}
|
||||
}
|
||||
|
||||
Ty::OptionOption => quote_spanned! { ty.span()=>
|
||||
if #arg_matches.contains_id(#id) {
|
||||
Some(
|
||||
#arg_matches.#get_one(#id)
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
|
||||
Ty::OptionVec => quote_spanned! { ty.span()=>
|
||||
if #arg_matches.contains_id(#id) {
|
||||
Some(#arg_matches.#get_many(#id)
|
||||
.map(|v| v.collect::<Vec<_>>())
|
||||
.unwrap_or_else(Vec::new))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
|
||||
Ty::Vec => {
|
||||
quote_spanned! { ty.span()=>
|
||||
#arg_matches.#get_many(#id)
|
||||
.map(|v| v.collect::<Vec<_>>())
|
||||
.unwrap_or_else(Vec::new)
|
||||
}
|
||||
}
|
||||
|
||||
Ty::VecVec => quote_spanned! { ty.span()=>
|
||||
#arg_matches.#get_occurrences(#id)
|
||||
.map(|g| g.map(::std::iter::Iterator::collect).collect::<Vec<Vec<_>>>())
|
||||
.unwrap_or_else(Vec::new)
|
||||
},
|
||||
|
||||
Ty::OptionVecVec => quote_spanned! { ty.span()=>
|
||||
#arg_matches.#get_occurrences(#id)
|
||||
.map(|g| g.map(::std::iter::Iterator::collect).collect::<Vec<Vec<_>>>())
|
||||
},
|
||||
|
||||
Ty::Other => {
|
||||
// Prefer `concat` where possible for reduced code size but fallback to `format!` to
|
||||
// allow non-literal `id`s
|
||||
match id {
|
||||
Name::Assigned(_) => {
|
||||
quote_spanned! { ty.span()=>
|
||||
#arg_matches.#get_one(#id)
|
||||
.ok_or_else(|| clap::Error::raw(clap::error::ErrorKind::MissingRequiredArgument, format!("the following required argument was not provided: {}", #id)))?
|
||||
}
|
||||
}
|
||||
Name::Derived(_) => {
|
||||
quote_spanned! { ty.span()=>
|
||||
#arg_matches.#get_one(#id)
|
||||
.ok_or_else(|| clap::Error::raw(clap::error::ErrorKind::MissingRequiredArgument, concat!("the following required argument was not provided: ", #id)))?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let genned = if let Some(access) = update {
|
||||
quote_spanned! { field.span()=>
|
||||
if #arg_matches.contains_id(#id) {
|
||||
#access
|
||||
*#field_name = #field_value
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote_spanned!(field.span()=> #field_name: #field_value )
|
||||
};
|
||||
Ok(genned)
|
||||
}
|
||||
|
||||
#[cfg(feature = "raw-deprecated")]
|
||||
pub(crate) fn raw_deprecated() -> TokenStream {
|
||||
quote! {}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "raw-deprecated"))]
|
||||
pub(crate) fn raw_deprecated() -> TokenStream {
|
||||
quote! {
|
||||
#![allow(deprecated)] // Assuming any deprecation in here will be related to a deprecation in `Args`
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn collect_args_fields<'a>(
|
||||
item: &'a Item,
|
||||
fields: &'a FieldsNamed,
|
||||
) -> Result<Vec<(&'a Field, Item)>, syn::Error> {
|
||||
fields
|
||||
.named
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let item = Item::from_args_field(field, item.casing(), item.env_casing())?;
|
||||
Ok((field, item))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
117
third_party/crates/clap_derive-4.6.7/src/derives/into_app.rs
vendored
Normal file
117
third_party/crates/clap_derive-4.6.7/src/derives/into_app.rs
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
|
||||
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
|
||||
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//
|
||||
// This work was derived from Structopt (https://github.com/TeXitoi/structopt)
|
||||
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
|
||||
// MIT/Apache 2.0 license.
|
||||
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{Generics, Ident};
|
||||
|
||||
use crate::item::Item;
|
||||
|
||||
pub(crate) fn gen_for_struct(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
generics: &Generics,
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let name = item.cased_name();
|
||||
let app_var = Ident::new("__clap_app", Span::call_site());
|
||||
|
||||
let tokens = quote! {
|
||||
#[allow(
|
||||
dead_code,
|
||||
unreachable_code,
|
||||
unused_variables,
|
||||
unused_braces,
|
||||
unused_qualifications,
|
||||
)]
|
||||
#[allow(
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::pedantic,
|
||||
clippy::restriction,
|
||||
clippy::perf,
|
||||
clippy::deprecated,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
clippy::suspicious_else_formatting,
|
||||
clippy::almost_swapped,
|
||||
clippy::redundant_locals,
|
||||
)]
|
||||
#[automatically_derived]
|
||||
impl #impl_generics clap::CommandFactory for #item_name #ty_generics #where_clause {
|
||||
fn command<'b>() -> clap::Command {
|
||||
let #app_var = clap::Command::new(#name);
|
||||
<Self as clap::Args>::augment_args(#app_var)
|
||||
}
|
||||
|
||||
fn command_for_update<'b>() -> clap::Command {
|
||||
let #app_var = clap::Command::new(#name);
|
||||
<Self as clap::Args>::augment_args_for_update(#app_var)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(tokens)
|
||||
}
|
||||
|
||||
pub(crate) fn gen_for_enum(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
generics: &Generics,
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let name = item.cased_name();
|
||||
let app_var = Ident::new("__clap_app", Span::call_site());
|
||||
|
||||
Ok(quote! {
|
||||
#[allow(
|
||||
dead_code,
|
||||
unreachable_code,
|
||||
unused_variables,
|
||||
unused_braces,
|
||||
unused_qualifications,
|
||||
)]
|
||||
#[allow(
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::pedantic,
|
||||
clippy::restriction,
|
||||
clippy::perf,
|
||||
clippy::deprecated,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
clippy::suspicious_else_formatting,
|
||||
clippy::almost_swapped,
|
||||
clippy::redundant_locals,
|
||||
)]
|
||||
#[automatically_derived]
|
||||
impl #impl_generics clap::CommandFactory for #item_name #ty_generics #where_clause {
|
||||
fn command<'b>() -> clap::Command {
|
||||
let #app_var = clap::Command::new(#name)
|
||||
.subcommand_required(true)
|
||||
.arg_required_else_help(true);
|
||||
<Self as clap::Subcommand>::augment_subcommands(#app_var)
|
||||
}
|
||||
|
||||
fn command_for_update<'b>() -> clap::Command {
|
||||
let #app_var = clap::Command::new(#name);
|
||||
<Self as clap::Subcommand>::augment_subcommands_for_update(#app_var)
|
||||
.subcommand_required(false)
|
||||
.arg_required_else_help(false)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
23
third_party/crates/clap_derive-4.6.7/src/derives/mod.rs
vendored
Normal file
23
third_party/crates/clap_derive-4.6.7/src/derives/mod.rs
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
|
||||
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
|
||||
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//
|
||||
// This work was derived from Structopt (https://github.com/TeXitoi/structopt)
|
||||
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
|
||||
// MIT/Apache 2.0 license.
|
||||
mod args;
|
||||
mod into_app;
|
||||
mod parser;
|
||||
mod subcommand;
|
||||
mod 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;
|
||||
127
third_party/crates/clap_derive-4.6.7/src/derives/parser.rs
vendored
Normal file
127
third_party/crates/clap_derive-4.6.7/src/derives/parser.rs
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
|
||||
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
|
||||
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//
|
||||
// This work was derived from Structopt (https://github.com/TeXitoi/structopt)
|
||||
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
|
||||
// MIT/Apache 2.0 license.
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::Ident;
|
||||
use syn::Variant;
|
||||
use syn::{
|
||||
self, Data, DataStruct, DeriveInput, Field, Fields, Generics, punctuated::Punctuated,
|
||||
token::Comma,
|
||||
};
|
||||
|
||||
use crate::derives::args::collect_args_fields;
|
||||
use crate::derives::{args, into_app, subcommand};
|
||||
use crate::item::Item;
|
||||
use crate::item::Name;
|
||||
|
||||
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();
|
||||
|
||||
let pkg_name_tokens = if pkg_name.is_empty() {
|
||||
quote!(#pkg_name)
|
||||
} else {
|
||||
quote!({
|
||||
let _ = ::core::env!("CARGO_PKG_NAME");
|
||||
#pkg_name })
|
||||
};
|
||||
|
||||
match input.data {
|
||||
Data::Struct(DataStruct {
|
||||
fields: Fields::Named(ref fields),
|
||||
..
|
||||
}) => {
|
||||
let name = Name::Assigned(pkg_name_tokens.clone());
|
||||
let item = Item::from_args_struct(input, name)?;
|
||||
let fields = collect_args_fields(&item, fields)?;
|
||||
gen_for_struct(&item, ident, &input.generics, &fields)
|
||||
}
|
||||
Data::Struct(DataStruct {
|
||||
fields: Fields::Unit,
|
||||
..
|
||||
}) => {
|
||||
let name = Name::Assigned(pkg_name_tokens.clone());
|
||||
let item = Item::from_args_struct(input, name)?;
|
||||
let fields = Punctuated::<Field, Comma>::new();
|
||||
let fields = fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let item = Item::from_args_field(field, item.casing(), item.env_casing())?;
|
||||
Ok((field, item))
|
||||
})
|
||||
.collect::<Result<Vec<_>, syn::Error>>()?;
|
||||
gen_for_struct(&item, ident, &input.generics, &fields)
|
||||
}
|
||||
Data::Enum(ref e) => {
|
||||
let name = Name::Assigned(pkg_name_tokens);
|
||||
let item = Item::from_subcommand_enum(input, name)?;
|
||||
let variants = e
|
||||
.variants
|
||||
.iter()
|
||||
.map(|variant| {
|
||||
let item =
|
||||
Item::from_subcommand_variant(variant, item.casing(), item.env_casing())?;
|
||||
Ok((variant, item))
|
||||
})
|
||||
.collect::<Result<Vec<_>, syn::Error>>()?;
|
||||
gen_for_enum(&item, ident, &input.generics, &variants)
|
||||
}
|
||||
_ => abort_call_site!("`#[derive(Parser)]` only supports non-tuple structs and enums"),
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_for_struct(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
generics: &Generics,
|
||||
fields: &[(&Field, Item)],
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let into_app = into_app::gen_for_struct(item, item_name, generics)?;
|
||||
let args = args::gen_for_struct(item, item_name, generics, fields)?;
|
||||
|
||||
Ok(quote! {
|
||||
#[automatically_derived]
|
||||
#[allow(
|
||||
unused_qualifications,
|
||||
clippy::redundant_locals,
|
||||
)]
|
||||
impl #impl_generics clap::Parser for #item_name #ty_generics #where_clause {}
|
||||
|
||||
#into_app
|
||||
#args
|
||||
})
|
||||
}
|
||||
|
||||
fn gen_for_enum(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
generics: &Generics,
|
||||
variants: &[(&Variant, Item)],
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let into_app = into_app::gen_for_enum(item, item_name, generics)?;
|
||||
let subcommand = subcommand::gen_for_enum(item, item_name, generics, variants)?;
|
||||
|
||||
Ok(quote! {
|
||||
#[automatically_derived]
|
||||
impl #impl_generics clap::Parser for #item_name #ty_generics #where_clause {}
|
||||
|
||||
#into_app
|
||||
#subcommand
|
||||
})
|
||||
}
|
||||
686
third_party/crates/clap_derive-4.6.7/src/derives/subcommand.rs
vendored
Normal file
686
third_party/crates/clap_derive-4.6.7/src/derives/subcommand.rs
vendored
Normal file
@@ -0,0 +1,686 @@
|
||||
// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
|
||||
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
|
||||
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//
|
||||
// This work was derived from Structopt (https://github.com/TeXitoi/structopt)
|
||||
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
|
||||
// MIT/Apache 2.0 license.
|
||||
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use syn::{Data, DeriveInput, FieldsUnnamed, Generics, Variant, spanned::Spanned};
|
||||
|
||||
use crate::derives::args;
|
||||
use crate::derives::args::collect_args_fields;
|
||||
use crate::item::{Item, Kind, Name};
|
||||
use crate::utils::{is_simple_ty, subty_if_name};
|
||||
|
||||
pub(crate) fn derive_subcommand(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
let ident = &input.ident;
|
||||
|
||||
match input.data {
|
||||
Data::Enum(ref e) => {
|
||||
let name = Name::Derived(ident.clone());
|
||||
let item = Item::from_subcommand_enum(input, name)?;
|
||||
let variants = e
|
||||
.variants
|
||||
.iter()
|
||||
.map(|variant| {
|
||||
let item =
|
||||
Item::from_subcommand_variant(variant, item.casing(), item.env_casing())?;
|
||||
Ok((variant, item))
|
||||
})
|
||||
.collect::<Result<Vec<_>, syn::Error>>()?;
|
||||
gen_for_enum(&item, ident, &input.generics, &variants)
|
||||
}
|
||||
_ => abort_call_site!("`#[derive(Subcommand)]` only supports enums"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn gen_for_enum(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
generics: &Generics,
|
||||
variants: &[(&Variant, Item)],
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
if !matches!(&*item.kind(), Kind::Command(_)) {
|
||||
abort! { item.kind().span(),
|
||||
"`{}` cannot be used with `#[command]`",
|
||||
item.kind().name(),
|
||||
}
|
||||
}
|
||||
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let from_arg_matches = gen_from_arg_matches(variants)?;
|
||||
let update_from_arg_matches = gen_update_from_arg_matches(variants)?;
|
||||
|
||||
let augmentation = gen_augment(variants, item, false)?;
|
||||
let augmentation_update = gen_augment(variants, item, true)?;
|
||||
let has_subcommand = gen_has_subcommand(variants)?;
|
||||
let initial_app_methods = item.initial_top_level_methods();
|
||||
let final_app_methods = item.final_top_level_methods();
|
||||
|
||||
Ok(quote! {
|
||||
#[allow(
|
||||
dead_code,
|
||||
unreachable_code,
|
||||
unused_variables,
|
||||
unused_braces,
|
||||
unused_qualifications,
|
||||
)]
|
||||
#[allow(
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::pedantic,
|
||||
clippy::restriction,
|
||||
clippy::perf,
|
||||
clippy::deprecated,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
clippy::suspicious_else_formatting,
|
||||
clippy::almost_swapped,
|
||||
clippy::redundant_locals,
|
||||
)]
|
||||
#[automatically_derived]
|
||||
impl #impl_generics clap::FromArgMatches for #item_name #ty_generics #where_clause {
|
||||
fn from_arg_matches(__clap_arg_matches: &clap::ArgMatches) -> ::std::result::Result<Self, clap::Error> {
|
||||
Self::from_arg_matches_mut(&mut __clap_arg_matches.clone())
|
||||
}
|
||||
|
||||
#from_arg_matches
|
||||
|
||||
fn update_from_arg_matches(&mut self, __clap_arg_matches: &clap::ArgMatches) -> ::std::result::Result<(), clap::Error> {
|
||||
self.update_from_arg_matches_mut(&mut __clap_arg_matches.clone())
|
||||
}
|
||||
#update_from_arg_matches
|
||||
}
|
||||
|
||||
#[allow(
|
||||
dead_code,
|
||||
unreachable_code,
|
||||
unused_variables,
|
||||
unused_braces,
|
||||
unused_qualifications,
|
||||
)]
|
||||
#[allow(
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::pedantic,
|
||||
clippy::restriction,
|
||||
clippy::perf,
|
||||
clippy::deprecated,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
clippy::suspicious_else_formatting,
|
||||
clippy::almost_swapped,
|
||||
clippy::redundant_locals,
|
||||
)]
|
||||
#[automatically_derived]
|
||||
impl #impl_generics clap::Subcommand for #item_name #ty_generics #where_clause {
|
||||
fn augment_subcommands <'b>(__clap_app: clap::Command) -> clap::Command {
|
||||
let __clap_app = __clap_app #initial_app_methods;
|
||||
let __clap_app = #augmentation;
|
||||
__clap_app #final_app_methods
|
||||
}
|
||||
fn augment_subcommands_for_update <'b>(__clap_app: clap::Command) -> clap::Command {
|
||||
let __clap_app = __clap_app #initial_app_methods;
|
||||
let __clap_app = #augmentation_update;
|
||||
__clap_app #final_app_methods
|
||||
}
|
||||
fn has_subcommand(__clap_name: &str) -> bool {
|
||||
#has_subcommand
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn gen_augment(
|
||||
variants: &[(&Variant, Item)],
|
||||
parent_item: &Item,
|
||||
override_required: bool,
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
use syn::Fields::{Named, Unit, Unnamed};
|
||||
|
||||
let app_var = Ident::new("__clap_app", Span::call_site());
|
||||
|
||||
let mut subcommands = Vec::new();
|
||||
for (variant, item) in variants {
|
||||
let kind = item.kind();
|
||||
|
||||
let genned = match &*kind {
|
||||
Kind::Skip(_, _) | Kind::Arg(_) | Kind::FromGlobal(_) | Kind::Value => None,
|
||||
|
||||
Kind::ExternalSubcommand => {
|
||||
let ty = match variant.fields {
|
||||
Unnamed(ref fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty,
|
||||
|
||||
_ => abort!(
|
||||
variant,
|
||||
"invalid type for `#[command(external_subcommand)]`, expected a newtype variant with either a `Vec<String>` or `Vec<OsString>`"
|
||||
),
|
||||
};
|
||||
let deprecations = if !override_required {
|
||||
item.deprecations()
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let subty = subty_if_name(ty, "Vec").ok_or_else(|| {
|
||||
format_err!(
|
||||
ty.span(),
|
||||
"invalid type for `#[command(external_subcommand)]`, expected a `Vec<_>`"
|
||||
)
|
||||
})?;
|
||||
let subcommand = quote_spanned! { kind.span()=>
|
||||
#deprecations
|
||||
let #app_var = #app_var
|
||||
.external_subcommand_value_parser(clap::value_parser!(#subty));
|
||||
};
|
||||
Some(subcommand)
|
||||
}
|
||||
|
||||
Kind::Flatten(_) => match variant.fields {
|
||||
Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
|
||||
let ty = &unnamed[0].ty;
|
||||
let deprecations = if !override_required {
|
||||
item.deprecations()
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let next_help_heading = item.next_help_heading();
|
||||
let next_display_order = item.next_display_order();
|
||||
let subcommand = if override_required {
|
||||
quote! {
|
||||
#deprecations
|
||||
let #app_var = #app_var
|
||||
#next_help_heading
|
||||
#next_display_order;
|
||||
let #app_var = <#ty as clap::Subcommand>::augment_subcommands_for_update(#app_var);
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#deprecations
|
||||
let #app_var = #app_var
|
||||
#next_help_heading
|
||||
#next_display_order;
|
||||
let #app_var = <#ty as clap::Subcommand>::augment_subcommands(#app_var);
|
||||
}
|
||||
};
|
||||
Some(subcommand)
|
||||
}
|
||||
_ => abort!(
|
||||
variant,
|
||||
"invalid variant for `#[command(flatten)]`, expected a newtype variant"
|
||||
),
|
||||
},
|
||||
|
||||
Kind::Subcommand(_) => {
|
||||
let subcommand_var = Ident::new("__clap_subcommand", Span::call_site());
|
||||
let arg_block = match variant.fields {
|
||||
Named(_) => {
|
||||
abort!(
|
||||
variant,
|
||||
"invalid variant for `#[command(subcommand)]`, expected a newtype variant"
|
||||
)
|
||||
}
|
||||
Unit => quote!( #subcommand_var ),
|
||||
Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
|
||||
let ty = &unnamed[0].ty;
|
||||
if override_required {
|
||||
quote_spanned! { ty.span()=>
|
||||
{
|
||||
<#ty as clap::Subcommand>::augment_subcommands_for_update(#subcommand_var)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote_spanned! { ty.span()=>
|
||||
{
|
||||
<#ty as clap::Subcommand>::augment_subcommands(#subcommand_var)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Unnamed(..) => {
|
||||
abort!(
|
||||
variant,
|
||||
"invalid variant for `#[command(subcommand)]`, expected a newtype variant"
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let name = item.cased_name();
|
||||
let deprecations = if !override_required {
|
||||
item.deprecations()
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let initial_app_methods = item.initial_top_level_methods();
|
||||
let final_from_attrs = item.final_top_level_methods();
|
||||
let override_methods = if override_required {
|
||||
quote_spanned! { kind.span()=>
|
||||
.subcommand_required(false)
|
||||
.arg_required_else_help(false)
|
||||
}
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let subcommand = quote! {
|
||||
let #app_var = #app_var.subcommand({
|
||||
#deprecations;
|
||||
let #subcommand_var = clap::Command::new(#name);
|
||||
let #subcommand_var = #subcommand_var
|
||||
.subcommand_required(true)
|
||||
.arg_required_else_help(true);
|
||||
let #subcommand_var = #subcommand_var #initial_app_methods;
|
||||
let #subcommand_var = #arg_block;
|
||||
#subcommand_var #final_from_attrs #override_methods
|
||||
});
|
||||
};
|
||||
Some(subcommand)
|
||||
}
|
||||
|
||||
Kind::Command(_) => {
|
||||
let subcommand_var = Ident::new("__clap_subcommand", Span::call_site());
|
||||
let (sub_augment, initial_app_methods, final_from_attrs) = match variant.fields {
|
||||
Named(ref fields) => {
|
||||
let fields = collect_args_fields(item, fields)?;
|
||||
let sub_augment =
|
||||
args::gen_augment(&fields, &subcommand_var, item, override_required)?;
|
||||
(
|
||||
sub_augment,
|
||||
item.initial_top_level_methods(),
|
||||
item.final_top_level_methods(),
|
||||
)
|
||||
}
|
||||
Unit => (
|
||||
quote! { #subcommand_var },
|
||||
item.initial_top_level_methods(),
|
||||
item.final_top_level_methods(),
|
||||
),
|
||||
Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
|
||||
let ty = &unnamed[0].ty;
|
||||
let arg_block = if override_required {
|
||||
quote_spanned! { ty.span()=>
|
||||
{
|
||||
<#ty as clap::Args>::augment_args_for_update(#subcommand_var)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote_spanned! { ty.span()=>
|
||||
{
|
||||
<#ty as clap::Args>::augment_args(#subcommand_var)
|
||||
}
|
||||
}
|
||||
};
|
||||
(
|
||||
arg_block,
|
||||
item.initial_top_level_methods(),
|
||||
item.final_top_level_methods(),
|
||||
)
|
||||
}
|
||||
Unnamed(..) => {
|
||||
abort!(
|
||||
variant,
|
||||
"invalid variant for `#[command(subcommand)]`, expected a newtype variant"
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let sub_augment = if parent_item.defer() {
|
||||
quote! {
|
||||
#subcommand_var.defer(|#subcommand_var| { #sub_augment })
|
||||
}
|
||||
} else {
|
||||
sub_augment
|
||||
};
|
||||
|
||||
let deprecations = if !override_required {
|
||||
item.deprecations()
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let name = item.cased_name();
|
||||
let subcommand = quote! {
|
||||
let #app_var = #app_var.subcommand({
|
||||
#deprecations
|
||||
let #subcommand_var = clap::Command::new(#name)
|
||||
#initial_app_methods;
|
||||
let #subcommand_var = #sub_augment;
|
||||
#subcommand_var #final_from_attrs
|
||||
});
|
||||
};
|
||||
Some(subcommand)
|
||||
}
|
||||
};
|
||||
subcommands.push(genned);
|
||||
}
|
||||
|
||||
let deprecations = if !override_required {
|
||||
parent_item.deprecations()
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
Ok(quote! {{
|
||||
#deprecations;
|
||||
#( #subcommands )*;
|
||||
#app_var
|
||||
}})
|
||||
}
|
||||
|
||||
fn gen_has_subcommand(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error> {
|
||||
use syn::Fields::Unnamed;
|
||||
|
||||
let mut ext_subcmd = false;
|
||||
|
||||
let (flatten_variants, variants): (Vec<_>, Vec<_>) = variants
|
||||
.iter()
|
||||
.filter_map(|(variant, item)| {
|
||||
let kind = item.kind();
|
||||
match &*kind {
|
||||
Kind::Skip(_, _) | Kind::Arg(_) | Kind::FromGlobal(_) | Kind::Value => None,
|
||||
|
||||
Kind::ExternalSubcommand => {
|
||||
ext_subcmd = true;
|
||||
None
|
||||
}
|
||||
Kind::Flatten(_) | Kind::Subcommand(_) | Kind::Command(_) => Some((variant, item)),
|
||||
}
|
||||
})
|
||||
.partition(|(_, item)| {
|
||||
let kind = item.kind();
|
||||
matches!(&*kind, Kind::Flatten(_))
|
||||
});
|
||||
|
||||
let subcommands = variants.iter().map(|(_variant, item)| {
|
||||
let sub_name = item.cased_name();
|
||||
quote! {
|
||||
if #sub_name == __clap_name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
});
|
||||
let child_subcommands = flatten_variants
|
||||
.iter()
|
||||
.map(|(variant, _attrs)| match variant.fields {
|
||||
Unnamed(ref fields) if fields.unnamed.len() == 1 => {
|
||||
let ty = &fields.unnamed[0].ty;
|
||||
Ok(quote! {
|
||||
if <#ty as clap::Subcommand>::has_subcommand(__clap_name) {
|
||||
return true;
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => abort!(
|
||||
variant,
|
||||
"invalid variant for `#[command(flatten)]`, expected newtype variant"
|
||||
),
|
||||
})
|
||||
.collect::<Result<Vec<_>, syn::Error>>()?;
|
||||
|
||||
let genned = if ext_subcmd {
|
||||
quote! { true }
|
||||
} else {
|
||||
quote! {
|
||||
#( #subcommands )*
|
||||
|
||||
#( #child_subcommands )else*
|
||||
|
||||
false
|
||||
}
|
||||
};
|
||||
Ok(genned)
|
||||
}
|
||||
|
||||
fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error> {
|
||||
use syn::Fields::{Named, Unit, Unnamed};
|
||||
|
||||
let subcommand_name_var = format_ident!("__clap_name");
|
||||
let sub_arg_matches_var = format_ident!("__clap_arg_matches");
|
||||
|
||||
let mut ext_subcmd = None;
|
||||
let mut flatten_variants = Vec::new();
|
||||
let mut unflatten_variants = Vec::new();
|
||||
for (variant, item) in variants {
|
||||
let kind = item.kind();
|
||||
match &*kind {
|
||||
Kind::Skip(_, _) | Kind::Arg(_) | Kind::FromGlobal(_) | Kind::Value => {}
|
||||
|
||||
Kind::ExternalSubcommand => {
|
||||
if ext_subcmd.is_some() {
|
||||
abort!(
|
||||
item.kind().span(),
|
||||
"`#[command(external_subcommand)] can only be specified once and has already been specified"
|
||||
);
|
||||
}
|
||||
|
||||
let ty = match variant.fields {
|
||||
Unnamed(ref fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty,
|
||||
|
||||
_ => abort!(
|
||||
variant,
|
||||
"invalid type for `#[command(external_subcommand)]`, expected a newtype variant with either a `Vec<String>` or `Vec<OsString>`"
|
||||
),
|
||||
};
|
||||
|
||||
let (span, str_ty) = match subty_if_name(ty, "Vec") {
|
||||
Some(subty) => {
|
||||
if is_simple_ty(subty, "String") {
|
||||
(subty.span(), quote!(::std::string::String))
|
||||
} else if is_simple_ty(subty, "OsString") {
|
||||
(subty.span(), quote!(::std::ffi::OsString))
|
||||
} else {
|
||||
abort!(
|
||||
ty.span(),
|
||||
"invalid type for `#[command(external_subcommand)]`, expected a `Vec<String>` or `Vec<OsString>`"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
None => abort!(
|
||||
ty.span(),
|
||||
"invalid type for `#[command(external_subcommand)]`, expected a `Vec<String>` or `Vec<OsString>`"
|
||||
),
|
||||
};
|
||||
|
||||
ext_subcmd = Some((span, &variant.ident, str_ty));
|
||||
}
|
||||
Kind::Flatten(_) | Kind::Subcommand(_) | Kind::Command(_) => {
|
||||
if matches!(&*item.kind(), Kind::Flatten(_)) {
|
||||
flatten_variants.push((variant, item));
|
||||
} else {
|
||||
unflatten_variants.push((variant, item));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let subcommands = unflatten_variants.iter().map(|(variant, item)| {
|
||||
let sub_name = item.cased_name();
|
||||
let variant_name = &variant.ident;
|
||||
let constructor_block = match variant.fields {
|
||||
Named(ref fields) => {
|
||||
let fields = collect_args_fields(item, fields)?;
|
||||
args::gen_constructor(&fields)?
|
||||
},
|
||||
Unit => quote!(),
|
||||
Unnamed(ref fields) if fields.unnamed.len() == 1 => {
|
||||
let ty = &fields.unnamed[0].ty;
|
||||
quote!( ( <#ty as clap::FromArgMatches>::from_arg_matches_mut(__clap_arg_matches)? ) )
|
||||
}
|
||||
Unnamed(..) => abort_call_site!("{}: tuple enums are not supported", variant.ident),
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
if #subcommand_name_var == #sub_name && !#sub_arg_matches_var.contains_id("") {
|
||||
return ::std::result::Result::Ok(Self :: #variant_name #constructor_block)
|
||||
}
|
||||
})
|
||||
}).collect::<Result<Vec<_>, syn::Error>>()?;
|
||||
let child_subcommands = flatten_variants.iter().map(|(variant, _attrs)| {
|
||||
let variant_name = &variant.ident;
|
||||
match variant.fields {
|
||||
Unnamed(ref fields) if fields.unnamed.len() == 1 => {
|
||||
let ty = &fields.unnamed[0].ty;
|
||||
Ok(quote! {
|
||||
if __clap_arg_matches
|
||||
.subcommand_name()
|
||||
.map(|__clap_name| <#ty as clap::Subcommand>::has_subcommand(__clap_name))
|
||||
.unwrap_or_default()
|
||||
{
|
||||
let __clap_res = <#ty as clap::FromArgMatches>::from_arg_matches_mut(__clap_arg_matches)?;
|
||||
return ::std::result::Result::Ok(Self :: #variant_name (__clap_res));
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => abort!(
|
||||
variant,
|
||||
"invalid variant for `#[command(flatten)]`, expected newtype variant"
|
||||
),
|
||||
}
|
||||
}).collect::<Result<Vec<_>, syn::Error>>()?;
|
||||
|
||||
let wildcard = match ext_subcmd {
|
||||
Some((span, var_name, str_ty)) => quote_spanned! { span=>
|
||||
::std::result::Result::Ok(Self::#var_name(
|
||||
::std::iter::once(#str_ty::from(#subcommand_name_var))
|
||||
.chain(
|
||||
#sub_arg_matches_var
|
||||
.remove_many::<#str_ty>("")
|
||||
.unwrap()
|
||||
.map(#str_ty::from)
|
||||
)
|
||||
.collect::<::std::vec::Vec<_>>()
|
||||
))
|
||||
},
|
||||
|
||||
None => quote! {
|
||||
::std::result::Result::Err(clap::Error::raw(clap::error::ErrorKind::InvalidSubcommand, format!("the subcommand '{}' wasn't recognized", #subcommand_name_var)))
|
||||
},
|
||||
};
|
||||
|
||||
let raw_deprecated = args::raw_deprecated();
|
||||
Ok(quote! {
|
||||
fn from_arg_matches_mut(__clap_arg_matches: &mut clap::ArgMatches) -> ::std::result::Result<Self, clap::Error> {
|
||||
#raw_deprecated
|
||||
|
||||
#( #child_subcommands )else*
|
||||
|
||||
if let Some((#subcommand_name_var, mut __clap_arg_sub_matches)) = __clap_arg_matches.remove_subcommand() {
|
||||
let #sub_arg_matches_var = &mut __clap_arg_sub_matches;
|
||||
#( #subcommands )*
|
||||
|
||||
#wildcard
|
||||
} else {
|
||||
::std::result::Result::Err(clap::Error::raw(clap::error::ErrorKind::MissingSubcommand, "a subcommand is required but one was not provided"))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error> {
|
||||
use syn::Fields::{Named, Unit, Unnamed};
|
||||
|
||||
let (flatten, variants): (Vec<_>, Vec<_>) = variants
|
||||
.iter()
|
||||
.filter_map(|(variant, item)| {
|
||||
let kind = item.kind();
|
||||
match &*kind {
|
||||
// Fallback to `from_arg_matches_mut`
|
||||
Kind::Skip(_, _)
|
||||
| Kind::Arg(_)
|
||||
| Kind::FromGlobal(_)
|
||||
| Kind::Value
|
||||
| Kind::ExternalSubcommand => None,
|
||||
Kind::Flatten(_) | Kind::Subcommand(_) | Kind::Command(_) => Some((variant, item)),
|
||||
}
|
||||
})
|
||||
.partition(|(_, item)| {
|
||||
let kind = item.kind();
|
||||
matches!(&*kind, Kind::Flatten(_))
|
||||
});
|
||||
|
||||
let subcommands = variants.iter().map(|(variant, item)| {
|
||||
let sub_name = item.cased_name();
|
||||
let variant_name = &variant.ident;
|
||||
let (pattern, updater) = match variant.fields {
|
||||
Named(ref fields) => {
|
||||
let field_names = fields.named.iter().map(|field| {
|
||||
field.ident.as_ref().unwrap()
|
||||
}).collect::<Vec<_>>();
|
||||
let fields = collect_args_fields(item, fields)?;
|
||||
let update = args::gen_updater(&fields, false)?;
|
||||
(quote!( { #( #field_names, )* }), quote!( { #update } ))
|
||||
}
|
||||
Unit => (quote!(), quote!({})),
|
||||
Unnamed(ref fields) => {
|
||||
if fields.unnamed.len() == 1 {
|
||||
(
|
||||
quote!((__clap_arg)),
|
||||
quote!(clap::FromArgMatches::update_from_arg_matches_mut(
|
||||
__clap_arg,
|
||||
__clap_arg_matches
|
||||
)?),
|
||||
)
|
||||
} else {
|
||||
abort_call_site!("{}: tuple enums are not supported", variant.ident)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
Self :: #variant_name #pattern if #sub_name == __clap_name => {
|
||||
let (_, mut __clap_arg_sub_matches) = __clap_arg_matches.remove_subcommand().unwrap();
|
||||
let __clap_arg_matches = &mut __clap_arg_sub_matches;
|
||||
#updater
|
||||
}
|
||||
})
|
||||
}).collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
let child_subcommands = flatten.iter().map(|(variant, _attrs)| {
|
||||
let variant_name = &variant.ident;
|
||||
match variant.fields {
|
||||
Unnamed(ref fields) if fields.unnamed.len() == 1 => {
|
||||
let ty = &fields.unnamed[0].ty;
|
||||
Ok(quote! {
|
||||
if <#ty as clap::Subcommand>::has_subcommand(__clap_name) {
|
||||
if let Self :: #variant_name (child) = s {
|
||||
<#ty as clap::FromArgMatches>::update_from_arg_matches_mut(child, __clap_arg_matches)?;
|
||||
return ::std::result::Result::Ok(());
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => abort!(
|
||||
variant,
|
||||
"invalid variant for `#[command(flatten)]`, expected newtype variant"
|
||||
),
|
||||
}
|
||||
}).collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
let raw_deprecated = args::raw_deprecated();
|
||||
Ok(quote! {
|
||||
fn update_from_arg_matches_mut<'b>(
|
||||
&mut self,
|
||||
__clap_arg_matches: &mut clap::ArgMatches,
|
||||
) -> ::std::result::Result<(), clap::Error> {
|
||||
#raw_deprecated
|
||||
|
||||
if let Some(__clap_name) = __clap_arg_matches.subcommand_name() {
|
||||
match self {
|
||||
#( #subcommands ),*
|
||||
s => {
|
||||
#( #child_subcommands )*
|
||||
*s = <Self as clap::FromArgMatches>::from_arg_matches_mut(__clap_arg_matches)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
})
|
||||
}
|
||||
133
third_party/crates/clap_derive-4.6.7/src/derives/value_enum.rs
vendored
Normal file
133
third_party/crates/clap_derive-4.6.7/src/derives/value_enum.rs
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
|
||||
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
|
||||
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use quote::quote_spanned;
|
||||
use syn::{Data, DeriveInput, Fields, Ident, Variant, spanned::Spanned};
|
||||
|
||||
use crate::item::{Item, Kind, Name};
|
||||
|
||||
pub(crate) fn derive_value_enum(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
let ident = &input.ident;
|
||||
|
||||
match input.data {
|
||||
Data::Enum(ref e) => {
|
||||
let name = Name::Derived(ident.clone());
|
||||
let item = Item::from_value_enum(input, name)?;
|
||||
let mut variants = Vec::new();
|
||||
for variant in &e.variants {
|
||||
let item =
|
||||
Item::from_value_enum_variant(variant, item.casing(), item.env_casing())?;
|
||||
variants.push((variant, item));
|
||||
}
|
||||
gen_for_enum(&item, ident, &variants)
|
||||
}
|
||||
_ => abort_call_site!("`#[derive(ValueEnum)]` only supports enums"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn gen_for_enum(
|
||||
item: &Item,
|
||||
item_name: &Ident,
|
||||
variants: &[(&Variant, Item)],
|
||||
) -> Result<TokenStream, syn::Error> {
|
||||
if !matches!(&*item.kind(), Kind::Value) {
|
||||
abort! { item.kind().span(),
|
||||
"`{}` cannot be used with `#[value]`",
|
||||
item.kind().name(),
|
||||
}
|
||||
}
|
||||
|
||||
let lits = lits(variants)?;
|
||||
let value_variants = gen_value_variants(&lits);
|
||||
let to_possible_value = gen_to_possible_value(item, &lits);
|
||||
|
||||
Ok(quote! {
|
||||
#[allow(
|
||||
dead_code,
|
||||
unreachable_code,
|
||||
unused_variables,
|
||||
unused_braces,
|
||||
unused_qualifications,
|
||||
)]
|
||||
#[allow(
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::pedantic,
|
||||
clippy::restriction,
|
||||
clippy::perf,
|
||||
clippy::deprecated,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
clippy::suspicious_else_formatting,
|
||||
clippy::almost_swapped,
|
||||
clippy::redundant_locals,
|
||||
)]
|
||||
#[automatically_derived]
|
||||
impl clap::ValueEnum for #item_name {
|
||||
#value_variants
|
||||
#to_possible_value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn lits(variants: &[(&Variant, Item)]) -> Result<Vec<(TokenStream, Ident)>, syn::Error> {
|
||||
let mut genned = Vec::new();
|
||||
for (variant, item) in variants {
|
||||
if let Kind::Skip(_, _) = &*item.kind() {
|
||||
continue;
|
||||
}
|
||||
if !matches!(variant.fields, Fields::Unit) {
|
||||
abort!(
|
||||
variant.span(),
|
||||
"`#[derive(ValueEnum)]` only supports unit variants. Non-unit variants must be skipped"
|
||||
);
|
||||
}
|
||||
let fields = item.field_methods();
|
||||
let deprecations = item.deprecations();
|
||||
let name = item.cased_name();
|
||||
genned.push((
|
||||
quote_spanned! { variant.span()=> {
|
||||
#deprecations
|
||||
clap::builder::PossibleValue::new(#name)
|
||||
#fields
|
||||
}},
|
||||
variant.ident.clone(),
|
||||
));
|
||||
}
|
||||
Ok(genned)
|
||||
}
|
||||
|
||||
fn gen_value_variants(lits: &[(TokenStream, Ident)]) -> TokenStream {
|
||||
let lit = lits.iter().map(|l| &l.1).collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
fn value_variants<'a>() -> &'a [Self]{
|
||||
&[#(Self::#lit),*]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_to_possible_value(item: &Item, lits: &[(TokenStream, Ident)]) -> TokenStream {
|
||||
let (lit, variant): (Vec<TokenStream>, Vec<Ident>) = lits.iter().cloned().unzip();
|
||||
|
||||
let deprecations = item.deprecations();
|
||||
|
||||
quote! {
|
||||
fn to_possible_value<'a>(&self) -> ::std::option::Option<clap::builder::PossibleValue> {
|
||||
#deprecations
|
||||
match self {
|
||||
#(Self::#variant => Some(#lit),)*
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
99
third_party/crates/clap_derive-4.6.7/src/dummies.rs
vendored
Normal file
99
third_party/crates/clap_derive-4.6.7/src/dummies.rs
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
//! Dummy implementations that we emit along with an error.
|
||||
|
||||
use proc_macro2::Ident;
|
||||
use quote::quote;
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn parser(name: &Ident) -> proc_macro2::TokenStream {
|
||||
let into_app = into_app(name);
|
||||
quote!(
|
||||
#[automatically_derived]
|
||||
impl clap::Parser for #name {}
|
||||
#into_app
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn into_app(name: &Ident) -> proc_macro2::TokenStream {
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl clap::CommandFactory for #name {
|
||||
fn command<'b>() -> clap::Command {
|
||||
unimplemented!()
|
||||
}
|
||||
fn command_for_update<'b>() -> clap::Command {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn from_arg_matches(name: &Ident) -> proc_macro2::TokenStream {
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl clap::FromArgMatches for #name {
|
||||
fn from_arg_matches(_m: &clap::ArgMatches) -> ::std::result::Result<Self, clap::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn update_from_arg_matches(&mut self, matches: &clap::ArgMatches) -> ::std::result::Result<(), clap::Error>{
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn subcommand(name: &Ident) -> proc_macro2::TokenStream {
|
||||
let from_arg_matches = from_arg_matches(name);
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl clap::Subcommand for #name {
|
||||
fn augment_subcommands(_cmd: clap::Command) -> clap::Command {
|
||||
unimplemented!()
|
||||
}
|
||||
fn augment_subcommands_for_update(_cmd: clap::Command) -> clap::Command {
|
||||
unimplemented!()
|
||||
}
|
||||
fn has_subcommand(name: &str) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
#from_arg_matches
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn args(name: &Ident) -> proc_macro2::TokenStream {
|
||||
let from_arg_matches = from_arg_matches(name);
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl clap::Args for #name {
|
||||
fn augment_args(_cmd: clap::Command) -> clap::Command {
|
||||
unimplemented!()
|
||||
}
|
||||
fn augment_args_for_update(_cmd: clap::Command) -> clap::Command {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
#from_arg_matches
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn value_enum(name: &Ident) -> proc_macro2::TokenStream {
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl clap::ValueEnum for #name {
|
||||
fn value_variants<'a>() -> &'a [Self]{
|
||||
unimplemented!()
|
||||
}
|
||||
fn from_str(_input: &str, _ignore_case: bool) -> ::std::result::Result<Self, String> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn to_possible_value<'a>(&self) -> ::std::option::Option<clap::builder::PossibleValue>{
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1521
third_party/crates/clap_derive-4.6.7/src/item.rs
vendored
Normal file
1521
third_party/crates/clap_derive-4.6.7/src/item.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
118
third_party/crates/clap_derive-4.6.7/src/lib.rs
vendored
Normal file
118
third_party/crates/clap_derive-4.6.7/src/lib.rs
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
|
||||
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
|
||||
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//
|
||||
// This work was derived from Structopt (https://github.com/TeXitoi/structopt)
|
||||
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
|
||||
// MIT/Apache 2.0 license.
|
||||
|
||||
#![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_cfg))]
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(missing_docs)]
|
||||
#![warn(clippy::print_stderr)]
|
||||
#![warn(clippy::print_stdout)]
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use syn::{Data, DataStruct, Fields};
|
||||
use syn::{DeriveInput, parse_macro_input};
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
mod attr;
|
||||
mod derives;
|
||||
mod dummies;
|
||||
mod item;
|
||||
mod utils;
|
||||
|
||||
/// Generates the `ValueEnum` impl.
|
||||
#[proc_macro_derive(ValueEnum, attributes(clap, value))]
|
||||
pub fn value_enum(input: TokenStream) -> TokenStream {
|
||||
let input: DeriveInput = parse_macro_input!(input);
|
||||
derives::derive_value_enum(&input)
|
||||
.unwrap_or_else(|err| {
|
||||
let dummy = dummies::value_enum(&input.ident);
|
||||
to_compile_error(err, dummy)
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Generates the `Parser` implementation.
|
||||
///
|
||||
/// This is far less verbose than defining the `clap::Command` struct manually,
|
||||
/// receiving an instance of `clap::ArgMatches` from conducting parsing, and then
|
||||
/// implementing a conversion code to instantiate an instance of the user
|
||||
/// context struct.
|
||||
#[proc_macro_derive(Parser, attributes(clap, structopt, command, arg, group))]
|
||||
pub fn parser(input: TokenStream) -> TokenStream {
|
||||
let input: DeriveInput = parse_macro_input!(input);
|
||||
derives::derive_parser(&input)
|
||||
.unwrap_or_else(|err| {
|
||||
let specific_dummy = match input.data {
|
||||
Data::Struct(DataStruct {
|
||||
fields: Fields::Named(ref _fields),
|
||||
..
|
||||
}) => Some(dummies::args(&input.ident)),
|
||||
Data::Struct(DataStruct {
|
||||
fields: Fields::Unit,
|
||||
..
|
||||
}) => Some(dummies::args(&input.ident)),
|
||||
Data::Enum(_) => Some(dummies::subcommand(&input.ident)),
|
||||
_ => None,
|
||||
};
|
||||
let dummy = specific_dummy
|
||||
.map(|specific_dummy| {
|
||||
let parser_dummy = dummies::parser(&input.ident);
|
||||
quote::quote! {
|
||||
#parser_dummy
|
||||
#specific_dummy
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| quote::quote!());
|
||||
to_compile_error(err, dummy)
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Generates the `Subcommand` impl.
|
||||
#[proc_macro_derive(Subcommand, attributes(clap, command, arg, group))]
|
||||
pub fn subcommand(input: TokenStream) -> TokenStream {
|
||||
let input: DeriveInput = parse_macro_input!(input);
|
||||
derives::derive_subcommand(&input)
|
||||
.unwrap_or_else(|err| {
|
||||
let dummy = dummies::subcommand(&input.ident);
|
||||
to_compile_error(err, dummy)
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Generates the `Args` impl.
|
||||
#[proc_macro_derive(Args, attributes(clap, command, arg, group))]
|
||||
pub fn args(input: TokenStream) -> TokenStream {
|
||||
let input: DeriveInput = parse_macro_input!(input);
|
||||
derives::derive_args(&input)
|
||||
.unwrap_or_else(|err| {
|
||||
let dummy = dummies::args(&input.ident);
|
||||
to_compile_error(err, dummy)
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
fn to_compile_error(
|
||||
error: syn::Error,
|
||||
dummy: proc_macro2::TokenStream,
|
||||
) -> proc_macro2::TokenStream {
|
||||
let compile_errors = error.to_compile_error();
|
||||
quote::quote!(
|
||||
#dummy
|
||||
#compile_errors
|
||||
)
|
||||
}
|
||||
21
third_party/crates/clap_derive-4.6.7/src/macros.rs
vendored
Normal file
21
third_party/crates/clap_derive-4.6.7/src/macros.rs
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
macro_rules! format_err {
|
||||
($obj:expr, $($format:tt)+) => {{
|
||||
#[allow(unused_imports)]
|
||||
use $crate::utils::error::*;
|
||||
let msg = format!($($format)+);
|
||||
$obj.EXPECTED_Span_OR_ToTokens(msg)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! abort {
|
||||
($obj:expr, $($format:tt)+) => {{
|
||||
return Err(format_err!($obj, $($format)+));
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! abort_call_site {
|
||||
($($format:tt)+) => {{
|
||||
let span = proc_macro2::Span::call_site();
|
||||
abort!(span, $($format)+)
|
||||
}};
|
||||
}
|
||||
410
third_party/crates/clap_derive-4.6.7/src/utils/doc_comments.rs
vendored
Normal file
410
third_party/crates/clap_derive-4.6.7/src/utils/doc_comments.rs
vendored
Normal file
@@ -0,0 +1,410 @@
|
||||
//! The preprocessing we apply to doc comments.
|
||||
//!
|
||||
//! #[derive(Parser)] works in terms of "paragraphs". Paragraph is a sequence of
|
||||
//! non-empty adjacent lines, delimited by sequences of blank (whitespace only) lines.
|
||||
|
||||
#[cfg(feature = "unstable-markdown")]
|
||||
use markdown::parse_markdown;
|
||||
|
||||
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
|
||||
//
|
||||
// we also need to remove leading and trailing blank lines
|
||||
let mut lines: Vec<_> = attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path().is_ident("doc"))
|
||||
.filter_map(|attr| {
|
||||
// non #[doc = "..."] attributes are not our concern
|
||||
// we leave them for rustc to handle
|
||||
match &attr.meta {
|
||||
syn::Meta::NameValue(syn::MetaNameValue {
|
||||
value:
|
||||
syn::Expr::Lit(syn::ExprLit {
|
||||
lit: syn::Lit::Str(s),
|
||||
..
|
||||
}),
|
||||
..
|
||||
}) => Some(s.value()),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.skip_while(|s| is_blank(s))
|
||||
.flat_map(|s| {
|
||||
let lines = s
|
||||
.split('\n')
|
||||
.map(|s| {
|
||||
// remove one leading space no matter what
|
||||
let s = s.strip_prefix(' ').unwrap_or(s);
|
||||
s.to_owned()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
lines
|
||||
})
|
||||
.collect();
|
||||
|
||||
while let Some(true) = lines.last().map(|s| is_blank(s)) {
|
||||
lines.pop();
|
||||
}
|
||||
|
||||
lines
|
||||
}
|
||||
|
||||
pub(crate) fn format_doc_comment(
|
||||
lines: &[String],
|
||||
preprocess: bool,
|
||||
force_long: bool,
|
||||
) -> (Option<String>, Option<String>) {
|
||||
if preprocess {
|
||||
let (short, long) = parse_markdown(lines);
|
||||
let long = long.or_else(|| force_long.then(|| short.clone()));
|
||||
|
||||
(Some(remove_period(short)), long)
|
||||
} else if let Some(first_blank) = lines.iter().position(|s| is_blank(s)) {
|
||||
let short = lines[..first_blank].join("\n");
|
||||
let long = lines.join("\n");
|
||||
|
||||
(Some(short), Some(long))
|
||||
} else {
|
||||
let short = lines.join("\n");
|
||||
let long = force_long.then(|| short.clone());
|
||||
|
||||
(Some(short), long)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unstable-markdown"))]
|
||||
fn split_paragraphs(lines: &[String]) -> Vec<String> {
|
||||
use std::iter;
|
||||
|
||||
let mut last_line = 0;
|
||||
iter::from_fn(|| {
|
||||
let slice = &lines[last_line..];
|
||||
let start = slice.iter().position(|s| !is_blank(s)).unwrap_or(0);
|
||||
|
||||
let slice = &slice[start..];
|
||||
let len = slice
|
||||
.iter()
|
||||
.position(|s| is_blank(s))
|
||||
.unwrap_or(slice.len());
|
||||
|
||||
last_line += start + len;
|
||||
|
||||
if len != 0 {
|
||||
Some(merge_lines(&slice[..len]))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn remove_period(mut s: String) -> String {
|
||||
if s.ends_with('.') && !s.ends_with("..") {
|
||||
s.pop();
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
fn is_blank(s: &str) -> bool {
|
||||
s.trim().is_empty()
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unstable-markdown"))]
|
||||
fn merge_lines(lines: impl IntoIterator<Item = impl AsRef<str>>) -> String {
|
||||
lines
|
||||
.into_iter()
|
||||
.map(|s| s.as_ref().trim().to_owned())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unstable-markdown"))]
|
||||
fn parse_markdown(lines: &[String]) -> (String, Option<String>) {
|
||||
if lines.iter().any(|s| is_blank(s)) {
|
||||
let paragraphs = split_paragraphs(lines);
|
||||
let short = paragraphs[0].clone();
|
||||
let long = paragraphs.join("\n\n");
|
||||
(short, Some(long))
|
||||
} else {
|
||||
let short = merge_lines(lines);
|
||||
(short, None)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-markdown")]
|
||||
mod markdown {
|
||||
use anstyle::{Reset, Style};
|
||||
use pulldown_cmark::{Event, Options, Parser, Tag, TagEnd};
|
||||
use std::fmt;
|
||||
use std::fmt::Write;
|
||||
use std::ops::AddAssign;
|
||||
|
||||
#[derive(Default)]
|
||||
struct MarkdownWriter {
|
||||
output: String,
|
||||
/// Prefix inserted for each line.
|
||||
prefix: String,
|
||||
/// Should an empty line be inserted before the next anything.
|
||||
hanging_paragraph: bool,
|
||||
/// Are we in an empty line
|
||||
dirty_line: bool,
|
||||
styles: Vec<Style>,
|
||||
}
|
||||
|
||||
impl MarkdownWriter {
|
||||
fn newline(&mut self) {
|
||||
self.reset();
|
||||
self.output.push('\n');
|
||||
self.dirty_line = false;
|
||||
}
|
||||
fn endline(&mut self) {
|
||||
if self.dirty_line {
|
||||
self.newline();
|
||||
}
|
||||
}
|
||||
fn new_paragraph(&mut self) {
|
||||
self.endline();
|
||||
self.hanging_paragraph = true;
|
||||
}
|
||||
|
||||
fn write_fmt(&mut self, arguments: fmt::Arguments<'_>) {
|
||||
if self.hanging_paragraph {
|
||||
self.hanging_paragraph = false;
|
||||
self.newline();
|
||||
}
|
||||
if !self.dirty_line {
|
||||
self.output.push_str(&self.prefix);
|
||||
self.apply_styles();
|
||||
self.dirty_line = true;
|
||||
}
|
||||
self.output.write_fmt(arguments).unwrap();
|
||||
}
|
||||
|
||||
fn start_link(&mut self, dest_url: pulldown_cmark::CowStr<'_>) {
|
||||
write!(self, "\x1B]8;;{dest_url}\x1B\\");
|
||||
}
|
||||
fn end_link(&mut self) {
|
||||
write!(self, "\x1B]8;;\x1B\\");
|
||||
}
|
||||
|
||||
fn start_style(&mut self, style: Style) {
|
||||
self.styles.push(style);
|
||||
write!(self, "{style}");
|
||||
}
|
||||
fn end_style(&mut self, style: Style) {
|
||||
let last_style = self.styles.pop();
|
||||
debug_assert_eq!(last_style.unwrap(), style);
|
||||
|
||||
write!(self, "{Reset}");
|
||||
self.apply_styles();
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
write!(self, "{Reset}");
|
||||
}
|
||||
|
||||
fn apply_styles(&mut self) {
|
||||
// Reapplying all, because anstyle doesn't support merging styles
|
||||
// (probably because the ambiguity around colors)
|
||||
// TODO If we decide not to support any colors, we can replace this with
|
||||
// anstyle::Effects and remove the need for applying them all individually.
|
||||
for style in &self.styles {
|
||||
write!(self.output, "{style}").unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_prefix(&mut self, quote_prefix: &str) {
|
||||
debug_assert!(self.prefix.ends_with(quote_prefix));
|
||||
let new_len = self.prefix.len() - quote_prefix.len();
|
||||
self.prefix.truncate(new_len);
|
||||
}
|
||||
|
||||
fn add_prefix(&mut self, quote_prefix: &str) {
|
||||
if self.hanging_paragraph {
|
||||
self.hanging_paragraph = false;
|
||||
self.newline();
|
||||
}
|
||||
self.prefix += quote_prefix;
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn parse_markdown(input: &[String]) -> (String, Option<String>) {
|
||||
// Markdown Configuration
|
||||
let parsing_options = Options::ENABLE_STRIKETHROUGH;
|
||||
// Minimal Styling for now, because we cannot configure it
|
||||
let style_heading = Style::new().bold().underline();
|
||||
let style_emphasis = Style::new().italic();
|
||||
let style_strong = Style::new().bold();
|
||||
let style_strike_through = Style::new().strikethrough();
|
||||
let style_link = Style::new().underline();
|
||||
let style_code = Style::new().bold();
|
||||
let list_symbol = '-';
|
||||
let quote_prefix = "| ";
|
||||
let indentation = " ";
|
||||
|
||||
let input = input.join("\n");
|
||||
let input = Parser::new_ext(&input, parsing_options);
|
||||
|
||||
let mut short = None;
|
||||
let mut has_details = false;
|
||||
|
||||
let mut writer = MarkdownWriter::default();
|
||||
|
||||
let mut list_indices = Vec::new();
|
||||
|
||||
for event in input {
|
||||
if short.is_some() {
|
||||
has_details = true;
|
||||
}
|
||||
match event {
|
||||
Event::Start(Tag::Paragraph) => { /* nothing to do */ }
|
||||
Event::End(TagEnd::Paragraph) => {
|
||||
if short.is_none() {
|
||||
short = Some(writer.output.trim().to_owned());
|
||||
}
|
||||
writer.new_paragraph();
|
||||
}
|
||||
|
||||
Event::Start(Tag::Heading { .. }) => writer.start_style(style_heading),
|
||||
Event::End(TagEnd::Heading(..)) => {
|
||||
writer.end_style(style_heading);
|
||||
writer.new_paragraph();
|
||||
}
|
||||
|
||||
Event::Start(Tag::Image { .. } | Tag::HtmlBlock) => { /* IGNORED */ }
|
||||
Event::End(TagEnd::Image) => { /* IGNORED */ }
|
||||
Event::End(TagEnd::HtmlBlock) => writer.new_paragraph(),
|
||||
|
||||
Event::Start(Tag::BlockQuote(_)) => writer.add_prefix(quote_prefix),
|
||||
Event::End(TagEnd::BlockQuote(_)) => {
|
||||
writer.remove_prefix(quote_prefix);
|
||||
writer.new_paragraph();
|
||||
}
|
||||
|
||||
Event::Start(Tag::CodeBlock(_)) => {
|
||||
writer.add_prefix(indentation);
|
||||
writer.start_style(style_code);
|
||||
}
|
||||
Event::End(TagEnd::CodeBlock) => {
|
||||
writer.remove_prefix(indentation);
|
||||
writer.end_style(style_code);
|
||||
writer.dirty_line = false;
|
||||
writer.hanging_paragraph = true;
|
||||
}
|
||||
|
||||
Event::Start(Tag::List(list_start)) => {
|
||||
list_indices.push(list_start);
|
||||
writer.endline();
|
||||
}
|
||||
Event::End(TagEnd::List(_)) => {
|
||||
let list = list_indices.pop();
|
||||
debug_assert!(list.is_some());
|
||||
if list_indices.is_empty() {
|
||||
writer.new_paragraph();
|
||||
}
|
||||
}
|
||||
Event::Start(Tag::Item) => {
|
||||
if let Some(Some(index)) = list_indices.last_mut() {
|
||||
write!(writer, "{index}. ");
|
||||
index.add_assign(1);
|
||||
} else {
|
||||
write!(writer, "{list_symbol} ");
|
||||
}
|
||||
writer.add_prefix(indentation);
|
||||
}
|
||||
Event::End(TagEnd::Item) => {
|
||||
writer.remove_prefix(indentation);
|
||||
writer.endline();
|
||||
}
|
||||
|
||||
Event::Start(Tag::Emphasis) => writer.start_style(style_emphasis),
|
||||
Event::End(TagEnd::Emphasis) => writer.end_style(style_emphasis),
|
||||
Event::Start(Tag::Strong) => writer.start_style(style_strong),
|
||||
Event::End(TagEnd::Strong) => writer.end_style(style_strong),
|
||||
Event::Start(Tag::Strikethrough) => writer.start_style(style_strike_through),
|
||||
Event::End(TagEnd::Strikethrough) => writer.end_style(style_strike_through),
|
||||
|
||||
Event::Start(Tag::Link { dest_url, .. }) => {
|
||||
writer.start_link(dest_url);
|
||||
writer.start_style(style_link);
|
||||
}
|
||||
Event::End(TagEnd::Link) => {
|
||||
writer.end_link();
|
||||
writer.end_style(style_link);
|
||||
}
|
||||
|
||||
Event::Text(segment) => {
|
||||
// split into lines to support code blocks
|
||||
let mut lines = segment.lines();
|
||||
// `.lines()` always returns at least one
|
||||
write!(writer, "{}", lines.next().unwrap());
|
||||
for line in lines {
|
||||
writer.endline();
|
||||
write!(writer, "{line}");
|
||||
}
|
||||
if segment.ends_with('\n') {
|
||||
writer.endline();
|
||||
}
|
||||
}
|
||||
|
||||
Event::Code(code) => {
|
||||
writer.start_style(style_code);
|
||||
write!(writer, "{code}");
|
||||
writer.end_style(style_code);
|
||||
}
|
||||
|
||||
// There is not really anything useful to do with block level html.
|
||||
Event::Html(html) => write!(writer, "{html}"),
|
||||
// At some point we could support custom tags like `<red>`
|
||||
Event::InlineHtml(html) => write!(writer, "{html}"),
|
||||
Event::SoftBreak => write!(writer, " "),
|
||||
Event::HardBreak => writer.endline(),
|
||||
|
||||
Event::Rule => {
|
||||
writer.new_paragraph();
|
||||
write!(writer, "---");
|
||||
writer.new_paragraph();
|
||||
}
|
||||
|
||||
// Markdown features currently not supported
|
||||
Event::Start(
|
||||
Tag::FootnoteDefinition(_)
|
||||
| Tag::DefinitionList
|
||||
| Tag::DefinitionListTitle
|
||||
| Tag::DefinitionListDefinition
|
||||
| Tag::Table(_)
|
||||
| Tag::TableHead
|
||||
| Tag::TableRow
|
||||
| Tag::TableCell
|
||||
| Tag::MetadataBlock(_)
|
||||
| Tag::Superscript
|
||||
| Tag::Subscript,
|
||||
)
|
||||
| Event::End(
|
||||
TagEnd::FootnoteDefinition
|
||||
| TagEnd::DefinitionList
|
||||
| TagEnd::DefinitionListTitle
|
||||
| TagEnd::DefinitionListDefinition
|
||||
| TagEnd::Table
|
||||
| TagEnd::TableHead
|
||||
| TagEnd::TableRow
|
||||
| TagEnd::TableCell
|
||||
| TagEnd::MetadataBlock(_)
|
||||
| TagEnd::Superscript
|
||||
| TagEnd::Subscript,
|
||||
)
|
||||
| Event::InlineMath(_)
|
||||
| Event::DisplayMath(_)
|
||||
| Event::FootnoteReference(_)
|
||||
| Event::TaskListMarker(_) => {
|
||||
unimplemented!("feature not enabled {event:?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
let short = short.unwrap_or_else(|| writer.output.trim_end().to_owned());
|
||||
let long = writer.output.trim_end();
|
||||
let long = has_details.then(|| long.to_owned());
|
||||
(short, long)
|
||||
}
|
||||
}
|
||||
22
third_party/crates/clap_derive-4.6.7/src/utils/error.rs
vendored
Normal file
22
third_party/crates/clap_derive-4.6.7/src/utils/error.rs
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
pub(crate) trait SpanError {
|
||||
#[allow(non_snake_case)]
|
||||
fn EXPECTED_Span_OR_ToTokens<D: std::fmt::Display>(&self, msg: D) -> syn::Error;
|
||||
}
|
||||
|
||||
pub(crate) trait ToTokensError {
|
||||
#[allow(non_snake_case)]
|
||||
fn EXPECTED_Span_OR_ToTokens<D: std::fmt::Display>(&self, msg: D) -> syn::Error;
|
||||
}
|
||||
|
||||
impl<T: quote::ToTokens> ToTokensError for T {
|
||||
fn EXPECTED_Span_OR_ToTokens<D: std::fmt::Display>(&self, msg: D) -> syn::Error {
|
||||
// Curb monomorphization from generating too many identical `new_spanned`.
|
||||
syn::Error::new_spanned(self.to_token_stream(), msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl SpanError for proc_macro2::Span {
|
||||
fn EXPECTED_Span_OR_ToTokens<D: std::fmt::Display>(&self, msg: D) -> syn::Error {
|
||||
syn::Error::new(*self, msg)
|
||||
}
|
||||
}
|
||||
13
third_party/crates/clap_derive-4.6.7/src/utils/mod.rs
vendored
Normal file
13
third_party/crates/clap_derive-4.6.7/src/utils/mod.rs
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
pub(crate) mod error;
|
||||
|
||||
mod doc_comments;
|
||||
mod spanned;
|
||||
mod ty;
|
||||
|
||||
pub(crate) use doc_comments::extract_doc_comment;
|
||||
pub(crate) use doc_comments::format_doc_comment;
|
||||
|
||||
pub(crate) use self::{
|
||||
spanned::Sp,
|
||||
ty::{Ty, inner_type, is_simple_ty, sub_type, subty_if_name},
|
||||
};
|
||||
89
third_party/crates/clap_derive-4.6.7/src/utils/spanned.rs
vendored
Normal file
89
third_party/crates/clap_derive-4.6.7/src/utils/spanned.rs
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::ToTokens;
|
||||
use syn::LitStr;
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
/// An entity with a span attached.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub(crate) struct Sp<T> {
|
||||
val: T,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl<T> Sp<T> {
|
||||
pub(crate) fn new(val: T, span: Span) -> Self {
|
||||
Self { val, span }
|
||||
}
|
||||
|
||||
pub(crate) fn get(&self) -> &T {
|
||||
&self.val
|
||||
}
|
||||
|
||||
pub(crate) fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for Sp<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &T {
|
||||
&self.val
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for Sp<T> {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
&mut self.val
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Ident> for Sp<String> {
|
||||
fn from(ident: Ident) -> Self {
|
||||
Self {
|
||||
val: ident.to_string(),
|
||||
span: ident.span(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LitStr> for Sp<String> {
|
||||
fn from(lit: LitStr) -> Self {
|
||||
Self {
|
||||
val: lit.value(),
|
||||
span: lit.span(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<Sp<&'a str>> for Sp<String> {
|
||||
fn from(sp: Sp<&'a str>) -> Self {
|
||||
Self::new(sp.val.into(), sp.span)
|
||||
}
|
||||
}
|
||||
|
||||
impl<U, T: PartialEq<U>> PartialEq<U> for Sp<T> {
|
||||
fn eq(&self, other: &U) -> bool {
|
||||
self.val == *other
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> AsRef<str> for Sp<T> {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.val.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToTokens> ToTokens for Sp<T> {
|
||||
fn to_tokens(&self, stream: &mut TokenStream) {
|
||||
// this is the simplest way out of correct ones to change span on
|
||||
// arbitrary token tree I could come up with
|
||||
let tt = self.val.to_token_stream().into_iter().map(|mut tt| {
|
||||
tt.set_span(self.span);
|
||||
tt
|
||||
});
|
||||
|
||||
stream.extend(tt);
|
||||
}
|
||||
}
|
||||
166
third_party/crates/clap_derive-4.6.7/src/utils/ty.rs
vendored
Normal file
166
third_party/crates/clap_derive-4.6.7/src/utils/ty.rs
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
//! Special types handling
|
||||
|
||||
use super::spanned::Sp;
|
||||
|
||||
use syn::{
|
||||
GenericArgument, Path, PathArguments, PathArguments::AngleBracketed, PathSegment, Type,
|
||||
TypePath, spanned::Spanned,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub(crate) enum Ty {
|
||||
Unit,
|
||||
Vec,
|
||||
VecVec,
|
||||
Option,
|
||||
OptionOption,
|
||||
OptionVec,
|
||||
OptionVecVec,
|
||||
Other,
|
||||
}
|
||||
|
||||
impl 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) {
|
||||
t(Unit)
|
||||
} else if let Some(vt) = get_vec_ty(ty, Vec, VecVec) {
|
||||
t(vt)
|
||||
} else if let Some(subty) = subty_if_name(ty, "Option") {
|
||||
if is_generic_ty(subty, "Option") {
|
||||
t(OptionOption)
|
||||
} else if let Some(vt) = get_vec_ty(subty, OptionVec, OptionVecVec) {
|
||||
t(vt)
|
||||
} else {
|
||||
t(Option)
|
||||
}
|
||||
} else {
|
||||
t(Other)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Unit => "()",
|
||||
Self::Vec => "Vec<T>",
|
||||
Self::Option => "Option<T>",
|
||||
Self::OptionOption => "Option<Option<T>>",
|
||||
Self::OptionVec => "Option<Vec<T>>",
|
||||
Self::VecVec => "Vec<Vec<T>>",
|
||||
Self::OptionVecVec => "Option<Vec<Vec<T>>>",
|
||||
Self::Other => "...other...",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
Ty::OptionOption | Ty::OptionVec | Ty::VecVec => {
|
||||
sub_type(field_ty).and_then(sub_type).unwrap_or(field_ty)
|
||||
}
|
||||
Ty::OptionVecVec => sub_type(field_ty)
|
||||
.and_then(sub_type)
|
||||
.and_then(sub_type)
|
||||
.unwrap_or(field_ty),
|
||||
_ => field_ty,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn sub_type(ty: &Type) -> Option<&Type> {
|
||||
subty_if(ty, |_| true)
|
||||
}
|
||||
|
||||
fn only_last_segment(mut ty: &Type) -> Option<&PathSegment> {
|
||||
while let Type::Group(syn::TypeGroup { elem, .. }) = ty {
|
||||
ty = elem;
|
||||
}
|
||||
match ty {
|
||||
Type::Path(TypePath {
|
||||
qself: None,
|
||||
path:
|
||||
Path {
|
||||
leading_colon: None,
|
||||
segments,
|
||||
},
|
||||
attrs: _,
|
||||
}) => only_one(segments.iter()),
|
||||
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn subty_if<F>(ty: &Type, f: F) -> Option<&Type>
|
||||
where
|
||||
F: FnOnce(&PathSegment) -> bool,
|
||||
{
|
||||
only_last_segment(ty)
|
||||
.filter(|segment| f(segment))
|
||||
.and_then(|segment| {
|
||||
if let AngleBracketed(args) = &segment.arguments {
|
||||
only_one(args.args.iter()).and_then(|genneric| {
|
||||
if let GenericArgument::Type(ty) = genneric {
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn subty_if_name<'a>(ty: &'a Type, name: &str) -> Option<&'a Type> {
|
||||
subty_if(ty, |seg| seg.ident == name)
|
||||
}
|
||||
|
||||
pub(crate) fn is_simple_ty(ty: &Type, name: &str) -> bool {
|
||||
only_last_segment(ty)
|
||||
.map(|segment| {
|
||||
if let PathArguments::None = segment.arguments {
|
||||
segment.ident == name
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn is_generic_ty(ty: &Type, name: &str) -> bool {
|
||||
subty_if_name(ty, name).is_some()
|
||||
}
|
||||
|
||||
fn is_unit_ty(ty: &Type) -> bool {
|
||||
if let Type::Tuple(tuple) = ty {
|
||||
tuple.elems.is_empty()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn only_one<I, T>(mut iter: I) -> Option<T>
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
{
|
||||
iter.next().filter(|_| iter.next().is_none())
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-v5")]
|
||||
fn get_vec_ty(ty: &Type, vec_ty: Ty, vecvec_ty: Ty) -> Option<Ty> {
|
||||
subty_if_name(ty, "Vec").map(|subty| {
|
||||
if is_generic_ty(subty, "Vec") {
|
||||
vecvec_ty
|
||||
} else {
|
||||
vec_ty
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unstable-v5"))]
|
||||
fn get_vec_ty(ty: &Type, vec_ty: Ty, _vecvec_ty: Ty) -> Option<Ty> {
|
||||
is_generic_ty(ty, "Vec").then_some(vec_ty)
|
||||
}
|
||||
Reference in New Issue
Block a user